Merge git://git.denx.de/u-boot-fsl-qoriq
diff --git a/.travis.yml b/.travis.yml
index 591915d..f6898a2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,8 +22,6 @@
     - swig
     - libpython-dev
     - gcc-powerpc-linux-gnu
-    - gcc-arm-linux-gnueabihf
-    - gcc-aarch64-linux-gnu
     - iasl
     - grub-efi-ia32-bin
     - rpm2cpio
@@ -40,6 +38,8 @@
  - ln -s travis-ci /tmp/uboot-test-hooks/py/`hostname`
  # prepare buildman environment
  - echo -e "[toolchain]\nroot = /usr" > ~/.buildman
+ - echo -e "aarch64 = /tmp/gcc-linaro-6.3.1-2017.02-x86_64_aarch64-linux-gnu" >> ~/.buildman
+ - echo -e "arm = /tmp/gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabihf" >> ~/.buildman
  - echo -e "\n[toolchain-alias]\nsh = sh4\nopenrisc = or32" >> ~/.buildman
  - cat ~/.buildman
  - virtualenv /tmp/venv
@@ -70,6 +70,13 @@
       echo -e "\n[toolchain-prefix]\nx86 = ${HOME}/.buildman-toolchains/gcc-4.9.0-nolibc/x86_64-linux/bin/x86_64-linux-" >> ~/.buildman;
     fi
   - if [[ "${TOOLCHAIN}" == *xtensa* ]]; then ./tools/buildman/buildman --fetch-arch xtensa ; fi
+  # If TOOLCHAIN is unset, we're on some flavour of ARM.
+  - if [[ "${TOOLCHAIN}" == "" ]]; then
+       wget http://releases.linaro.org/components/toolchain/binaries/6.3-2017.02/aarch64-linux-gnu/gcc-linaro-6.3.1-2017.02-x86_64_aarch64-linux-gnu.tar.xz &&
+       wget http://releases.linaro.org/components/toolchain/binaries/6.3-2017.02/arm-linux-gnueabihf/gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabihf.tar.xz &&
+       tar -C /tmp -xf gcc-linaro-6.3.1-2017.02-x86_64_aarch64-linux-gnu.tar.xz &&
+       tar -C /tmp -xf gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabihf.tar.xz;
+    fi
   - if [[ "${QEMU_TARGET}" != "" ]]; then
        git clone git://git.qemu.org/qemu.git /tmp/qemu;
        pushd /tmp/qemu;
@@ -152,7 +159,7 @@
     - env:
         - BUILDMAN="sun7i"
     - env:
-        - BUILDMAN="sun8i -x orangepi_pc2"
+        - BUILDMAN="sun8i"
     - env:
         - BUILDMAN="sun9i"
     - env:
@@ -221,7 +228,6 @@
         - BUILDMAN="uniphier"
     - env:
         - BUILDMAN="aarch64 -x tegra,freescale,mvebu,uniphier,sunxi,samsung,rockchip"
-          TOOLCHAIN="aarch64"
     - env:
         - BUILDMAN="rockchip"
     - env:
diff --git a/Makefile b/Makefile
index 8d4e605..131d62e 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@
 VERSION = 2017
 PATCHLEVEL = 05
 SUBLEVEL =
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME =
 
 # *DOCUMENTATION*
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 42f93b4..7812f21 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -174,6 +174,15 @@
 	default 64 if SYS_CACHE_SHIFT_6
 	default 32 if SYS_CACHE_SHIFT_5
 
+config ARM_SMCCC
+	bool "Support for ARM SMC Calling Convention (SMCCC)"
+	depends on CPU_V7 || ARM64
+	select ARM_PSCI_FW
+	help
+	  Say Y here if you want to enable ARM SMC Calling Convention.
+	  This should be enabled if U-Boot needs to communicate with system
+	  firmware (for example, PSCI) according to SMCCC.
+
 config SEMIHOSTING
 	bool "support boot from semihosting"
 	help
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
index 999ab47..5fac252 100644
--- a/arch/arm/cpu/armv7/Makefile
+++ b/arch/arm/cpu/armv7/Makefile
@@ -18,6 +18,7 @@
 endif
 endif
 
+obj-$(CONFIG_ARM_SMCCC)		+= smccc-call.o
 obj-$(CONFIG_ARMV7_NONSEC)	+= nonsec_virt.o virt-v7.o virt-dt.o
 obj-$(CONFIG_ARMV7_PSCI)	+= psci.o psci-common.o
 
diff --git a/arch/arm/cpu/armv7/smccc-call.S b/arch/arm/cpu/armv7/smccc-call.S
new file mode 100644
index 0000000..c2fdbad
--- /dev/null
+++ b/arch/arm/cpu/armv7/smccc-call.S
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+#include <linux/linkage.h>
+
+#include <asm/opcodes-sec.h>
+#include <asm/opcodes-virt.h>
+
+#define UNWIND(x...)
+	/*
+	 * Wrap c macros in asm macros to delay expansion until after the
+	 * SMCCC asm macro is expanded.
+	 */
+	.macro SMCCC_SMC
+	__SMC(0)
+	.endm
+
+	.macro SMCCC_HVC
+	__HVC(0)
+	.endm
+
+	.macro SMCCC instr
+UNWIND(	.fnstart)
+	mov	r12, sp
+	push	{r4-r7}
+UNWIND(	.save	{r4-r7})
+	ldm	r12, {r4-r7}
+	\instr
+	pop	{r4-r7}
+	ldr	r12, [sp, #(4 * 4)]
+	stm	r12, {r0-r3}
+	bx	lr
+UNWIND(	.fnend)
+	.endm
+
+/*
+ * void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
+ *		  unsigned long a3, unsigned long a4, unsigned long a5,
+ *		  unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
+ *		  struct arm_smccc_quirk *quirk)
+ */
+ENTRY(__arm_smccc_smc)
+	SMCCC SMCCC_SMC
+ENDPROC(__arm_smccc_smc)
+
+/*
+ * void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
+ *		  unsigned long a3, unsigned long a4, unsigned long a5,
+ *		  unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
+ *		  struct arm_smccc_quirk *quirk)
+ */
+ENTRY(__arm_smccc_hvc)
+	SMCCC SMCCC_HVC
+ENDPROC(__arm_smccc_hvc)
diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
index 65915ee..c447085 100644
--- a/arch/arm/cpu/armv8/Makefile
+++ b/arch/arm/cpu/armv8/Makefile
@@ -16,6 +16,8 @@
 obj-y	+= transition.o
 obj-y	+= fwcall.o
 obj-y	+= cpu-dt.o
+obj-$(CONFIG_ARM_SMCCC)		+= smccc-call.o
+
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_ARMV8_SPIN_TABLE) += spin_table.o spin_table_v8.o
 endif
diff --git a/arch/arm/cpu/armv8/smccc-call.S b/arch/arm/cpu/armv8/smccc-call.S
new file mode 100644
index 0000000..bbb6cba
--- /dev/null
+++ b/arch/arm/cpu/armv8/smccc-call.S
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+#include <linux/linkage.h>
+#include <linux/arm-smccc.h>
+#include <generated/asm-offsets.h>
+
+	.macro SMCCC instr
+	.cfi_startproc
+	\instr	#0
+	ldr	x4, [sp]
+	stp	x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS]
+	stp	x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS]
+	ldr	x4, [sp, #8]
+	cbz	x4, 1f /* no quirk structure */
+	ldr	x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS]
+	cmp	x9, #ARM_SMCCC_QUIRK_QCOM_A6
+	b.ne	1f
+	str	x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS]
+1:	ret
+	.cfi_endproc
+	.endm
+
+/*
+ * void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
+ *		  unsigned long a3, unsigned long a4, unsigned long a5,
+ *		  unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
+ *		  struct arm_smccc_quirk *quirk)
+ */
+ENTRY(__arm_smccc_smc)
+	SMCCC	smc
+ENDPROC(__arm_smccc_smc)
+
+/*
+ * void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
+ *		  unsigned long a3, unsigned long a4, unsigned long a5,
+ *		  unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
+ *		  struct arm_smccc_quirk *quirk)
+ */
+ENTRY(__arm_smccc_hvc)
+	SMCCC	hvc
+ENDPROC(__arm_smccc_hvc)
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 0ee4281..53fc936 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -29,12 +29,12 @@
 dtb-$(CONFIG_EXYNOS7420) += exynos7420-espresso7420.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += \
 	rk3036-sdk.dtb \
+	rk3188-radxarock.dtb \
 	rk3288-evb.dtb \
 	rk3288-fennec.dtb \
 	rk3288-firefly.dtb \
 	rk3288-miqi.dtb \
 	rk3288-popmetal.dtb \
-	rk3188-radxarock.dtb \
 	rk3288-rock2-square.dtb \
 	rk3288-tinker.dtb \
 	rk3288-veyron-jerry.dtb \
diff --git a/arch/arm/dts/rk3399-evb.dts b/arch/arm/dts/rk3399-evb.dts
index c3a7ca2..e1f867b 100644
--- a/arch/arm/dts/rk3399-evb.dts
+++ b/arch/arm/dts/rk3399-evb.dts
@@ -30,6 +30,13 @@
 		status = "okay";
 	};
 
+	vccsys: vccsys {
+		compatible = "regulator-fixed";
+		regulator-name = "vccsys";
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
 	vcc3v3_sys: vcc3v3-sys {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc3v3_sys";
@@ -51,6 +58,7 @@
 		regulator-name = "vcc5v0_host";
 		gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>;
 	};
+
 };
 
 &emmc_phy {
@@ -112,6 +120,37 @@
 	status = "okay";
 };
 
+&i2c0 {
+	status = "okay";
+	clock-frequency = <400000>;
+	i2c-scl-falling-time-ns = <50>;
+	i2c-scl-rising-time-ns = <100>;
+	u-boot,dm-pre-reloc;
+
+	rk808: pmic@1b {
+		compatible = "rockchip,rk808";
+		clock-output-names = "xin32k", "wifibt_32kin";
+		interrupt-parent = <&gpio0>;
+		interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int_l>;
+		reg = <0x1b>;
+		rockchip,system-power-controller;
+		#clock-cells = <1>;
+		u-boot,dm-pre-reloc;
+		status = "okay";
+
+		vcc12-supply = <&vcc3v3_sys>;
+		regulators {
+			vcc33_lcd: SWITCH_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc33_lcd";
+			};
+		};
+	};
+};
+
 &pinctrl {
 	pmic {
 		pmic_int_l: pmic-int-l {
diff --git a/arch/arm/dts/rk3399-puma.dts b/arch/arm/dts/rk3399-puma.dts
index 917df1e..50e43c7 100644
--- a/arch/arm/dts/rk3399-puma.dts
+++ b/arch/arm/dts/rk3399-puma.dts
@@ -1,7 +1,7 @@
 /*
  * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
  *
- * SPDX-License-Identifier:     GPL-2.0+
+ * SPDX-License-Identifier:     GPL-2.0+	X11
  */
 
 /dts-v1/;
@@ -91,7 +91,6 @@
 &sdmmc {
         u-boot,dm-pre-reloc;
 	bus-width = <4>;
-	fifo-mode; /* until we fix DMA in SPL */
 	status = "okay";
 };
 
diff --git a/arch/arm/dts/rk3399.dtsi b/arch/arm/dts/rk3399.dtsi
index dbe55f2..d94d780 100644
--- a/arch/arm/dts/rk3399.dtsi
+++ b/arch/arm/dts/rk3399.dtsi
@@ -26,6 +26,7 @@
 		serial4 = &uart4;
 		mmc0 = &sdhci;
 		mmc1 = &sdmmc;
+		i2c0 = &i2c0;
 	};
 
 	cpus {
@@ -668,6 +669,21 @@
 		status = "disabled";
 	};
 
+	i2c0: i2c@ff3c0000 {
+		compatible = "rockchip,rk3399-i2c";
+		reg = <0x0 0xff3c0000 0x0 0x1000>;
+		assigned-clocks = <&pmucru SCLK_I2C0_PMU>;
+		assigned-clock-rates = <200000000>;
+		clocks = <&pmucru SCLK_I2C0_PMU>, <&pmucru PCLK_I2C0_PMU>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH 0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c0_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
 	pinctrl: pinctrl {
 		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-pinctrl";
diff --git a/arch/arm/include/asm/arch-rockchip/bootrom.h b/arch/arm/include/asm/arch-rockchip/bootrom.h
index 79fb1a0..92eb878 100644
--- a/arch/arm/include/asm/arch-rockchip/bootrom.h
+++ b/arch/arm/include/asm/arch-rockchip/bootrom.h
@@ -13,10 +13,15 @@
  */
 extern u32 SAVE_SP_ADDR;
 
-/*
+/**
  * Hand control back to the bootrom to load another
  * boot stage.
  */
-extern void back_to_bootrom(void);
+void back_to_bootrom(void);
+
+/**
+ * Assembler component for the above (do not call this directly)
+ */
+void _back_to_bootrom_s(void);
 
 #endif
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
index b340b05..c424753 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
@@ -337,6 +337,14 @@
 	GRF_GPIO2B4_SEL_MASK	= 3 << GRF_GPIO2B4_SEL_SHIFT,
 	GRF_SPI2TPM_CSN0	= 1,
 
+	/* GRF_GPIO2C_IOMUX */
+	GRF_GPIO2C0_SEL_SHIFT   = 0,
+	GRF_GPIO2C0_SEL_MASK    = 3 << GRF_GPIO2C0_SEL_SHIFT,
+	GRF_UART0BT_SIN         = 1,
+	GRF_GPIO2C1_SEL_SHIFT   = 2,
+	GRF_GPIO2C1_SEL_MASK    = 3 << GRF_GPIO2C1_SEL_SHIFT,
+	GRF_UART0BT_SOUT        = 1,
+
 	/* GRF_GPIO3A_IOMUX */
 	GRF_GPIO3A0_SEL_SHIFT   = 0,
 	GRF_GPIO3A0_SEL_MASK    = 3 << GRF_GPIO3A0_SEL_SHIFT,
diff --git a/arch/arm/include/asm/opcodes-sec.h b/arch/arm/include/asm/opcodes-sec.h
new file mode 100644
index 0000000..16dee8f
--- /dev/null
+++ b/arch/arm/include/asm/opcodes-sec.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2012 ARM Limited
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef __ASM_ARM_OPCODES_SEC_H
+#define __ASM_ARM_OPCODES_SEC_H
+
+#include <asm/opcodes.h>
+
+#define __SMC(imm4) __inst_arm_thumb32(					\
+	0xE1600070 | (((imm4) & 0xF) << 0),				\
+	0xF7F08000 | (((imm4) & 0xF) << 16)				\
+)
+
+#endif /* __ASM_ARM_OPCODES_SEC_H */
diff --git a/arch/arm/include/asm/opcodes-virt.h b/arch/arm/include/asm/opcodes-virt.h
new file mode 100644
index 0000000..9272997
--- /dev/null
+++ b/arch/arm/include/asm/opcodes-virt.h
@@ -0,0 +1,27 @@
+/*
+ * opcodes-virt.h: Opcode definitions for the ARM virtualization extensions
+ * Copyright (C) 2012  Linaro Limited
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef __ASM_ARM_OPCODES_VIRT_H
+#define __ASM_ARM_OPCODES_VIRT_H
+
+#include <asm/opcodes.h>
+
+#define __HVC(imm16) __inst_arm_thumb32(				\
+	0xE1400070 | (((imm16) & 0xFFF0) << 4) | ((imm16) & 0x000F),	\
+	0xF7E08000 | (((imm16) & 0xF000) << 4) | ((imm16) & 0x0FFF)	\
+)
+
+#define __ERET	__inst_arm_thumb32(					\
+	0xE160006E,							\
+	0xF3DE8F00							\
+)
+
+#define __MSR_ELR_HYP(regnum)	__inst_arm_thumb32(			\
+	0xE12EF300 | regnum,						\
+	0xF3808E30 | (regnum << 16)					\
+)
+
+#endif /* ! __ASM_ARM_OPCODES_VIRT_H */
diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h
new file mode 100644
index 0000000..199f0ba
--- /dev/null
+++ b/arch/arm/include/asm/opcodes.h
@@ -0,0 +1,229 @@
+/*
+ *  arch/arm/include/asm/opcodes.h
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef __ASM_ARM_OPCODES_H
+#define __ASM_ARM_OPCODES_H
+
+#ifndef __ASSEMBLY__
+#include <linux/linkage.h>
+extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr);
+#endif
+
+#define ARM_OPCODE_CONDTEST_FAIL   0
+#define ARM_OPCODE_CONDTEST_PASS   1
+#define ARM_OPCODE_CONDTEST_UNCOND 2
+
+
+/*
+ * Assembler opcode byteswap helpers.
+ * These are only intended for use by this header: don't use them directly,
+ * because they will be suboptimal in most cases.
+ */
+#define ___asm_opcode_swab32(x) (	\
+	  (((x) << 24) & 0xFF000000)	\
+	| (((x) <<  8) & 0x00FF0000)	\
+	| (((x) >>  8) & 0x0000FF00)	\
+	| (((x) >> 24) & 0x000000FF)	\
+)
+#define ___asm_opcode_swab16(x) (	\
+	  (((x) << 8) & 0xFF00)		\
+	| (((x) >> 8) & 0x00FF)		\
+)
+#define ___asm_opcode_swahb32(x) (	\
+	  (((x) << 8) & 0xFF00FF00)	\
+	| (((x) >> 8) & 0x00FF00FF)	\
+)
+#define ___asm_opcode_swahw32(x) (	\
+	  (((x) << 16) & 0xFFFF0000)	\
+	| (((x) >> 16) & 0x0000FFFF)	\
+)
+#define ___asm_opcode_identity32(x) ((x) & 0xFFFFFFFF)
+#define ___asm_opcode_identity16(x) ((x) & 0xFFFF)
+
+
+/*
+ * Opcode byteswap helpers
+ *
+ * These macros help with converting instructions between a canonical integer
+ * format and in-memory representation, in an endianness-agnostic manner.
+ *
+ * __mem_to_opcode_*() convert from in-memory representation to canonical form.
+ * __opcode_to_mem_*() convert from canonical form to in-memory representation.
+ *
+ *
+ * Canonical instruction representation:
+ *
+ *	ARM:		0xKKLLMMNN
+ *	Thumb 16-bit:	0x0000KKLL, where KK < 0xE8
+ *	Thumb 32-bit:	0xKKLLMMNN, where KK >= 0xE8
+ *
+ * There is no way to distinguish an ARM instruction in canonical representation
+ * from a Thumb instruction (just as these cannot be distinguished in memory).
+ * Where this distinction is important, it needs to be tracked separately.
+ *
+ * Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not
+ * represent any valid Thumb-2 instruction.  For this range,
+ * __opcode_is_thumb32() and __opcode_is_thumb16() will both be false.
+ *
+ * The ___asm variants are intended only for use by this header, in situations
+ * involving inline assembler.  For .S files, the normal __opcode_*() macros
+ * should do the right thing.
+ */
+#ifdef __ASSEMBLY__
+
+#define ___opcode_swab32(x) ___asm_opcode_swab32(x)
+#define ___opcode_swab16(x) ___asm_opcode_swab16(x)
+#define ___opcode_swahb32(x) ___asm_opcode_swahb32(x)
+#define ___opcode_swahw32(x) ___asm_opcode_swahw32(x)
+#define ___opcode_identity32(x) ___asm_opcode_identity32(x)
+#define ___opcode_identity16(x) ___asm_opcode_identity16(x)
+
+#else /* ! __ASSEMBLY__ */
+
+#include <linux/types.h>
+#include <linux/swab.h>
+
+#define ___opcode_swab32(x) swab32(x)
+#define ___opcode_swab16(x) swab16(x)
+#define ___opcode_swahb32(x) swahb32(x)
+#define ___opcode_swahw32(x) swahw32(x)
+#define ___opcode_identity32(x) ((u32)(x))
+#define ___opcode_identity16(x) ((u16)(x))
+
+#endif /* ! __ASSEMBLY__ */
+
+
+#ifdef CONFIG_CPU_ENDIAN_BE8
+
+#define __opcode_to_mem_arm(x) ___opcode_swab32(x)
+#define __opcode_to_mem_thumb16(x) ___opcode_swab16(x)
+#define __opcode_to_mem_thumb32(x) ___opcode_swahb32(x)
+#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_swab32(x)
+#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_swab16(x)
+#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahb32(x)
+
+#else /* ! CONFIG_CPU_ENDIAN_BE8 */
+
+#define __opcode_to_mem_arm(x) ___opcode_identity32(x)
+#define __opcode_to_mem_thumb16(x) ___opcode_identity16(x)
+#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_identity32(x)
+#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_identity16(x)
+#ifndef CONFIG_CPU_ENDIAN_BE32
+/*
+ * On BE32 systems, using 32-bit accesses to store Thumb instructions will not
+ * work in all cases, due to alignment constraints.  For now, a correct
+ * version is not provided for BE32.
+ */
+#define __opcode_to_mem_thumb32(x) ___opcode_swahw32(x)
+#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahw32(x)
+#endif
+
+#endif /* ! CONFIG_CPU_ENDIAN_BE8 */
+
+#define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x)
+#define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x)
+#ifndef CONFIG_CPU_ENDIAN_BE32
+#define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x)
+#endif
+
+/* Operations specific to Thumb opcodes */
+
+/* Instruction size checks: */
+#define __opcode_is_thumb32(x) (		\
+	   ((x) & 0xF8000000) == 0xE8000000	\
+	|| ((x) & 0xF0000000) == 0xF0000000	\
+)
+#define __opcode_is_thumb16(x) (					\
+	   ((x) & 0xFFFF0000) == 0					\
+	&& !(((x) & 0xF800) == 0xE800 || ((x) & 0xF000) == 0xF000)	\
+)
+
+/* Operations to construct or split 32-bit Thumb instructions: */
+#define __opcode_thumb32_first(x) (___opcode_identity16((x) >> 16))
+#define __opcode_thumb32_second(x) (___opcode_identity16(x))
+#define __opcode_thumb32_compose(first, second) (			\
+	  (___opcode_identity32(___opcode_identity16(first)) << 16)	\
+	| ___opcode_identity32(___opcode_identity16(second))		\
+)
+#define ___asm_opcode_thumb32_first(x) (___asm_opcode_identity16((x) >> 16))
+#define ___asm_opcode_thumb32_second(x) (___asm_opcode_identity16(x))
+#define ___asm_opcode_thumb32_compose(first, second) (			    \
+	  (___asm_opcode_identity32(___asm_opcode_identity16(first)) << 16) \
+	| ___asm_opcode_identity32(___asm_opcode_identity16(second))	    \
+)
+
+/*
+ * Opcode injection helpers
+ *
+ * In rare cases it is necessary to assemble an opcode which the
+ * assembler does not support directly, or which would normally be
+ * rejected because of the CFLAGS or AFLAGS used to build the affected
+ * file.
+ *
+ * Before using these macros, consider carefully whether it is feasible
+ * instead to change the build flags for your file, or whether it really
+ * makes sense to support old assembler versions when building that
+ * particular kernel feature.
+ *
+ * The macros defined here should only be used where there is no viable
+ * alternative.
+ *
+ *
+ * __inst_arm(x): emit the specified ARM opcode
+ * __inst_thumb16(x): emit the specified 16-bit Thumb opcode
+ * __inst_thumb32(x): emit the specified 32-bit Thumb opcode
+ *
+ * __inst_arm_thumb16(arm, thumb): emit either the specified arm or
+ *	16-bit Thumb opcode, depending on whether an ARM or Thumb-2
+ *	kernel is being built
+ *
+ * __inst_arm_thumb32(arm, thumb): emit either the specified arm or
+ *	32-bit Thumb opcode, depending on whether an ARM or Thumb-2
+ *	kernel is being built
+ *
+ *
+ * Note that using these macros directly is poor practice.  Instead, you
+ * should use them to define human-readable wrapper macros to encode the
+ * instructions that you care about.  In code which might run on ARMv7 or
+ * above, you can usually use the __inst_arm_thumb{16,32} macros to
+ * specify the ARM and Thumb alternatives at the same time.  This ensures
+ * that the correct opcode gets emitted depending on the instruction set
+ * used for the kernel build.
+ *
+ * Look at opcodes-virt.h for an example of how to use these macros.
+ */
+#include <linux/stringify.h>
+
+#define __inst_arm(x) ___inst_arm(___asm_opcode_to_mem_arm(x))
+#define __inst_thumb32(x) ___inst_thumb32(				\
+	___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_first(x)),	\
+	___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_second(x))	\
+)
+#define __inst_thumb16(x) ___inst_thumb16(___asm_opcode_to_mem_thumb16(x))
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define __inst_arm_thumb16(arm_opcode, thumb_opcode) \
+	__inst_thumb16(thumb_opcode)
+#define __inst_arm_thumb32(arm_opcode, thumb_opcode) \
+	__inst_thumb32(thumb_opcode)
+#else
+#define __inst_arm_thumb16(arm_opcode, thumb_opcode) __inst_arm(arm_opcode)
+#define __inst_arm_thumb32(arm_opcode, thumb_opcode) __inst_arm(arm_opcode)
+#endif
+
+/* Helpers for the helpers.  Don't use these directly. */
+#ifdef __ASSEMBLY__
+#define ___inst_arm(x) .long x
+#define ___inst_thumb16(x) .short x
+#define ___inst_thumb32(first, second) .short first, second
+#else
+#define ___inst_arm(x) ".long " __stringify(x) "\n\t"
+#define ___inst_thumb16(x) ".short " __stringify(x) "\n\t"
+#define ___inst_thumb32(first, second) \
+	".short " __stringify(first) ", " __stringify(second) "\n\t"
+#endif
+
+#endif /* __ASM_ARM_OPCODES_H */
diff --git a/arch/arm/lib/asm-offsets.c b/arch/arm/lib/asm-offsets.c
index e5bcaea..d620dc0 100644
--- a/arch/arm/lib/asm-offsets.c
+++ b/arch/arm/lib/asm-offsets.c
@@ -14,6 +14,7 @@
 
 #include <common.h>
 #include <linux/kbuild.h>
+#include <linux/arm-smccc.h>
 
 #if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX35) \
 	|| defined(CONFIG_MX51) || defined(CONFIG_MX53)
@@ -198,5 +199,12 @@
 	DEFINE(PLL_DP_HFS_MFN, offsetof(struct dpll, dp_hfs_mfn));
 #endif
 
+#ifdef CONFIG_ARM_SMCCC
+	DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0));
+	DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2));
+	DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id));
+	DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, state));
+#endif
+
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index e814eb0..aa3986d 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -29,9 +29,11 @@
 endif
 
 ifneq ($(CONFIG_OMAP54XX),)
+ifeq ($(CONFIG_DM_SCSI),)
 obj-y	+= pipe3-phy.o
 obj-$(CONFIG_SCSI_AHCI_PLAT) += sata.o
 endif
+endif
 
 ifeq ($(CONFIG_SYS_DCACHE_OFF),)
 obj-y	+= omap-cache.o
diff --git a/arch/arm/mach-omap2/omap5/hw_data.c b/arch/arm/mach-omap2/omap5/hw_data.c
index 5d956b5..a8a6b8a 100644
--- a/arch/arm/mach-omap2/omap5/hw_data.c
+++ b/arch/arm/mach-omap2/omap5/hw_data.c
@@ -361,6 +361,9 @@
 		(*prcm)->cm_l4per_gpio6_clkctrl,
 		(*prcm)->cm_l4per_gpio7_clkctrl,
 		(*prcm)->cm_l4per_gpio8_clkctrl,
+#ifdef CONFIG_SCSI_AHCI_PLAT
+		(*prcm)->cm_l3init_ocp2scp3_clkctrl,
+#endif
 		0
 	};
 
@@ -379,6 +382,9 @@
 #ifdef CONFIG_TI_QSPI
 		(*prcm)->cm_l4per_qspi_clkctrl,
 #endif
+#ifdef CONFIG_SCSI_AHCI_PLAT
+		(*prcm)->cm_l3init_sata_clkctrl,
+#endif
 		0
 	};
 
@@ -411,6 +417,12 @@
 	setbits_le32((*prcm)->cm_l4per_qspi_clkctrl, (1<<24));
 #endif
 
+#ifdef CONFIG_SCSI_AHCI_PLAT
+	/* Enable optional functional clock for SATA */
+	setbits_le32((*prcm)->cm_l3init_sata_clkctrl,
+		     SATA_CLKCTRL_OPTFCLKEN_MASK);
+#endif
+
 	/* Enable SCRM OPT clocks for PER and CORE dpll */
 	setbits_le32((*prcm)->cm_wkupaon_scrm_clkctrl,
 			OPTFCLKEN_SCRM_PER_MASK);
diff --git a/arch/arm/mach-omap2/sata.c b/arch/arm/mach-omap2/sata.c
index 2c2d1bc..0c82689 100644
--- a/arch/arm/mach-omap2/sata.c
+++ b/arch/arm/mach-omap2/sata.c
@@ -37,29 +37,6 @@
 	int ret;
 	u32 val;
 
-	u32 const clk_domains_sata[] = {
-		0
-	};
-
-	u32 const clk_modules_hw_auto_sata[] = {
-		(*prcm)->cm_l3init_ocp2scp3_clkctrl,
-		0
-	};
-
-	u32 const clk_modules_explicit_en_sata[] = {
-		(*prcm)->cm_l3init_sata_clkctrl,
-		0
-	};
-
-	do_enable_clocks(clk_domains_sata,
-			 clk_modules_hw_auto_sata,
-			 clk_modules_explicit_en_sata,
-			 0);
-
-	/* Enable optional functional clock for SATA */
-	setbits_le32((*prcm)->cm_l3init_sata_clkctrl,
-		     SATA_CLKCTRL_OPTFCLKEN_MASK);
-
 	sata_phy.power_reg = (void __iomem *)(*ctrl)->control_phy_power_sata;
 
 	/* Power up the PHY */
diff --git a/arch/arm/mach-omap2/sec-common.c b/arch/arm/mach-omap2/sec-common.c
index 0fa8db0..ec1ffa5 100644
--- a/arch/arm/mach-omap2/sec-common.c
+++ b/arch/arm/mach-omap2/sec-common.c
@@ -39,8 +39,10 @@
 
 	num_args = va_arg(ap, u32);
 
-	if (num_args > 4)
+	if (num_args > 4) {
+		va_end(ap);
 		return 1;
+	}
 
 	/* Copy args to aligned args structure */
 	for (i = 0; i < num_args; i++)
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index af0796d..2b752ad 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -18,6 +18,7 @@
 	select SUPPORT_TPL
 	select SPL
 	select TPL
+	select BOARD_LATE_INIT
 	select ROCKCHIP_BROM_HELPER
 	help
 	  The Rockchip RK3188 is a ARM-based SoC with a quad-core Cortex-A9
@@ -55,6 +56,7 @@
 	select SPL
 	select SPL_SEPARATE_BSS
 	select ENABLE_ARM_SOC_BOOT0_HOOK
+	select DEBUG_UART_BOARD_INIT
 	help
 	  The Rockchip RK3399 is a ARM-based SoC with a dual-core Cortex-A72
 	  and quad-core Cortex-A53.
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 6b251c7..327b267 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -4,6 +4,8 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+obj-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o
+
 ifdef CONFIG_TPL_BUILD
 obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board-tpl.o
 obj-$(CONFIG_ROCKCHIP_BROM_HELPER) += save_boot_param.o
diff --git a/arch/arm/mach-rockchip/bootrom.c b/arch/arm/mach-rockchip/bootrom.c
new file mode 100644
index 0000000..da36f92
--- /dev/null
+++ b/arch/arm/mach-rockchip/bootrom.c
@@ -0,0 +1,16 @@
+/**
+ * Copyright (c) 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/bootrom.h>
+
+void back_to_bootrom(void)
+{
+#if defined(CONFIG_SPL_LIBGENERIC_SUPPORT) && !defined(CONFIG_TPL_BUILD)
+	printf("Returning to boot ROM...");
+#endif
+	_back_to_bootrom_s();
+}
diff --git a/arch/arm/mach-rockchip/rk3188-board.c b/arch/arm/mach-rockchip/rk3188-board.c
index c370156..4be711e 100644
--- a/arch/arm/mach-rockchip/rk3188-board.c
+++ b/arch/arm/mach-rockchip/rk3188-board.c
@@ -11,6 +11,7 @@
 #include <syscon.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3188.h>
 #include <asm/arch/periph.h>
 #include <asm/arch/pmu_rk3288.h>
 #include <asm/arch/boot_mode.h>
@@ -19,6 +20,23 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+int board_late_init(void)
+{
+	struct rk3188_grf *grf;
+
+	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	if (IS_ERR(grf)) {
+		error("grf syscon returned %ld\n", PTR_ERR(grf));
+	} else {
+		/* enable noc remap to mimic legacy loaders */
+		rk_clrsetreg(&grf->soc_con0,
+			NOC_REMAP_MASK << NOC_REMAP_SHIFT,
+			NOC_REMAP_MASK << NOC_REMAP_SHIFT);
+	}
+
+	return 0;
+}
+
 int board_init(void)
 {
 #if defined(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM)
diff --git a/arch/arm/mach-rockchip/rk3399-board-spl.c b/arch/arm/mach-rockchip/rk3399-board-spl.c
index 4f84ec1..050f5e1 100644
--- a/arch/arm/mach-rockchip/rk3399-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3399-board-spl.c
@@ -156,19 +156,24 @@
 	writel(TIMER_EN | TIMER_FMODE, TIMER_CHN10_BASE + TIMER_CONTROL_REG);
 }
 
-#define GRF_EMMCCORE_CON11 0xff77f02c
-void board_init_f(ulong dummy)
-{
-	struct udevice *pinctrl;
-	struct udevice *dev;
-	int ret;
+#define SGRF_DDR_RGN_CON16 0xff330040
 
-	/* Example code showing how to enable the debug UART on RK3288 */
+void board_debug_uart_init(void)
+{
 #include <asm/arch/grf_rk3399.h>
-	/* Enable early UART2 channel C on the RK3399 */
 #define GRF_BASE	0xff770000
 	struct rk3399_grf_regs * const grf = (void *)GRF_BASE;
 
+#if defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff180000)
+	/* Enable early UART0 on the RK3399 */
+	rk_clrsetreg(&grf->gpio2c_iomux,
+		     GRF_GPIO2C0_SEL_MASK,
+		     GRF_UART0BT_SIN << GRF_GPIO2C0_SEL_SHIFT);
+	rk_clrsetreg(&grf->gpio2c_iomux,
+		     GRF_GPIO2C1_SEL_MASK,
+		     GRF_UART0BT_SOUT << GRF_GPIO2C1_SEL_SHIFT);
+#else
+	/* Enable early UART2 channel C on the RK3399 */
 	rk_clrsetreg(&grf->gpio4c_iomux,
 		     GRF_GPIO4C3_SEL_MASK,
 		     GRF_UART2DGBC_SIN << GRF_GPIO4C3_SEL_SHIFT);
@@ -179,6 +184,16 @@
 	rk_clrsetreg(&grf->soc_con7,
 		     GRF_UART_DBG_SEL_MASK,
 		     GRF_UART_DBG_SEL_C << GRF_UART_DBG_SEL_SHIFT);
+#endif
+}
+
+#define GRF_EMMCCORE_CON11 0xff77f02c
+void board_init_f(ulong dummy)
+{
+	struct udevice *pinctrl;
+	struct udevice *dev;
+	int ret;
+
 #define EARLY_UART
 #ifdef EARLY_UART
 	/*
@@ -201,6 +216,17 @@
 		hang();
 	}
 
+	/*
+	 * Disable DDR security regions.
+	 *
+	 * As we are entered from the BootROM, the region from
+	 * 0x0 through 0xfffff (i.e. the first MB of memory) will
+	 * be protected. This will cause issues with the DW_MMC
+	 * driver, which tries to DMA from/to the stack (likely)
+	 * located in this range.
+	 */
+	rk_clrsetreg(SGRF_DDR_RGN_CON16, 0x1FF, 0);
+
 	secure_timer_init();
 
 	ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
@@ -238,6 +264,7 @@
 #ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
 	back_to_bootrom();
 #endif
+
 	return;
 err:
 	printf("spl_board_init: Error %d\n", ret);
diff --git a/arch/arm/mach-rockchip/rk3399/Kconfig b/arch/arm/mach-rockchip/rk3399/Kconfig
index 83bd04a..415466a 100644
--- a/arch/arm/mach-rockchip/rk3399/Kconfig
+++ b/arch/arm/mach-rockchip/rk3399/Kconfig
@@ -10,6 +10,24 @@
 	  with full function and phisical connectors support like type-C ports,
 	  usb2.0 host ports, LVDS, JTAG, MAC, SDcard, HDMI, USB-2-serial...
 
+config TARGET_PUMA_RK3399
+	bool "Theobroma Systems RK3399-Q7 (Puma)"
+	help
+	  The RK3399-Q7 (Puma) is a system-on-module (designed and
+	  marketed by Theobroma Systems) featuring the Rockchip RK3399
+	  in a Qseven-compatible form-factor (running of a single 5V
+	  supply and exposing its external interfaces on a MXM-230
+	  connector).
+
+	  Key features of the RK3399-Q7 include:
+	   * on-module USB 3.0 hub (2x USB 3.0 host + 1x USB 2.0 host)
+	   * USB 3.0 dual-role
+	   * on-module Micrel KSZ9031 GbE PHY
+	   * on-module eMMC (up to 256GB configurations available)
+	   * on-module DDR3 (1GB, 2GB and 4GB configurations available)
+	   * HDMI, eDP, MIPI-DSI, MIPI-DSI/CSI and MIPI-CSI
+	   * SPI, I2C, I2S, UART, GPIO, ...
+
 endchoice
 
 config SYS_SOC
@@ -19,5 +37,6 @@
 	default 0x0800
 
 source "board/rockchip/evb_rk3399/Kconfig"
+source "board/theobroma-systems/puma_rk3399/Kconfig"
 
 endif
diff --git a/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c b/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c
index d32985b..74d4552 100644
--- a/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c
+++ b/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c
@@ -14,6 +14,7 @@
 	{ .compatible = "rockchip,rk3399-pmugrf", .data = ROCKCHIP_SYSCON_PMUGRF },
 	{ .compatible = "rockchip,rk3399-pmusgrf", .data = ROCKCHIP_SYSCON_PMUSGRF },
 	{ .compatible = "rockchip,rk3399-cic", .data = ROCKCHIP_SYSCON_CIC },
+	{ }
 };
 
 U_BOOT_DRIVER(syscon_rk3399) = {
diff --git a/arch/arm/mach-rockchip/save_boot_param.S b/arch/arm/mach-rockchip/save_boot_param.S
index 85b407b..5e6c8db 100644
--- a/arch/arm/mach-rockchip/save_boot_param.S
+++ b/arch/arm/mach-rockchip/save_boot_param.S
@@ -23,10 +23,10 @@
 ENDPROC(save_boot_params)
 
 
-.globl back_to_bootrom
-ENTRY(back_to_bootrom)
+.globl _back_to_bootrom_s
+ENTRY(_back_to_bootrom_s)
 	ldr	r0, =SAVE_SP_ADDR
 	ldr	sp, [r0]
 	mov	r0, #0
 	pop	{r1-r12, pc}
-ENDPROC(back_to_bootrom)
+ENDPROC(_back_to_bootrom_s)
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 2061464..40f423d 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -123,6 +123,20 @@
 		yres = <768>;
 	};
 
+	leds {
+		compatible = "gpio-leds";
+
+		iracibble {
+			gpios = <&gpio_a 1 0>;
+			label = "sandbox:red";
+		};
+
+		martinet {
+			gpios = <&gpio_a 2 0>;
+			label = "sandbox:green";
+		};
+	};
+
 	pci: pci-controller {
 		compatible = "sandbox,pci";
 		device_type = "pci";
diff --git a/arch/x86/cpu/cpu_x86.c b/arch/x86/cpu/cpu_x86.c
index 8be14b5..b465b14 100644
--- a/arch/x86/cpu/cpu_x86.c
+++ b/arch/x86/cpu/cpu_x86.c
@@ -41,10 +41,14 @@
 
 int cpu_x86_get_desc(struct udevice *dev, char *buf, int size)
 {
+	char *ptr;
+
 	if (size < CPU_MAX_NAME_LEN)
 		return -ENOSPC;
 
-	cpu_get_name(buf);
+	ptr = cpu_get_name(buf);
+	if (ptr != buf)
+		strcpy(buf, ptr);
 
 	return 0;
 }
diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c
index 2b1b450..832a5d7 100644
--- a/arch/x86/lib/spl.c
+++ b/arch/x86/lib/spl.c
@@ -37,8 +37,6 @@
 		debug("%s: spl_init() failed\n", __func__);
 		return ret;
 	}
-	preloader_console_init();
-
 	ret = arch_cpu_init();
 	if (ret) {
 		debug("%s: arch_cpu_init() failed\n", __func__);
@@ -49,6 +47,7 @@
 		debug("%s: arch_cpu_init_dm() failed\n", __func__);
 		return ret;
 	}
+	preloader_console_init();
 	ret = print_cpuinfo();
 	if (ret) {
 		debug("%s: print_cpuinfo() failed\n", __func__);
diff --git a/board/atmel/sama5d3_xplained/sama5d3_xplained.c b/board/atmel/sama5d3_xplained/sama5d3_xplained.c
index 2b9da91..ba7f9f2 100644
--- a/board/atmel/sama5d3_xplained/sama5d3_xplained.c
+++ b/board/atmel/sama5d3_xplained/sama5d3_xplained.c
@@ -6,16 +6,13 @@
  */
 
 #include <common.h>
-#include <mmc.h>
 #include <asm/io.h>
 #include <asm/arch/sama5d3_smc.h>
 #include <asm/arch/at91_common.h>
 #include <asm/arch/at91_rstc.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/clk.h>
-#include <atmel_mci.h>
-#include <net.h>
-#include <netdev.h>
+#include <debug_uart.h>
 #include <spl.h>
 #include <asm/arch/atmel_mpddrc.h>
 #include <asm/arch/at91_wdt.h>
@@ -65,24 +62,26 @@
 #ifdef CONFIG_GENERIC_ATMEL_MCI
 static void sama5d3_xplained_mci0_hw_init(void)
 {
-	at91_mci_hw_init();
-
 	at91_set_pio_output(AT91_PIO_PORTE, 2, 0);	/* MCI0 Power */
 }
 #endif
 
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+	at91_seriald_hw_init();
+}
+#endif
+
+#ifdef CONFIG_BOARD_EARLY_INIT_F
 int board_early_init_f(void)
 {
-	at91_periph_clk_enable(ATMEL_ID_PIOA);
-	at91_periph_clk_enable(ATMEL_ID_PIOB);
-	at91_periph_clk_enable(ATMEL_ID_PIOC);
-	at91_periph_clk_enable(ATMEL_ID_PIOD);
-	at91_periph_clk_enable(ATMEL_ID_PIOE);
-
-	at91_seriald_hw_init();
-
+#ifdef CONFIG_DEBUG_UART
+	debug_uart_init();
+#endif
 	return 0;
 }
+#endif
 
 int board_init(void)
 {
@@ -98,10 +97,6 @@
 #ifdef CONFIG_GENERIC_ATMEL_MCI
 	sama5d3_xplained_mci0_hw_init();
 #endif
-#ifdef CONFIG_MACB
-	at91_gmac_hw_init();
-	at91_macb_hw_init();
-#endif
 	return 0;
 }
 
@@ -113,30 +108,14 @@
 	return 0;
 }
 
-int board_eth_init(bd_t *bis)
-{
-#ifdef CONFIG_MACB
-	macb_eth_initialize(0, (void *)ATMEL_BASE_GMAC, 0x00);
-	macb_eth_initialize(0, (void *)ATMEL_BASE_EMAC, 0x00);
-#endif
-	return 0;
-}
-
-#ifdef CONFIG_GENERIC_ATMEL_MCI
-int board_mmc_init(bd_t *bis)
-{
-	atmel_mci_init((void *)ATMEL_BASE_MCI0);
-
-	return 0;
-}
-#endif
-
 /* SPL */
 #ifdef CONFIG_SPL_BUILD
 void spl_board_init(void)
 {
 #ifdef CONFIG_SYS_USE_MMC
+#ifdef CONFIG_GENERIC_ATMEL_MCI
 	sama5d3_xplained_mci0_hw_init();
+#endif
 #elif CONFIG_SYS_USE_NANDFLASH
 	sama5d3_xplained_nand_hw_init();
 #endif
diff --git a/board/atmel/sama5d3xek/sama5d3xek.c b/board/atmel/sama5d3xek/sama5d3xek.c
index 134c2fe..cae6e24 100644
--- a/board/atmel/sama5d3xek/sama5d3xek.c
+++ b/board/atmel/sama5d3xek/sama5d3xek.c
@@ -6,29 +6,22 @@
  */
 
 #include <common.h>
-#include <mmc.h>
 #include <asm/io.h>
 #include <asm/arch/sama5d3_smc.h>
 #include <asm/arch/at91_common.h>
 #include <asm/arch/at91_rstc.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/clk.h>
+#include <debug_uart.h>
 #include <lcd.h>
 #include <linux/ctype.h>
 #include <atmel_hlcdc.h>
-#include <atmel_mci.h>
 #include <phy.h>
 #include <micrel.h>
-#include <net.h>
-#include <netdev.h>
 #include <spl.h>
 #include <asm/arch/atmel_mpddrc.h>
 #include <asm/arch/at91_wdt.h>
 
-#ifdef CONFIG_USB_GADGET_ATMEL_USBA
-#include <asm/arch/atmel_usba_udc.h>
-#endif
-
 DECLARE_GLOBAL_DATA_PTR;
 
 /* ------------------------------------------------------------------------- */
@@ -135,8 +128,6 @@
 #ifdef CONFIG_GENERIC_ATMEL_MCI
 static void sama5d3xek_mci_hw_init(void)
 {
-	at91_mci_hw_init();
-
 	at91_set_pio_output(AT91_PIO_PORTB, 10, 0);	/* MCI0 Power */
 }
 #endif
@@ -215,18 +206,22 @@
 #endif /* CONFIG_LCD_INFO */
 #endif /* CONFIG_LCD */
 
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+	at91_seriald_hw_init();
+}
+#endif
+
+#ifdef CONFIG_BOARD_EARLY_INIT_F
 int board_early_init_f(void)
 {
-	at91_periph_clk_enable(ATMEL_ID_PIOA);
-	at91_periph_clk_enable(ATMEL_ID_PIOB);
-	at91_periph_clk_enable(ATMEL_ID_PIOC);
-	at91_periph_clk_enable(ATMEL_ID_PIOD);
-	at91_periph_clk_enable(ATMEL_ID_PIOE);
-
-	at91_seriald_hw_init();
-
+#ifdef CONFIG_DEBUG_UART
+	debug_uart_init();
+#endif
 	return 0;
 }
+#endif
 
 int board_init(void)
 {
@@ -242,21 +237,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
-#ifdef CONFIG_ATMEL_SPI
-	at91_spi0_hw_init(1 << 0);
-#endif
-#ifdef CONFIG_MACB
-	if (has_emac())
-		at91_macb_hw_init();
-	if (has_gmac())
-		at91_gmac_hw_init();
-#endif
 #ifdef CONFIG_LCD
 	if (has_lcdc())
 		sama5d3xek_lcd_hw_init();
@@ -271,104 +254,6 @@
 	return 0;
 }
 
-int board_phy_config(struct phy_device *phydev)
-{
-	/* board specific timings for GMAC */
-	if (has_gmac()) {
-		/* rx data delay */
-		ksz9021_phy_extended_write(phydev,
-					   MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW,
-					   0x2222);
-		/* tx data delay */
-		ksz9021_phy_extended_write(phydev,
-					   MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW,
-					   0x2222);
-		/* rx/tx clock delay */
-		ksz9021_phy_extended_write(phydev,
-					   MII_KSZ9021_EXT_RGMII_CLOCK_SKEW,
-					   0xf2f4);
-	}
-
-	/* always run the PHY's config routine */
-	if (phydev->drv->config)
-		return phydev->drv->config(phydev);
-
-	return 0;
-}
-
-int board_eth_init(bd_t *bis)
-{
-	int rc = 0;
-
-#ifdef CONFIG_MACB
-	if (has_emac())
-		rc = macb_eth_initialize(0, (void *)ATMEL_BASE_EMAC, 0x00);
-	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;
-}
-
-#ifdef CONFIG_GENERIC_ATMEL_MCI
-int board_mmc_init(bd_t *bis)
-{
-	int rc = 0;
-
-	rc = atmel_mci_init((void *)ATMEL_BASE_MCI0);
-
-	return rc;
-}
-#endif
-
-/* SPI chip select control */
-#ifdef CONFIG_ATMEL_SPI
-#include <spi.h>
-
-int spi_cs_is_valid(unsigned int bus, unsigned int cs)
-{
-	return bus == 0 && cs < 4;
-}
-
-void spi_cs_activate(struct spi_slave *slave)
-{
-	switch (slave->cs) {
-	case 0:
-		at91_set_pio_output(AT91_PIO_PORTD, 13, 0);
-	case 1:
-		at91_set_pio_output(AT91_PIO_PORTD, 14, 0);
-	case 2:
-		at91_set_pio_output(AT91_PIO_PORTD, 15, 0);
-	case 3:
-		at91_set_pio_output(AT91_PIO_PORTD, 16, 0);
-	default:
-		break;
-	}
-}
-
-void spi_cs_deactivate(struct spi_slave *slave)
-{
-	switch (slave->cs) {
-	case 0:
-		at91_set_pio_output(AT91_PIO_PORTD, 13, 1);
-	case 1:
-		at91_set_pio_output(AT91_PIO_PORTD, 14, 1);
-	case 2:
-		at91_set_pio_output(AT91_PIO_PORTD, 15, 1);
-	case 3:
-		at91_set_pio_output(AT91_PIO_PORTD, 16, 1);
-	default:
-		break;
-	}
-}
-#endif /* CONFIG_ATMEL_SPI */
-
 #ifdef CONFIG_BOARD_LATE_INIT
 int board_late_init(void)
 {
@@ -392,12 +277,8 @@
 #ifdef CONFIG_SPL_BUILD
 void spl_board_init(void)
 {
-#ifdef CONFIG_SYS_USE_MMC
-	sama5d3xek_mci_hw_init();
-#elif CONFIG_SYS_USE_NANDFLASH
+#if CONFIG_SYS_USE_NANDFLASH
 	sama5d3xek_nand_hw_init();
-#elif CONFIG_SYS_USE_SERIALFLASH
-	at91_spi0_hw_init(1 << 0);
 #endif
 }
 
diff --git a/board/gaisler/gr_cpci_ax2000/Kconfig b/board/gaisler/gr_cpci_ax2000/Kconfig
deleted file mode 100644
index c12a002..0000000
--- a/board/gaisler/gr_cpci_ax2000/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-if TARGET_GR_CPCI_AX2000
-
-config SYS_BOARD
-	default "gr_cpci_ax2000"
-
-config SYS_CONFIG_NAME
-	default "gr_cpci_ax2000"
-
-endif
diff --git a/board/gaisler/gr_cpci_ax2000/MAINTAINERS b/board/gaisler/gr_cpci_ax2000/MAINTAINERS
deleted file mode 100644
index df55a4c..0000000
--- a/board/gaisler/gr_cpci_ax2000/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-GR_CPCI_AX2000 BOARD
-#M:	-
-S:	Maintained
-F:	board/gaisler/gr_cpci_ax2000/
-F:	include/configs/gr_cpci_ax2000.h
-F:	configs/gr_cpci_ax2000_defconfig
diff --git a/board/gaisler/gr_cpci_ax2000/Makefile b/board/gaisler/gr_cpci_ax2000/Makefile
deleted file mode 100644
index a08e04d..0000000
--- a/board/gaisler/gr_cpci_ax2000/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# (C) Copyright 2003-2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# SPDX-License-Identifier:	GPL-2.0+
-#
-
-obj-y	:= gr_cpci_ax2000.o
diff --git a/board/gaisler/gr_cpci_ax2000/gr_cpci_ax2000.c b/board/gaisler/gr_cpci_ax2000/gr_cpci_ax2000.c
deleted file mode 100644
index f186855..0000000
--- a/board/gaisler/gr_cpci_ax2000/gr_cpci_ax2000.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * (C) Copyright 2008
- * Daniel Hellstrom, daniel@gaisler.com.
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <netdev.h>
-#include <config.h>
-#include <asm/leon.h>
-
-int dram_init(void)
-{
-	/* Does not set gd->ram_size here */
-
-	return 0;
-}
-
-int checkboard(void)
-{
-	puts("Board: GR-CPCI-AX2000\n");
-	return 0;
-}
-
-int misc_init_r(void)
-{
-	return 0;
-}
-
-#ifdef CONFIG_CMD_NET
-int board_eth_init(bd_t *bis)
-{
-	int rc = 0;
-#ifdef CONFIG_SMC91111
-	rc = smc91111_initialize(0, CONFIG_SMC91111_BASE);
-#endif
-	return rc;
-}
-#endif
diff --git a/board/gaisler/gr_ep2s60/Kconfig b/board/gaisler/gr_ep2s60/Kconfig
deleted file mode 100644
index f49937c..0000000
--- a/board/gaisler/gr_ep2s60/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-if TARGET_GR_EP2S60
-
-config SYS_BOARD
-	default "gr_ep2s60"
-
-config SYS_CONFIG_NAME
-	default "gr_ep2s60"
-
-endif
diff --git a/board/gaisler/gr_ep2s60/MAINTAINERS b/board/gaisler/gr_ep2s60/MAINTAINERS
deleted file mode 100644
index 7acd5f4..0000000
--- a/board/gaisler/gr_ep2s60/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-GR_EP2S60 BOARD
-#M:	-
-S:	Maintained
-F:	board/gaisler/gr_ep2s60/
-F:	include/configs/gr_ep2s60.h
-F:	configs/gr_ep2s60_defconfig
diff --git a/board/gaisler/gr_ep2s60/Makefile b/board/gaisler/gr_ep2s60/Makefile
deleted file mode 100644
index 059a9c0..0000000
--- a/board/gaisler/gr_ep2s60/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# (C) Copyright 2003-2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# SPDX-License-Identifier:	GPL-2.0+
-#
-
-obj-y	:= gr_ep2s60.o
diff --git a/board/gaisler/gr_ep2s60/gr_ep2s60.c b/board/gaisler/gr_ep2s60/gr_ep2s60.c
deleted file mode 100644
index a73d89d..0000000
--- a/board/gaisler/gr_ep2s60/gr_ep2s60.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * (C) Copyright 2008
- * Daniel Hellstrom, daniel@gaisler.com.
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <netdev.h>
-#include <config.h>
-#include <asm/leon.h>
-
-int dram_init(void)
-{
-	/* Does not set gd->ram_size here */
-
-	return 0;
-}
-
-int checkboard(void)
-{
-	puts("Board: EP2S60 GRLIB\n");
-	return 0;
-}
-
-int misc_init_r(void)
-{
-	return 0;
-}
-
-#ifdef CONFIG_CMD_NET
-int board_eth_init(bd_t *bis)
-{
-	int rc = 0;
-#ifdef CONFIG_SMC91111
-	rc = smc91111_initialize(0, CONFIG_SMC91111_BASE);
-#endif
-	return rc;
-}
-#endif
diff --git a/board/gaisler/gr_xc3s_1500/Kconfig b/board/gaisler/gr_xc3s_1500/Kconfig
deleted file mode 100644
index e695ba2..0000000
--- a/board/gaisler/gr_xc3s_1500/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-if TARGET_GR_XC3S_1500
-
-config SYS_BOARD
-	default "gr_xc3s_1500"
-
-config SYS_CONFIG_NAME
-	default "gr_xc3s_1500"
-
-endif
diff --git a/board/gaisler/gr_xc3s_1500/MAINTAINERS b/board/gaisler/gr_xc3s_1500/MAINTAINERS
deleted file mode 100644
index c4179d2..0000000
--- a/board/gaisler/gr_xc3s_1500/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-GR_XC3S_1500 BOARD
-#M:	-
-S:	Maintained
-F:	board/gaisler/gr_xc3s_1500/
-F:	include/configs/gr_xc3s_1500.h
-F:	configs/gr_xc3s_1500_defconfig
diff --git a/board/gaisler/gr_xc3s_1500/Makefile b/board/gaisler/gr_xc3s_1500/Makefile
deleted file mode 100644
index 302c461..0000000
--- a/board/gaisler/gr_xc3s_1500/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# (C) Copyright 2003-2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# SPDX-License-Identifier:	GPL-2.0+
-#
-
-obj-y	:= gr_xc3s_1500.o
diff --git a/board/gaisler/gr_xc3s_1500/gr_xc3s_1500.c b/board/gaisler/gr_xc3s_1500/gr_xc3s_1500.c
deleted file mode 100644
index d86047a..0000000
--- a/board/gaisler/gr_xc3s_1500/gr_xc3s_1500.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * (C) Copyright 2007
- * Daniel Hellstrom, daniel@gaisler.com.
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <config.h>
-#include <asm/leon.h>
-
-int dram_init(void)
-{
-	/* Does not set gd->ram_size here */
-
-	return 0;
-}
-
-int checkboard(void)
-{
-	puts("Board: GR-XC3S-1500\n");
-	return 0;
-}
-
-int misc_init_r(void)
-{
-	return 0;
-}
diff --git a/board/gaisler/grsim/Kconfig b/board/gaisler/grsim/Kconfig
deleted file mode 100644
index 18598d3..0000000
--- a/board/gaisler/grsim/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-if TARGET_GRSIM
-
-config SYS_BOARD
-	default "grsim"
-
-config SYS_CONFIG_NAME
-	default "grsim"
-
-endif
diff --git a/board/gaisler/grsim/MAINTAINERS b/board/gaisler/grsim/MAINTAINERS
deleted file mode 100644
index 4b3312e..0000000
--- a/board/gaisler/grsim/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-GRSIM BOARD
-#M:	-
-S:	Maintained
-F:	board/gaisler/grsim/
-F:	include/configs/grsim.h
-F:	configs/grsim_defconfig
diff --git a/board/gaisler/grsim/Makefile b/board/gaisler/grsim/Makefile
deleted file mode 100644
index 4c93bda..0000000
--- a/board/gaisler/grsim/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# (C) Copyright 2003-2004
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# SPDX-License-Identifier:	GPL-2.0+
-#
-
-obj-y	:= grsim.o
diff --git a/board/gaisler/grsim/grsim.c b/board/gaisler/grsim/grsim.c
deleted file mode 100644
index 99262b0..0000000
--- a/board/gaisler/grsim/grsim.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * GRSIM/TSIM board
- *
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <asm/leon.h>
-
-int dram_init(void)
-{
-	/* Does not set gd->ram_size here */
-
-	return 0;
-}
-
-int checkboard(void)
-{
-	puts("Board: GRSIM/TSIM\n");
-	return 0;
-}
-
-int misc_init_r(void)
-{
-	return 0;
-}
diff --git a/board/gaisler/grsim_leon2/Kconfig b/board/gaisler/grsim_leon2/Kconfig
deleted file mode 100644
index 0d21a0a..0000000
--- a/board/gaisler/grsim_leon2/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-if TARGET_GRSIM_LEON2
-
-config SYS_BOARD
-	default "grsim_leon2"
-
-config SYS_CONFIG_NAME
-	default "grsim_leon2"
-
-endif
diff --git a/board/gaisler/grsim_leon2/MAINTAINERS b/board/gaisler/grsim_leon2/MAINTAINERS
deleted file mode 100644
index bf4a950..0000000
--- a/board/gaisler/grsim_leon2/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-GRSIM_LEON2 BOARD
-#M:	-
-S:	Maintained
-F:	board/gaisler/grsim_leon2/
-F:	include/configs/grsim_leon2.h
-F:	configs/grsim_leon2_defconfig
diff --git a/board/gaisler/grsim_leon2/Makefile b/board/gaisler/grsim_leon2/Makefile
deleted file mode 100644
index 5468305..0000000
--- a/board/gaisler/grsim_leon2/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# (C) Copyright 2003-2004
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# SPDX-License-Identifier:	GPL-2.0+
-#
-
-obj-y	:= grsim_leon2.o
diff --git a/board/gaisler/grsim_leon2/grsim_leon2.c b/board/gaisler/grsim_leon2/grsim_leon2.c
deleted file mode 100644
index c6c4bb4..0000000
--- a/board/gaisler/grsim_leon2/grsim_leon2.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * GRSIM/TSIM board
- *
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <asm/leon.h>
-
-int dram_init(void)
-{
-	/* Does not set gd->ram_size here */
-
-	return 0;
-}
-
-int checkboard(void)
-{
-	puts("Board: GRSIM/TSIM LEON2\n");
-	return 0;
-}
-
-int misc_init_r(void)
-{
-	return 0;
-}
diff --git a/board/ibf-dsp561/Kconfig b/board/ibf-dsp561/Kconfig
deleted file mode 100644
index acf5d7c..0000000
--- a/board/ibf-dsp561/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-if TARGET_IBF_DSP561
-
-config SYS_BOARD
-	default "ibf-dsp561"
-
-config SYS_CONFIG_NAME
-	default "ibf-dsp561"
-
-endif
diff --git a/board/ibf-dsp561/MAINTAINERS b/board/ibf-dsp561/MAINTAINERS
deleted file mode 100644
index dfd0f90..0000000
--- a/board/ibf-dsp561/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-IBF-DSP561 BOARD
-M:	I-SYST Micromodule <support@i-syst.com>
-S:	Maintained
-F:	board/ibf-dsp561/
-F:	include/configs/ibf-dsp561.h
-F:	configs/ibf-dsp561_defconfig
diff --git a/board/ibf-dsp561/Makefile b/board/ibf-dsp561/Makefile
deleted file mode 100644
index cbf1612..0000000
--- a/board/ibf-dsp561/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# U-Boot - Makefile
-#
-# Copyright (c) 2005-2007 Analog Device Inc.
-#
-# (C) Copyright 2000-2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# SPDX-License-Identifier:	GPL-2.0+
-#
-
-obj-y	:= ibf-dsp561.o
diff --git a/board/ibf-dsp561/config.mk b/board/ibf-dsp561/config.mk
deleted file mode 100644
index 854d7db..0000000
--- a/board/ibf-dsp561/config.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Copyright (c) 2005-2008 Analog Device Inc.
-#
-# (C) Copyright 2001
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# SPDX-License-Identifier:	GPL-2.0+
-#
-
-# Set some default LDR flags based on boot mode.
-LDR_FLAGS-BFIN_BOOT_PARA := --bits 16
diff --git a/board/ibf-dsp561/ibf-dsp561.c b/board/ibf-dsp561/ibf-dsp561.c
deleted file mode 100644
index 8475fda..0000000
--- a/board/ibf-dsp561/ibf-dsp561.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * U-Boot - main board file
- *
- * Copyright (c) 2008-2009 I-SYST.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <netdev.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-int checkboard(void)
-{
-	printf("Board: I-SYST IBF-DSP561 Micromodule\n");
-	printf("       Support: http://www.i-syst.com/\n");
-	return 0;
-}
-
-#ifdef CONFIG_DRIVER_AX88180
-int board_eth_init(bd_t *bis)
-{
-	return ax88180_initialize(bis);
-}
-#endif
diff --git a/board/theobroma-systems/puma_rk3399/Kconfig b/board/theobroma-systems/puma_rk3399/Kconfig
new file mode 100644
index 0000000..a645590
--- /dev/null
+++ b/board/theobroma-systems/puma_rk3399/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_PUMA_RK3399
+
+config SYS_BOARD
+	default "puma_rk3399"
+
+config SYS_VENDOR
+	default "theobroma-systems"
+
+config SYS_CONFIG_NAME
+	default "puma_rk3399"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+
+endif
diff --git a/board/theobroma-systems/puma_rk3399/MAINTAINERS b/board/theobroma-systems/puma_rk3399/MAINTAINERS
new file mode 100644
index 0000000..ccec09c
--- /dev/null
+++ b/board/theobroma-systems/puma_rk3399/MAINTAINERS
@@ -0,0 +1,10 @@
+PUMA-RK3399
+M:	Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+M:	Klaus Goger <klaus.goger@theobroma-systems.com>
+S:	Maintained
+F:	board/theobroma-systems/puma_rk3399
+F:	include/configs/puma_rk3399.h
+F:	arch/arm/dts/rk3399-puma.dts
+F:	configs/puma-rk3399_defconfig
+W:	https://www.theobroma-systems.com/rk3399-q7/tech-specs
+T:	git git://git.theobroma-systems.com/puma-u-boot.git
diff --git a/board/theobroma-systems/puma_rk3399/Makefile b/board/theobroma-systems/puma_rk3399/Makefile
new file mode 100644
index 0000000..d962b56
--- /dev/null
+++ b/board/theobroma-systems/puma_rk3399/Makefile
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= puma-rk3399.o
diff --git a/board/theobroma-systems/puma_rk3399/README b/board/theobroma-systems/puma_rk3399/README
new file mode 100644
index 0000000..1a8d02b
--- /dev/null
+++ b/board/theobroma-systems/puma_rk3399/README
@@ -0,0 +1,73 @@
+Introduction
+============
+
+The RK3399-Q7 (Puma) is a system-on-module featuring the Rockchip
+RK3399 in a Qseven-compatible form-factor.
+
+RK3399-Q7 features:
+	* CPU: ARMv8 64bit Big-Little architecture,
+		* Big: dual-core Cortex-A72
+		* Little: quad-core Cortex-A53
+		* IRAM: 200KB
+	* DRAM: 4GB-128MB dual-channel
+	* eMMC: onboard eMMC
+	* SD/MMC
+	* GbE (onboard Micrel KSZ9031) Gigabit ethernet PHY
+	* USB:
+		* USB3.0 dual role port
+		* 2x USB3.0 host, 1x USB2.0 host via onboard USB3.0 hub
+	* Display: HDMI/eDP/MIPI
+	* Camera: 2x CSI (one on the edge connector, one on the Q7 specified CSI ZIF)
+	* NOR Flash: onboard SPI NOR
+	* Companion Controller: onboard additional Cortex-M0 microcontroller
+		* RTC
+		* fan controller
+		* CAN
+
+Here is the step-by-step to boot to U-Boot on rk3399.
+
+Get the Source and build ATF/Cortex-M0 binaries
+===============================================
+
+  > git clone git://git.theobroma-systems.com/arm-trusted-firmware.git
+  > git clone git://git.theobroma-systems.com/rk3399-cortex-m0.git
+
+Compile the ATF
+===============
+
+  > cd arm-trusted-firmware
+  > make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3399 bl31
+  > cp build/rk3399/release/bl31.bin ../u-boot
+
+Compile the M0 firmware
+=======================
+
+  > cd ../rk3399-cortex-m0
+  > make CROSS_COMPILE=arm-cortex_m0-eabi-
+  > cp rk3399m0.bin ../u-boot
+
+Compile the U-Boot
+==================
+
+  > cd ../u-boot
+  > make CROSS_COMPILE=aarch64-linux-gnu- puma-rk3399_defconfig all
+
+Package the image
+=================
+
+	> tools/mkimage -n rk3399 -T rksd -d spl/u-boot-spl.bin spl.img
+	> tools/mkimage -f board/theobroma/puma_rk3399/fit_spl_atf.its \
+		-E rk3399_bl3x.itb
+
+Flash the image
+===============
+
+Copy the SPL to offset 32k and the FIT image containing the payloads
+(U-Boot proper, ATF, M0 Firmware, devicetree) to offset 256k on a SD
+card.
+
+  > dd if=spl.img of=/dev/sdb seek=64
+  > dd if=rk3399_bl3x.itb of=/dev/sdb seek=512
+
+After powering up the board (with the inserted SD card), you should see
+a U-Boot console on UART0 (115200n8).
diff --git a/board/theobroma-systems/puma_rk3399/fit_spl_atf.its b/board/theobroma-systems/puma_rk3399/fit_spl_atf.its
new file mode 100644
index 0000000..f93c251
--- /dev/null
+++ b/board/theobroma-systems/puma_rk3399/fit_spl_atf.its
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * Minimal dts for a SPL FIT image payload.
+ *
+ * SPDX-License-Identifier: GPL-2.0+  X11
+ */
+
+/dts-v1/;
+
+/ {
+	description = "FIT image with U-Boot proper, ATF bl31, M0 Firmware, DTB";
+	#address-cells = <1>;
+
+	images {
+		uboot@1 {
+			description = "U-Boot (64-bit)";
+			data = /incbin/("../../../u-boot-nodtb.bin");
+			type = "standalone";
+			arch = "arm64";
+			compression = "none";
+			load = <0x00200000>;
+		};
+		atf@1 {
+			description = "ARM Trusted Firmware";
+			data = /incbin/("../../../bl31.bin");
+			type = "firmware";
+			arch = "arm64";
+			compression = "none";
+			load = <0x00001000>;
+			entry = <0x00001000>;
+		};
+		pmu@1 {
+		        description = "Cortex-M0 firmware";
+			data = /incbin/("../../../rk3399m0.bin");
+			type = "pmu-firmware";
+			compression = "none";
+			load = <0xff8c0000>;
+                };
+		fdt@1 {
+			description = "RK3399-Q7 (Puma) flat device-tree";
+			data = /incbin/("../../../u-boot.dtb");
+			type = "flat_dt";
+			compression = "none";
+		};
+	};
+
+	configurations {
+		default = "conf@1";
+		conf@1 {
+			description = "Theobroma Systems RK3399-Q7 (Puma) SoM";
+			firmware = "uboot@1";
+			loadables = "atf@1";
+			fdt = "fdt@1";
+		};
+	};
+};
diff --git a/board/theobroma-systems/puma_rk3399/puma-rk3399.c b/board/theobroma-systems/puma_rk3399/puma-rk3399.c
new file mode 100644
index 0000000..fb4d31e
--- /dev/null
+++ b/board/theobroma-systems/puma_rk3399/puma-rk3399.c
@@ -0,0 +1,71 @@
+/*
+ * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#include <common.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <dm/uclass-internal.h>
+#include <asm/arch/periph.h>
+#include <power/regulator.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+	struct udevice *pinctrl, *regulator;
+	int ret;
+
+	/*
+	 * The PWM does not have decicated interrupt number in dts and can
+	 * not get periph_id by pinctrl framework, so let's init them here.
+	 * The PWM2 and PWM3 are for pwm regulators.
+	 */
+	ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
+	if (ret) {
+		debug("%s: Cannot find pinctrl device\n", __func__);
+		goto out;
+	}
+
+	ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_PWM2);
+	if (ret) {
+		debug("%s PWM2 pinctrl init fail!\n", __func__);
+		goto out;
+	}
+
+	/* rk3399 need to init vdd_center to get the correct output voltage */
+	ret = regulator_get_by_platname("vdd_center", &regulator);
+	if (ret)
+		debug("%s: Cannot get vdd_center regulator\n", __func__);
+
+	ret = regulator_get_by_platname("vcc5v0_host", &regulator);
+	if (ret) {
+		debug("%s vcc5v0_host init fail! ret %d\n", __func__, ret);
+		goto out;
+	}
+
+	ret = regulator_set_enable(regulator, true);
+	if (ret) {
+		debug("%s vcc5v0-host-en set fail!\n", __func__);
+		goto out;
+	}
+
+out:
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = 0x80000000;
+	return 0;
+}
+
+int dram_init_banksize(void)
+{
+	/* Reserve 0x200000 for ATF bl31 */
+	gd->bd->bi_dram[0].start = 0x200000;
+	gd->bd->bi_dram[0].size = 0x7e000000;
+
+	return 0;
+}
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 661ae7a..13dc46a 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -667,6 +667,15 @@
 	help
 	  Enable the "icache" and "dcache" commands
 
+config CMD_LED
+	bool "led"
+	default y if LED
+	help
+	  Enable the 'led' command which allows for control of LEDs supported
+	  by the board. The LEDs can be listed with 'led list' and controlled
+	  with led on/off/togle/blink. Any LED drivers can be controlled with
+	  this command, e.g. led_gpio.
+
 config CMD_TIME
 	bool "time"
 	help
diff --git a/cmd/Makefile b/cmd/Makefile
index ef1406b..97c862f 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -23,7 +23,6 @@
 obj-$(CONFIG_CMD_BMP) += bmp.o
 obj-$(CONFIG_CMD_BOOTEFI) += bootefi.o
 obj-$(CONFIG_CMD_BOOTMENU) += bootmenu.o
-obj-$(CONFIG_CMD_BOOTLDR) += bootldr.o
 obj-$(CONFIG_CMD_BOOTSTAGE) += bootstage.o
 obj-$(CONFIG_CMD_BOOTZ) += bootz.o
 obj-$(CONFIG_CMD_BOOTI) += booti.o
@@ -32,7 +31,6 @@
 obj-$(CONFIG_CMD_CLK) += clk.o
 obj-$(CONFIG_CMD_CONFIG) += config.o
 obj-$(CONFIG_CMD_CONSOLE) += console.o
-obj-$(CONFIG_CMD_CPLBINFO) += cplbinfo.o
 obj-$(CONFIG_CMD_CPU) += cpu.o
 obj-$(CONFIG_DATAFLASH_MMC_SELECT) += dataflash_mmc_mux.o
 obj-$(CONFIG_CMD_DATE) += date.o
@@ -77,8 +75,8 @@
 obj-$(CONFIG_CMD_ITEST) += itest.o
 obj-$(CONFIG_CMD_JFFS2) += jffs2.o
 obj-$(CONFIG_CMD_CRAMFS) += cramfs.o
-obj-$(CONFIG_CMD_LDRINFO) += ldrinfo.o
-obj-$(CONFIG_LED_STATUS_CMD) += led.o
+obj-$(CONFIG_LED_STATUS_CMD) += legacy_led.o
+obj-$(CONFIG_CMD_LED) += led.o
 obj-$(CONFIG_CMD_LICENSE) += license.o
 obj-y += load.o
 obj-$(CONFIG_LOGBUFFER) += log.o
@@ -99,7 +97,6 @@
 obj-$(CONFIG_CMD_NAND) += nand.o
 obj-$(CONFIG_CMD_NET) += net.o
 obj-$(CONFIG_CMD_ONENAND) += onenand.o
-obj-$(CONFIG_CMD_OTP) += otp.o
 obj-$(CONFIG_CMD_PART) += part.o
 ifdef CONFIG_PCI
 obj-$(CONFIG_CMD_PCI) += pci.o
@@ -118,9 +115,7 @@
 obj-$(CONFIG_SCSI) += scsi.o disk.o
 obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o
 obj-$(CONFIG_CMD_SETEXPR) += setexpr.o
-obj-$(CONFIG_CMD_SOFTSWITCH) += softswitch.o
 obj-$(CONFIG_CMD_SPI) += spi.o
-obj-$(CONFIG_CMD_SPIBOOTLDR) += spibootldr.o
 obj-$(CONFIG_CMD_STRINGS) += strings.o
 obj-$(CONFIG_CMD_TERMINAL) += terminal.o
 obj-$(CONFIG_CMD_TIME) += time.o
diff --git a/cmd/bootldr.c b/cmd/bootldr.c
deleted file mode 100644
index 38b3b2f..0000000
--- a/cmd/bootldr.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * U-Boot - bootldr.c
- *
- * Copyright (c) 2005-2008 Analog Devices Inc.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <config.h>
-#include <common.h>
-#include <command.h>
-
-#include <asm/blackfin.h>
-#include <asm/mach-common/bits/bootrom.h>
-
-/* Simple sanity check on the specified address to make sure it contains
- * an LDR image of some sort.
- */
-static bool ldr_valid_signature(uint8_t *data)
-{
-#if defined(__ADSPBF561__)
-
-	/* BF56x has a 4 byte global header */
-	if (data[3] == (GFLAG_56X_SIGN_MAGIC << (GFLAG_56X_SIGN_SHIFT - 24)))
-		return true;
-
-#elif defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
-      defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) || \
-      defined(__ADSPBF538__) || defined(__ADSPBF539__)
-
-	/* all the BF53x should start at this address mask */
-	uint32_t addr;
-	memmove(&addr, data, sizeof(addr));
-	if ((addr & 0xFF0FFF0F) == 0xFF000000)
-		return true;
-#else
-
-	/* everything newer has a magic byte */
-	uint32_t count;
-	memmove(&count, data + 8, sizeof(count));
-	if (data[3] == 0xAD && count == 0)
-		return true;
-
-#endif
-
-	return false;
-}
-
-/* If the Blackfin is new enough, the Blackfin on-chip ROM supports loading
- * LDRs from random memory addresses.  So whenever possible, use that.  In
- * the older cases (BF53x/BF561), parse the LDR format ourselves.
- */
-static void ldr_load(uint8_t *base_addr)
-{
-#if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
-  /*defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) ||*/\
-    defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__)
-
-	uint32_t addr;
-	uint32_t count;
-	uint16_t flags;
-
-	/* the bf56x has a 4 byte global header ... but it is useless to
-	 * us when booting an LDR from a memory address, so skip it
-	 */
-# ifdef __ADSPBF561__
-	base_addr += 4;
-# endif
-
-	memmove(&flags, base_addr + 8, sizeof(flags));
-	bfin_write_EVT1(flags & BFLAG_53X_RESVECT ? 0xFFA00000 : 0xFFA08000);
-
-	do {
-		/* block header may not be aligned */
-		memmove(&addr, base_addr, sizeof(addr));
-		memmove(&count, base_addr+4, sizeof(count));
-		memmove(&flags, base_addr+8, sizeof(flags));
-		base_addr += sizeof(addr) + sizeof(count) + sizeof(flags);
-
-		printf("loading to 0x%08x (%#x bytes) flags: 0x%04x\n",
-			addr, count, flags);
-
-		if (!(flags & BFLAG_53X_IGNORE)) {
-			if (flags & BFLAG_53X_ZEROFILL)
-				memset((void *)addr, 0x00, count);
-			else
-				memcpy((void *)addr, base_addr, count);
-
-			if (flags & BFLAG_53X_INIT) {
-				void (*init)(void) = (void *)addr;
-				init();
-			}
-		}
-
-		if (!(flags & BFLAG_53X_ZEROFILL))
-			base_addr += count;
-	} while (!(flags & BFLAG_53X_FINAL));
-
-#endif
-}
-
-/* For BF537, we use the _BOOTROM_BOOT_DXE_FLASH funky ROM function.
- * For all other BF53x/BF56x, we just call the entry point.
- * For everything else (newer), we use _BOOTROM_MEMBOOT ROM function.
- */
-static void ldr_exec(void *addr)
-{
-#if defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__)
-
-	/* restore EVT1 to reset value as this is what the bootrom uses as
-	 * the default entry point when booting the final block of LDRs
-	 */
-	bfin_write_EVT1(L1_INST_SRAM);
-	__asm__("call (%0);" : : "a"(_BOOTROM_MEMBOOT), "q7"(addr) : "RETS", "memory");
-
-#elif defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
-      defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__)
-
-	void (*ldr_entry)(void) = (void *)bfin_read_EVT1();
-	ldr_entry();
-
-#else
-
-	int32_t (*BOOTROM_MEM)(void *, int32_t, int32_t, void *) = (void *)_BOOTROM_MEMBOOT;
-	BOOTROM_MEM(addr, 0, 0, NULL);
-
-#endif
-}
-
-/*
- * the bootldr command loads an address, checks to see if there
- *   is a Boot stream that the on-chip BOOTROM can understand,
- *   and loads it via the BOOTROM Callback. It is possible
- *   to also add booting from SPI, or TWI, but this function does
- *   not currently support that.
- */
-int do_bootldr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-	void *addr;
-
-	/* Get the address */
-	if (argc < 2)
-		addr = (void *)load_addr;
-	else
-		addr = (void *)simple_strtoul(argv[1], NULL, 16);
-
-	/* Check if it is a LDR file */
-	if (ldr_valid_signature(addr)) {
-		printf("## Booting ldr image at 0x%p ...\n", addr);
-		ldr_load(addr);
-
-		icache_disable();
-		dcache_disable();
-
-		ldr_exec(addr);
-	} else
-		printf("## No ldr image at address 0x%p\n", addr);
-
-	return 0;
-}
-
-U_BOOT_CMD(
-	bootldr, 2, 0, do_bootldr,
-	"boot ldr image from memory",
-	"[addr]\n"
-	""
-);
diff --git a/cmd/cplbinfo.c b/cmd/cplbinfo.c
deleted file mode 100644
index ab5b3b5..0000000
--- a/cmd/cplbinfo.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * cmd_cplbinfo.c - dump the instruction/data cplb tables
- *
- * Copyright (c) 2007-2008 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <command.h>
-#include <asm/blackfin.h>
-#include <asm/cplb.h>
-#include <asm/mach-common/bits/mpu.h>
-
-/*
- * Translate the PAGE_SIZE bits into a human string
- */
-static const char *cplb_page_size(uint32_t data)
-{
-	static const char page_size_string_table[][4] = { "1K", "4K", "1M", "4M" };
-	return page_size_string_table[(data & PAGE_SIZE_MASK) >> PAGE_SIZE_SHIFT];
-}
-
-/*
- * show a hardware cplb table
- */
-static void show_cplb_table(uint32_t *addr, uint32_t *data)
-{
-	int i;
-	printf("      Address     Data   Size  Valid  Locked\n");
-	for (i = 1; i <= 16; ++i) {
-		printf(" %2i 0x%p  0x%05X   %s     %c      %c\n",
-			i, (void *)*addr, *data,
-			cplb_page_size(*data),
-			(*data & CPLB_VALID ? 'Y' : 'N'),
-			(*data & CPLB_LOCK ? 'Y' : 'N'));
-		++addr;
-		++data;
-	}
-}
-
-/*
- * display current instruction and data cplb tables
- */
-int do_cplbinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-	printf("%s CPLB table [%08x]:\n", "Instruction", *(uint32_t *)DMEM_CONTROL);
-	show_cplb_table((uint32_t *)ICPLB_ADDR0, (uint32_t *)ICPLB_DATA0);
-
-	printf("%s CPLB table [%08x]:\n", "Data", *(uint32_t *)IMEM_CONTROL);
-	show_cplb_table((uint32_t *)DCPLB_ADDR0, (uint32_t *)DCPLB_DATA0);
-
-	return 0;
-}
-
-U_BOOT_CMD(
-	cplbinfo, 1, 0, do_cplbinfo,
-	"display current CPLB tables",
-	""
-);
diff --git a/cmd/cramfs.c b/cmd/cramfs.c
index 965ca4e..4e75de8 100644
--- a/cmd/cramfs.c
+++ b/cmd/cramfs.c
@@ -13,11 +13,13 @@
 #include <common.h>
 #include <command.h>
 #include <malloc.h>
+#include <mapmem.h>
 #include <linux/list.h>
 #include <linux/ctype.h>
 #include <jffs2/jffs2.h>
 #include <jffs2/load_kernel.h>
 #include <cramfs/cramfs_fs.h>
+#include <asm/io.h>
 
 /* enable/disable debugging messages */
 #define	DEBUG_CRAMFS
@@ -95,6 +97,7 @@
 	char *filename;
 	int size;
 	ulong offset = load_addr;
+	char *offset_virt;
 
 	struct part_info part;
 	struct mtd_device dev;
@@ -111,7 +114,7 @@
 	dev.id = &id;
 	part.dev = &dev;
 	/* fake the address offset */
-	part.offset = addr - OFFSET_ADJUSTMENT;
+	part.offset = (u64)(uintptr_t) map_sysmem(addr - OFFSET_ADJUSTMENT, 0);
 
 	/* pre-set Boot file name */
 	if ((filename = getenv("bootfile")) == NULL) {
@@ -127,9 +130,10 @@
 		filename = argv[2];
 	}
 
+	offset_virt = map_sysmem(offset, 0);
 	size = 0;
 	if (cramfs_check(&part))
-		size = cramfs_load ((char *) offset, &part, filename);
+		size = cramfs_load (offset_virt, &part, filename);
 
 	if (size > 0) {
 		printf("### CRAMFS load complete: %d bytes loaded to 0x%lx\n",
@@ -139,6 +143,9 @@
 		printf("### CRAMFS LOAD ERROR<%x> for %s!\n", size, filename);
 	}
 
+	unmap_sysmem(offset_virt);
+	unmap_sysmem((void *)(uintptr_t)part.offset);
+
 	return !(size > 0);
 }
 
@@ -172,7 +179,7 @@
 	dev.id = &id;
 	part.dev = &dev;
 	/* fake the address offset */
-	part.offset = addr - OFFSET_ADJUSTMENT;
+	part.offset = (u64)(uintptr_t) map_sysmem(addr - OFFSET_ADJUSTMENT, 0);
 
 	if (argc == 2)
 		filename = argv[1];
@@ -180,6 +187,7 @@
 	ret = 0;
 	if (cramfs_check(&part))
 		ret = cramfs_ls (&part, filename);
+	unmap_sysmem((void *)(uintptr_t)part.offset);
 
 	return ret ? 0 : 1;
 }
diff --git a/cmd/ldrinfo.c b/cmd/ldrinfo.c
deleted file mode 100644
index 2b49297..0000000
--- a/cmd/ldrinfo.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * U-Boot - ldrinfo
- *
- * Copyright (c) 2010 Analog Devices Inc.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <config.h>
-#include <common.h>
-#include <command.h>
-
-#include <asm/blackfin.h>
-#include <asm/mach-common/bits/bootrom.h>
-
-static uint32_t ldrinfo_header(const void *addr)
-{
-	uint32_t skip = 0;
-
-#if defined(__ADSPBF561__)
-	/* BF56x has a 4 byte global header */
-	uint32_t header, sign;
-	static const char * const spi_speed[] = {
-		"500K", "1M", "2M", "??",
-	};
-
-	memcpy(&header, addr, sizeof(header));
-
-	sign = (header & GFLAG_56X_SIGN_MASK) >> GFLAG_56X_SIGN_SHIFT;
-	printf("Header: %08X ( %s-bit-flash wait:%i hold:%i spi:%s %s)\n",
-		header,
-		(header & GFLAG_56X_16BIT_FLASH) ? "16" : "8",
-		(header & GFLAG_56X_WAIT_MASK) >> GFLAG_56X_WAIT_SHIFT,
-		(header & GFLAG_56X_HOLD_MASK) >> GFLAG_56X_HOLD_SHIFT,
-		spi_speed[(header & GFLAG_56X_SPI_MASK) >> GFLAG_56X_SPI_SHIFT],
-		sign == GFLAG_56X_SIGN_MAGIC ? "" : "!!hdrsign!! ");
-
-	skip = 4;
-#endif
-
-	    /* |Block @ 12345678: 12345678 12345678 12345678 12345678 | */
-#if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
-    defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) || \
-    defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__)
-	printf("                  Address  Count    Flags\n");
-#else
-	printf("                  BCode    Address  Count    Argument\n");
-#endif
-
-	return skip;
-}
-
-struct ldr_flag {
-	uint16_t flag;
-	const char *desc;
-};
-
-static uint32_t ldrinfo_block(const void *base_addr)
-{
-	uint32_t count;
-
-	printf("Block @ %08X: ", (uint32_t)base_addr);
-
-#if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
-    defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) || \
-    defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__)
-
-	uint32_t addr, pval;
-	uint16_t flags;
-	int i;
-	static const struct ldr_flag ldr_flags[] = {
-		{ BFLAG_53X_ZEROFILL,    "zerofill"  },
-		{ BFLAG_53X_RESVECT,     "resvect"   },
-		{ BFLAG_53X_INIT,        "init"      },
-		{ BFLAG_53X_IGNORE,      "ignore"    },
-		{ BFLAG_53X_COMPRESSED,  "compressed"},
-		{ BFLAG_53X_FINAL,       "final"     },
-	};
-
-	memcpy(&addr, base_addr, sizeof(addr));
-	memcpy(&count, base_addr+4, sizeof(count));
-	memcpy(&flags, base_addr+8, sizeof(flags));
-
-	printf("%08X %08X %04X ( ", addr, count, flags);
-
-	for (i = 0; i < ARRAY_SIZE(ldr_flags); ++i)
-		if (flags & ldr_flags[i].flag)
-			printf("%s ", ldr_flags[i].desc);
-
-	pval = (flags & BFLAG_53X_PFLAG_MASK) >> BFLAG_53X_PFLAG_SHIFT;
-	if (pval)
-		printf("gpio%i ", pval);
-	pval = (flags & BFLAG_53X_PPORT_MASK) >> BFLAG_53X_PPORT_SHIFT;
-	if (pval)
-		printf("port%c ", 'e' + pval);
-
-	if (flags & BFLAG_53X_ZEROFILL)
-		count = 0;
-	if (flags & BFLAG_53X_FINAL)
-		count = 0;
-	else
-		count += sizeof(addr) + sizeof(count) + sizeof(flags);
-
-#else
-
-	const uint8_t *raw8 = base_addr;
-	uint32_t bcode, addr, arg, sign, chk;
-	int i;
-	static const struct ldr_flag ldr_flags[] = {
-		{ BFLAG_SAFE,        "safe"      },
-		{ BFLAG_AUX,         "aux"       },
-		{ BFLAG_FILL,        "fill"      },
-		{ BFLAG_QUICKBOOT,   "quickboot" },
-		{ BFLAG_CALLBACK,    "callback"  },
-		{ BFLAG_INIT,        "init"      },
-		{ BFLAG_IGNORE,      "ignore"    },
-		{ BFLAG_INDIRECT,    "indirect"  },
-		{ BFLAG_FIRST,       "first"     },
-		{ BFLAG_FINAL,       "final"     },
-	};
-
-	memcpy(&bcode, base_addr, sizeof(bcode));
-	memcpy(&addr, base_addr+4, sizeof(addr));
-	memcpy(&count, base_addr+8, sizeof(count));
-	memcpy(&arg, base_addr+12, sizeof(arg));
-
-	printf("%08X %08X %08X %08X ( ", bcode, addr, count, arg);
-
-	if (addr % 4)
-		printf("!!addralgn!! ");
-	if (count % 4)
-		printf("!!cntalgn!! ");
-
-	sign = (bcode & BFLAG_HDRSIGN_MASK) >> BFLAG_HDRSIGN_SHIFT;
-	if (sign != BFLAG_HDRSIGN_MAGIC)
-		printf("!!hdrsign!! ");
-
-	chk = 0;
-	for (i = 0; i < 16; ++i)
-		chk ^= raw8[i];
-	if (chk)
-		printf("!!hdrchk!! ");
-
-	printf("dma:%i ", bcode & BFLAG_DMACODE_MASK);
-
-	for (i = 0; i < ARRAY_SIZE(ldr_flags); ++i)
-		if (bcode & ldr_flags[i].flag)
-			printf("%s ", ldr_flags[i].desc);
-
-	if (bcode & BFLAG_FILL)
-		count = 0;
-	if (bcode & BFLAG_FINAL)
-		count = 0;
-	else
-		count += sizeof(bcode) + sizeof(addr) + sizeof(count) + sizeof(arg);
-
-#endif
-
-	printf(")\n");
-
-	return count;
-}
-
-static int do_ldrinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-	const void *addr;
-	uint32_t skip;
-
-	/* Get the address */
-	if (argc < 2)
-		addr = (void *)load_addr;
-	else
-		addr = (void *)simple_strtoul(argv[1], NULL, 16);
-
-	/* Walk the LDR */
-	addr += ldrinfo_header(addr);
-	do {
-		skip = ldrinfo_block(addr);
-		addr += skip;
-	} while (skip);
-
-	return 0;
-}
-
-U_BOOT_CMD(
-	ldrinfo, 2, 0, do_ldrinfo,
-	"validate ldr image in memory",
-	"[addr]\n"
-);
diff --git a/cmd/led.c b/cmd/led.c
index 951a5e2..84173f8 100644
--- a/cmd/led.c
+++ b/cmd/led.c
@@ -1,187 +1,145 @@
 /*
- * (C) Copyright 2010
- * Jason Kridner <jkridner@beagleboard.org>
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
  *
- * Based on cmd_led.c patch from:
- * http://www.mail-archive.com/u-boot@lists.denx.de/msg06873.html
- * (C) Copyright 2008
- * Ulf Samuelsson <ulf.samuelsson@atmel.com>
- *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:     GPL-2.0+
  */
 
 #include <common.h>
-#include <config.h>
 #include <command.h>
-#include <status_led.h>
+#include <dm.h>
+#include <led.h>
+#include <dm/uclass-internal.h>
 
-struct led_tbl_s {
-	char		*string;	/* String for use in the command */
-	led_id_t	mask;		/* Mask used for calling __led_set() */
-	void		(*off)(void);	/* Optional function for turning LED off */
-	void		(*on)(void);	/* Optional function for turning LED on */
-	void		(*toggle)(void);/* Optional function for toggling LED */
+#define LED_TOGGLE LEDST_COUNT
+
+static const char *const state_label[] = {
+	[LEDST_OFF]	= "off",
+	[LEDST_ON]	= "on",
+	[LEDST_TOGGLE]	= "toggle",
+#ifdef CONFIG_LED_BLINK
+	[LEDST_BLINK]	= "blink",
+#endif
 };
 
-typedef struct led_tbl_s led_tbl_t;
-
-static const led_tbl_t led_commands[] = {
-#ifdef CONFIG_LED_STATUS_BOARD_SPECIFIC
-#ifdef CONFIG_LED_STATUS0
-	{ "0", CONFIG_LED_STATUS_BIT, NULL, NULL, NULL },
-#endif
-#ifdef CONFIG_LED_STATUS1
-	{ "1", CONFIG_LED_STATUS_BIT1, NULL, NULL, NULL },
-#endif
-#ifdef CONFIG_LED_STATUS2
-	{ "2", CONFIG_LED_STATUS_BIT2, NULL, NULL, NULL },
-#endif
-#ifdef CONFIG_LED_STATUS3
-	{ "3", CONFIG_LED_STATUS_BIT3, NULL, NULL, NULL },
-#endif
-#ifdef CONFIG_LED_STATUS4
-	{ "4", CONFIG_LED_STATUS_BIT4, NULL, NULL, NULL },
-#endif
-#ifdef CONFIG_LED_STATUS5
-	{ "5", CONFIG_LED_STATUS_BIT5, NULL, NULL, NULL },
-#endif
-#endif
-#ifdef CONFIG_LED_STATUS_GREEN
-	{ "green", CONFIG_LED_STATUS_GREEN, green_led_off, green_led_on, NULL },
-#endif
-#ifdef CONFIG_LED_STATUS_YELLOW
-	{ "yellow", CONFIG_LED_STATUS_YELLOW, yellow_led_off, yellow_led_on,
-	  NULL },
-#endif
-#ifdef CONFIG_LED_STATUS_RED
-	{ "red", CONFIG_LED_STATUS_RED, red_led_off, red_led_on, NULL },
-#endif
-#ifdef CONFIG_LED_STATUS_BLUE
-	{ "blue", CONFIG_LED_STATUS_BLUE, blue_led_off, blue_led_on, NULL },
-#endif
-	{ NULL, 0, NULL, NULL, NULL }
-};
-
-enum led_cmd { LED_ON, LED_OFF, LED_TOGGLE, LED_BLINK };
-
-enum led_cmd get_led_cmd(char *var)
+enum led_state_t get_led_cmd(char *var)
 {
-	if (strcmp(var, "off") == 0)
-		return LED_OFF;
-	if (strcmp(var, "on") == 0)
-		return LED_ON;
-	if (strcmp(var, "toggle") == 0)
-		return LED_TOGGLE;
-	if (strcmp(var, "blink") == 0)
-		return LED_BLINK;
+	int i;
+
+	for (i = 0; i < LEDST_COUNT; i++) {
+		if (!strncmp(var, state_label[i], strlen(var)))
+			return i;
+	}
 
 	return -1;
 }
 
-/*
- * LED drivers providing a blinking LED functionality, like the
- * PCA9551, can override this empty weak function
- */
-void __weak __led_blink(led_id_t mask, int freq)
+static int show_led_state(struct udevice *dev)
 {
+	int ret;
+
+	ret = led_get_state(dev);
+	if (ret >= LEDST_COUNT)
+		ret = -EINVAL;
+	if (ret >= 0)
+		printf("%s\n", state_label[ret]);
+
+	return ret;
 }
 
-int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int list_leds(void)
 {
-	int i, match = 0;
-	enum led_cmd cmd;
-	int freq;
+	struct udevice *dev;
+	int ret;
 
-	/* Validate arguments */
-	if ((argc < 3) || (argc > 4))
-		return CMD_RET_USAGE;
+	for (uclass_find_first_device(UCLASS_LED, &dev);
+	     dev;
+	     uclass_find_next_device(&dev)) {
+		struct led_uc_plat *plat = dev_get_uclass_platdata(dev);
 
-	cmd = get_led_cmd(argv[2]);
-	if (cmd < 0) {
-		return CMD_RET_USAGE;
-	}
-
-	for (i = 0; led_commands[i].string; i++) {
-		if ((strcmp("all", argv[1]) == 0) ||
-		    (strcmp(led_commands[i].string, argv[1]) == 0)) {
-			match = 1;
-			switch (cmd) {
-			case LED_ON:
-				if (led_commands[i].on)
-					led_commands[i].on();
-				else
-					__led_set(led_commands[i].mask,
-							  CONFIG_LED_STATUS_ON);
-				break;
-			case LED_OFF:
-				if (led_commands[i].off)
-					led_commands[i].off();
-				else
-					__led_set(led_commands[i].mask,
-						  CONFIG_LED_STATUS_OFF);
-				break;
-			case LED_TOGGLE:
-				if (led_commands[i].toggle)
-					led_commands[i].toggle();
-				else
-					__led_toggle(led_commands[i].mask);
-				break;
-			case LED_BLINK:
-				if (argc != 4)
-					return CMD_RET_USAGE;
-
-				freq = simple_strtoul(argv[3], NULL, 10);
-				__led_blink(led_commands[i].mask, freq);
-			}
-			/* Need to set only 1 led if led_name wasn't 'all' */
-			if (strcmp("all", argv[1]) != 0)
-				break;
+		if (!plat->label)
+			continue;
+		printf("%-15s ", plat->label);
+		if (device_active(dev)) {
+			ret = show_led_state(dev);
+			if (ret < 0)
+				printf("Error %d\n", ret);
+		} else {
+			printf("<inactive>\n");
 		}
 	}
 
-	/* If we ran out of matches, print Usage */
-	if (!match) {
-		return CMD_RET_USAGE;
-	}
-
 	return 0;
 }
 
+int do_led(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	enum led_state_t cmd;
+	const char *led_label;
+	struct udevice *dev;
+#ifdef CONFIG_LED_BLINK
+	int freq_ms = 0;
+#endif
+	int ret;
+
+	/* Validate arguments */
+	if (argc < 2)
+		return CMD_RET_USAGE;
+	led_label = argv[1];
+	if (*led_label == 'l')
+		return list_leds();
+
+	cmd = argc > 2 ? get_led_cmd(argv[2]) : LEDST_COUNT;
+	if (cmd < 0)
+		return CMD_RET_USAGE;
+#ifdef CONFIG_LED_BLINK
+	if (cmd == LEDST_BLINK) {
+		if (argc < 4)
+			return CMD_RET_USAGE;
+		freq_ms = simple_strtoul(argv[3], NULL, 10);
+	}
+#endif
+	ret = led_get_by_label(led_label, &dev);
+	if (ret) {
+		printf("LED '%s' not found (err=%d)\n", led_label, ret);
+		return CMD_RET_FAILURE;
+	}
+	switch (cmd) {
+	case LEDST_OFF:
+	case LEDST_ON:
+	case LEDST_TOGGLE:
+		ret = led_set_state(dev, cmd);
+		break;
+#ifdef CONFIG_LED_BLINK
+	case LEDST_BLINK:
+		ret = led_set_period(dev, freq_ms);
+		if (!ret)
+			ret = led_set_state(dev, LEDST_BLINK);
+		break;
+#endif
+	case LEDST_COUNT:
+		printf("LED '%s': ", led_label);
+		ret = show_led_state(dev);
+		break;
+	}
+	if (ret < 0) {
+		printf("LED '%s' operation failed (err=%d)\n", led_label, ret);
+		return CMD_RET_FAILURE;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_LED_BLINK
+#define BLINK "|blink [blink-freq in ms]"
+#else
+#define BLINK ""
+#endif
+
 U_BOOT_CMD(
 	led, 4, 1, do_led,
-	"["
-#ifdef CONFIG_LED_STATUS_BOARD_SPECIFIC
-#ifdef CONFIG_LED_STATUS0
-	"0|"
-#endif
-#ifdef CONFIG_LED_STATUS1
-	"1|"
-#endif
-#ifdef CONFIG_LED_STATUS2
-	"2|"
-#endif
-#ifdef CONFIG_LED_STATUS3
-	"3|"
-#endif
-#ifdef CONFIG_LED_STATUS4
-	"4|"
-#endif
-#ifdef CONFIG_LED_STATUS5
-	"5|"
-#endif
-#endif
-#ifdef CONFIG_LED_STATUS_GREEN
-	"green|"
-#endif
-#ifdef CONFIG_LED_STATUS_YELLOW
-	"yellow|"
-#endif
-#ifdef CONFIG_LED_STATUS_RED
-	"red|"
-#endif
-#ifdef CONFIG_LED_STATUS_BLUE
-	"blue|"
-#endif
-	"all] [on|off|toggle|blink] [blink-freq in ms]",
-	"[led_name] [on|off|toggle|blink] sets or clears led(s)"
+	"manage LEDs",
+	"<led_label> on|off|toggle" BLINK "\tChange LED state\n"
+	"led [<led_label>\tGet LED state\n"
+	"led list\t\tshow a list of LEDs"
 );
diff --git a/cmd/legacy_led.c b/cmd/legacy_led.c
new file mode 100644
index 0000000..1ec2e43
--- /dev/null
+++ b/cmd/legacy_led.c
@@ -0,0 +1,187 @@
+/*
+ * (C) Copyright 2010
+ * Jason Kridner <jkridner@beagleboard.org>
+ *
+ * Based on cmd_led.c patch from:
+ * http://www.mail-archive.com/u-boot@lists.denx.de/msg06873.html
+ * (C) Copyright 2008
+ * Ulf Samuelsson <ulf.samuelsson@atmel.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <config.h>
+#include <command.h>
+#include <status_led.h>
+
+struct led_tbl_s {
+	char		*string;	/* String for use in the command */
+	led_id_t	mask;		/* Mask used for calling __led_set() */
+	void		(*off)(void);	/* Optional function for turning LED off */
+	void		(*on)(void);	/* Optional function for turning LED on */
+	void		(*toggle)(void);/* Optional function for toggling LED */
+};
+
+typedef struct led_tbl_s led_tbl_t;
+
+static const led_tbl_t led_commands[] = {
+#ifdef CONFIG_LED_STATUS_BOARD_SPECIFIC
+#ifdef CONFIG_LED_STATUS0
+	{ "0", CONFIG_LED_STATUS_BIT, NULL, NULL, NULL },
+#endif
+#ifdef CONFIG_LED_STATUS1
+	{ "1", CONFIG_LED_STATUS_BIT1, NULL, NULL, NULL },
+#endif
+#ifdef CONFIG_LED_STATUS2
+	{ "2", CONFIG_LED_STATUS_BIT2, NULL, NULL, NULL },
+#endif
+#ifdef CONFIG_LED_STATUS3
+	{ "3", CONFIG_LED_STATUS_BIT3, NULL, NULL, NULL },
+#endif
+#ifdef CONFIG_LED_STATUS4
+	{ "4", CONFIG_LED_STATUS_BIT4, NULL, NULL, NULL },
+#endif
+#ifdef CONFIG_LED_STATUS5
+	{ "5", CONFIG_LED_STATUS_BIT5, NULL, NULL, NULL },
+#endif
+#endif
+#ifdef CONFIG_LED_STATUS_GREEN
+	{ "green", CONFIG_LED_STATUS_GREEN, green_led_off, green_led_on, NULL },
+#endif
+#ifdef CONFIG_LED_STATUS_YELLOW
+	{ "yellow", CONFIG_LED_STATUS_YELLOW, yellow_led_off, yellow_led_on,
+	  NULL },
+#endif
+#ifdef CONFIG_LED_STATUS_RED
+	{ "red", CONFIG_LED_STATUS_RED, red_led_off, red_led_on, NULL },
+#endif
+#ifdef CONFIG_LED_STATUS_BLUE
+	{ "blue", CONFIG_LED_STATUS_BLUE, blue_led_off, blue_led_on, NULL },
+#endif
+	{ NULL, 0, NULL, NULL, NULL }
+};
+
+enum led_cmd { LED_ON, LED_OFF, LED_TOGGLE, LED_BLINK };
+
+enum led_cmd get_led_cmd(char *var)
+{
+	if (strcmp(var, "off") == 0)
+		return LED_OFF;
+	if (strcmp(var, "on") == 0)
+		return LED_ON;
+	if (strcmp(var, "toggle") == 0)
+		return LED_TOGGLE;
+	if (strcmp(var, "blink") == 0)
+		return LED_BLINK;
+
+	return -1;
+}
+
+/*
+ * LED drivers providing a blinking LED functionality, like the
+ * PCA9551, can override this empty weak function
+ */
+void __weak __led_blink(led_id_t mask, int freq)
+{
+}
+
+int do_legacy_led(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int i, match = 0;
+	enum led_cmd cmd;
+	int freq;
+
+	/* Validate arguments */
+	if ((argc < 3) || (argc > 4))
+		return CMD_RET_USAGE;
+
+	cmd = get_led_cmd(argv[2]);
+	if (cmd < 0) {
+		return CMD_RET_USAGE;
+	}
+
+	for (i = 0; led_commands[i].string; i++) {
+		if ((strcmp("all", argv[1]) == 0) ||
+		    (strcmp(led_commands[i].string, argv[1]) == 0)) {
+			match = 1;
+			switch (cmd) {
+			case LED_ON:
+				if (led_commands[i].on)
+					led_commands[i].on();
+				else
+					__led_set(led_commands[i].mask,
+							  CONFIG_LED_STATUS_ON);
+				break;
+			case LED_OFF:
+				if (led_commands[i].off)
+					led_commands[i].off();
+				else
+					__led_set(led_commands[i].mask,
+						  CONFIG_LED_STATUS_OFF);
+				break;
+			case LED_TOGGLE:
+				if (led_commands[i].toggle)
+					led_commands[i].toggle();
+				else
+					__led_toggle(led_commands[i].mask);
+				break;
+			case LED_BLINK:
+				if (argc != 4)
+					return CMD_RET_USAGE;
+
+				freq = simple_strtoul(argv[3], NULL, 10);
+				__led_blink(led_commands[i].mask, freq);
+			}
+			/* Need to set only 1 led if led_name wasn't 'all' */
+			if (strcmp("all", argv[1]) != 0)
+				break;
+		}
+	}
+
+	/* If we ran out of matches, print Usage */
+	if (!match) {
+		return CMD_RET_USAGE;
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	led, 4, 1, do_legacy_led,
+	"["
+#ifdef CONFIG_LED_STATUS_BOARD_SPECIFIC
+#ifdef CONFIG_LED_STATUS0
+	"0|"
+#endif
+#ifdef CONFIG_LED_STATUS1
+	"1|"
+#endif
+#ifdef CONFIG_LED_STATUS2
+	"2|"
+#endif
+#ifdef CONFIG_LED_STATUS3
+	"3|"
+#endif
+#ifdef CONFIG_LED_STATUS4
+	"4|"
+#endif
+#ifdef CONFIG_LED_STATUS5
+	"5|"
+#endif
+#endif
+#ifdef CONFIG_LED_STATUS_GREEN
+	"green|"
+#endif
+#ifdef CONFIG_LED_STATUS_YELLOW
+	"yellow|"
+#endif
+#ifdef CONFIG_LED_STATUS_RED
+	"red|"
+#endif
+#ifdef CONFIG_LED_STATUS_BLUE
+	"blue|"
+#endif
+	"all] [on|off|toggle|blink] [blink-freq in ms]",
+	"[led_name] [on|off|toggle|blink] sets or clears led(s)"
+);
diff --git a/cmd/otp.c b/cmd/otp.c
deleted file mode 100644
index 10c1475..0000000
--- a/cmd/otp.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * cmd_otp.c - interface to Blackfin on-chip One-Time-Programmable memory
- *
- * Copyright (c) 2007-2008 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-/* There are 512 128-bit "pages" (0x000 through 0x1FF).
- * The pages are accessable as 64-bit "halfpages" (an upper and lower half).
- * The pages are not part of the memory map.  There is an OTP controller which
- * handles scanning in/out of bits.  While access is done through OTP MMRs,
- * the bootrom provides C-callable helper functions to handle the interaction.
- */
-
-#include <config.h>
-#include <common.h>
-#include <command.h>
-#include <console.h>
-
-#include <asm/blackfin.h>
-#include <asm/clock.h>
-#include <asm/mach-common/bits/otp.h>
-
-static const char *otp_strerror(uint32_t err)
-{
-	switch (err) {
-	case 0:                   return "no error";
-	case OTP_WRITE_ERROR:     return "OTP fuse write error";
-	case OTP_READ_ERROR:      return "OTP fuse read error";
-	case OTP_ACC_VIO_ERROR:   return "invalid OTP address";
-	case OTP_DATA_MULT_ERROR: return "multiple bad bits detected";
-	case OTP_ECC_MULT_ERROR:  return "error in ECC bits";
-	case OTP_PREV_WR_ERROR:   return "space already written";
-	case OTP_DATA_SB_WARN:    return "single bad bit in half page";
-	case OTP_ECC_SB_WARN:     return "single bad bit in ECC";
-	default:                  return "unknown error";
-	}
-}
-
-#define lowup(x) ((x) % 2 ? "upper" : "lower")
-
-static int check_voltage(void)
-{
-	/* Make sure voltage limits are within datasheet spec */
-	uint16_t vr_ctl = bfin_read_VR_CTL();
-
-#ifdef __ADSPBF54x__
-	/* 0.9V <= VDDINT <= 1.1V */
-	if ((vr_ctl & 0xc) && (vr_ctl & 0xc0) == 0xc0)
-		return 1;
-#else
-	/* for the parts w/out qualification yet */
-	(void)vr_ctl;
-#endif
-
-	return 0;
-}
-
-static void set_otp_timing(bool write)
-{
-	static uint32_t timing;
-	if (!timing) {
-		uint32_t tp1, tp2, tp3;
-		/* OTP_TP1 = 1000 / sclk_period (in nanoseconds)
-		 * OTP_TP1 = 1000 / (1 / get_sclk() * 10^9)
-		 * OTP_TP1 = (1000 * get_sclk()) / 10^9
-		 * OTP_TP1 = get_sclk() / 10^6
-		 */
-		tp1 = get_sclk() / 1000000;
-		/* OTP_TP2 = 400 / (2 * sclk_period)
-		 * OTP_TP2 = 400 / (2 * 1 / get_sclk() * 10^9)
-		 * OTP_TP2 = (400 * get_sclk()) / (2 * 10^9)
-		 * OTP_TP2 = (2 * get_sclk()) / 10^7
-		 */
-		tp2 = (2 * get_sclk() / 10000000) << 8;
-		/* OTP_TP3 = magic constant */
-		tp3 = (0x1401) << 15;
-		timing = tp1 | tp2 | tp3;
-	}
-
-	bfrom_OtpCommand(OTP_INIT, write ? timing : timing & ~(-1 << 15));
-}
-
-int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-	char *cmd;
-	uint32_t ret, base_flags;
-	bool prompt_user, force_read;
-	uint32_t (*otp_func)(uint32_t page, uint32_t flags, uint64_t *page_content);
-
-	if (argc < 4) {
- usage:
-		return CMD_RET_USAGE;
-	}
-
-	prompt_user = false;
-	base_flags = 0;
-	cmd = argv[1];
-	if (!strcmp(cmd, "read"))
-		otp_func = bfrom_OtpRead;
-	else if (!strcmp(cmd, "dump")) {
-		otp_func = bfrom_OtpRead;
-		force_read = true;
-	} else if (!strcmp(cmd, "write")) {
-		otp_func = bfrom_OtpWrite;
-		base_flags = OTP_CHECK_FOR_PREV_WRITE;
-		if (!strcmp(argv[2], "--force")) {
-			argv++;
-			--argc;
-		} else
-			prompt_user = false;
-	} else if (!strcmp(cmd, "lock")) {
-		if (argc != 4)
-			goto usage;
-		otp_func = bfrom_OtpWrite;
-		base_flags = OTP_LOCK;
-	} else
-		goto usage;
-
-	uint64_t *addr = (uint64_t *)simple_strtoul(argv[2], NULL, 16);
-	uint32_t page = simple_strtoul(argv[3], NULL, 16);
-	uint32_t flags;
-	size_t i, count;
-	ulong half;
-
-	if (argc > 4)
-		count = simple_strtoul(argv[4], NULL, 16);
-	else
-		count = 2;
-
-	if (argc > 5) {
-		half = simple_strtoul(argv[5], NULL, 16);
-		if (half != 0 && half != 1) {
-			puts("Error: 'half' can only be '0' or '1'\n");
-			goto usage;
-		}
-	} else
-		half = 0;
-
-	/* "otp lock" has slightly different semantics */
-	if (base_flags & OTP_LOCK) {
-		count = page;
-		page = (uint32_t)addr;
-		addr = NULL;
-	}
-
-	/* do to the nature of OTP, make sure users are sure */
-	if (prompt_user) {
-		printf(
-			"Writing one time programmable memory\n"
-			"Make sure your operating voltages and temperature are within spec\n"
-			"   source address:  0x%p\n"
-			"   OTP destination: %s page 0x%03X - %s page 0x%03lX\n"
-			"   number to write: %lu halfpages\n"
-			" type \"YES\" (no quotes) to confirm: ",
-			addr,
-			lowup(half), page,
-			lowup(half + count - 1), page + (half + count - 1) / 2,
-			half + count
-		);
-		if (!confirm_yesno()) {
-			printf(" Aborting\n");
-			return 1;
-		}
-	}
-
-	printf("OTP memory %s: addr 0x%p  page 0x%03X  count %zu ... ",
-		cmd, addr, page, count);
-
-	set_otp_timing(otp_func == bfrom_OtpWrite);
-	if (otp_func == bfrom_OtpWrite && check_voltage()) {
-		puts("ERROR: VDDINT voltage is out of spec for writing\n");
-		return -1;
-	}
-
-	/* Do the actual reading/writing stuff */
-	ret = 0;
-	for (i = half; i < count + half; ++i) {
-		flags = base_flags | (i % 2 ? OTP_UPPER_HALF : OTP_LOWER_HALF);
- try_again:
-		ret = otp_func(page, flags, addr);
-		if (ret & OTP_MASTER_ERROR) {
-			if (force_read) {
-				if (flags & OTP_NO_ECC)
-					break;
-				else
-					flags |= OTP_NO_ECC;
-				puts("E");
-				goto try_again;
-			} else
-				break;
-		} else if (ret)
-			puts("W");
-		else
-			puts(".");
-		if (!(base_flags & OTP_LOCK)) {
-			++addr;
-			if (i % 2)
-				++page;
-		} else
-			++page;
-	}
-	if (ret & 0x1)
-		printf("\nERROR at page 0x%03X (%s-halfpage): 0x%03X: %s\n",
-			page, lowup(i), ret, otp_strerror(ret));
-	else
-		puts(" done\n");
-
-	/* Make sure we disable writing */
-	set_otp_timing(false);
-	bfrom_OtpCommand(OTP_CLOSE, 0);
-
-	return ret;
-}
-
-U_BOOT_CMD(
-	otp, 7, 0, do_otp,
-	"One-Time-Programmable sub-system",
-	"read <addr> <page> [count] [half]\n"
-	" - read 'count' half-pages starting at 'page' (offset 'half') to 'addr'\n"
-	"otp dump <addr> <page> [count] [half]\n"
-	" - like 'otp read', but skip read errors\n"
-	"otp write [--force] <addr> <page> [count] [half]\n"
-	" - write 'count' half-pages starting at 'page' (offset 'half') from 'addr'\n"
-	"otp lock <page> <count>\n"
-	" - lock 'count' pages starting at 'page'"
-);
diff --git a/cmd/softswitch.c b/cmd/softswitch.c
deleted file mode 100644
index f75d926..0000000
--- a/cmd/softswitch.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * cmd_softswitch.c - set the softswitch for bf60x
- *
- * Copyright (c) 2012 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <command.h>
-#include <asm/blackfin.h>
-#include <asm/soft_switch.h>
-
-int do_softswitch(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-	int switchaddr, value, pin, port;
-
-	if (argc != 5)
-		return CMD_RET_USAGE;
-
-	if (strcmp(argv[2], "GPA") == 0)
-		port = IO_PORT_A;
-	else if (strcmp(argv[2], "GPB") == 0)
-		port = IO_PORT_B;
-	else
-		return CMD_RET_USAGE;
-
-	switchaddr = simple_strtoul(argv[1], NULL, 16);
-	pin = simple_strtoul(argv[3], NULL, 16);
-	value = simple_strtoul(argv[4], NULL, 16);
-
-	config_switch_bit(switchaddr, port, (1 << pin), IO_PORT_OUTPUT, value);
-
-	return 0;
-}
-
-U_BOOT_CMD(
-	softswitch_output, 5, 1, do_softswitch,
-	"switchaddr GPA/GPB pin_offset value",
-	""
-);
diff --git a/cmd/spibootldr.c b/cmd/spibootldr.c
deleted file mode 100644
index acbb0f6..0000000
--- a/cmd/spibootldr.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * U-Boot - spibootldr.c
- *
- * Copyright (c) 2005-2008 Analog Devices Inc.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <command.h>
-
-#include <asm/blackfin.h>
-#include <asm/mach-common/bits/bootrom.h>
-
-int do_spibootldr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-	s32 addr;
-
-	/* Get the address */
-	if (argc < 2)
-		addr = 0;
-	else
-		addr = simple_strtoul(argv[1], NULL, 16);
-
-	printf("## Booting ldr image at SPI offset 0x%x ...\n", addr);
-
-	return bfrom_SpiBoot(addr, BFLAG_PERIPHERAL | 4, 0, NULL);
-}
-
-U_BOOT_CMD(
-	spibootldr, 2, 0, do_spibootldr,
-	"boot ldr image from spi",
-	"[offset]\n"
-	"    - boot ldr image stored at offset into spi\n");
diff --git a/cmd/ubi.c b/cmd/ubi.c
index efc43ff..222be5a 100644
--- a/cmd/ubi.c
+++ b/cmd/ubi.c
@@ -308,7 +308,7 @@
 		return ENODEV;
 
 	rsvd_bytes = vol->reserved_pebs * (ubi->leb_size - vol->data_pad);
-	if (size < 0 || size > rsvd_bytes) {
+	if (size > rsvd_bytes) {
 		printf("size > volume size! Aborting!\n");
 		return EINVAL;
 	}
diff --git a/common/scsi.c b/common/scsi.c
index fb5b407..d37222c 100644
--- a/common/scsi.c
+++ b/common/scsi.c
@@ -473,14 +473,15 @@
  * scsi_detect_dev - Detect scsi device
  *
  * @target: target id
+ * @lun: target lun
  * @dev_desc: block device description
  *
  * The scsi_detect_dev detects and fills a dev_desc structure when the device is
- * detected. The LUN number is taken from the struct blk_desc *dev_desc.
+ * detected.
  *
  * Return: 0 on success, error value otherwise
  */
-static int scsi_detect_dev(int target, struct blk_desc *dev_desc)
+static int scsi_detect_dev(int target, int lun, struct blk_desc *dev_desc)
 {
 	unsigned char perq, modi;
 	lbaint_t capacity;
@@ -488,7 +489,7 @@
 	ccb *pccb = (ccb *)&tempccb;
 
 	pccb->target = target;
-	pccb->lun = dev_desc->lun;
+	pccb->lun = lun;
 	pccb->pdata = (unsigned char *)&tempbuff;
 	pccb->datalen = 512;
 	scsi_setup_inquiry(pccb);
@@ -539,7 +540,6 @@
 	dev_desc->blksz = blksz;
 	dev_desc->log2blksz = LOG2(dev_desc->blksz);
 	dev_desc->type = perq;
-	part_init(&dev_desc[0]);
 removable:
 	return 0;
 }
@@ -580,9 +580,19 @@
 			for (lun = 0; lun < plat->max_lun; lun++) {
 				struct udevice *bdev; /* block device */
 				/* block device description */
+				struct blk_desc _bd;
 				struct blk_desc *bdesc;
 				char str[10];
 
+				scsi_init_dev_desc_priv(&_bd);
+				ret = scsi_detect_dev(i, lun, &_bd);
+				if (ret)
+					/*
+					 * no device detected?
+					 * check the next lun.
+					 */
+					continue;
+
 				/*
 				 * Create only one block device and do detection
 				 * to make sure that there won't be a lot of
@@ -590,21 +600,28 @@
 				 */
 				snprintf(str, sizeof(str), "id%dlun%d", i, lun);
 				ret = blk_create_devicef(dev, "scsi_blk",
-							  str, IF_TYPE_SCSI,
-							  -1, 0, 0, &bdev);
+						str, IF_TYPE_SCSI,
+						-1,
+						_bd.blksz,
+						_bd.blksz * _bd.lba,
+						&bdev);
 				if (ret) {
 					debug("Can't create device\n");
 					return ret;
 				}
-				bdesc = dev_get_uclass_platdata(bdev);
 
-				scsi_init_dev_desc_priv(bdesc);
+				bdesc = dev_get_uclass_platdata(bdev);
+				bdesc->target = i;
 				bdesc->lun = lun;
-				ret = scsi_detect_dev(i, bdesc);
-				if (ret) {
-					device_unbind(bdev);
-					continue;
-				}
+				bdesc->removable = _bd.removable;
+				bdesc->type = _bd.type;
+				memcpy(&bdesc->vendor, &_bd.vendor,
+				       sizeof(_bd.vendor));
+				memcpy(&bdesc->product, &_bd.product,
+				       sizeof(_bd.product));
+				memcpy(&bdesc->revision, &_bd.revision,
+				       sizeof(_bd.revision));
+				part_init(bdesc);
 
 				if (mode == 1) {
 					printf("  Device %d: ", 0);
@@ -630,10 +647,11 @@
 	scsi_max_devs = 0;
 	for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
 		for (lun = 0; lun < CONFIG_SYS_SCSI_MAX_LUN; lun++) {
-			scsi_dev_desc[scsi_max_devs].lun = lun;
-			ret = scsi_detect_dev(i, &scsi_dev_desc[scsi_max_devs]);
+			ret = scsi_detect_dev(i, lun,
+					      &scsi_dev_desc[scsi_max_devs]);
 			if (ret)
 				continue;
+			part_init(&scsi_dev_desc[scsi_max_devs]);
 
 			if (mode == 1) {
 				printf("  Device %d: ", 0);
diff --git a/configs/chromebook_link64_defconfig b/configs/chromebook_link64_defconfig
index 3ab34cd..749cfd4 100644
--- a/configs/chromebook_link64_defconfig
+++ b/configs/chromebook_link64_defconfig
@@ -86,4 +86,5 @@
 CONFIG_VIDEO_IVYBRIDGE_IGD=y
 CONFIG_CONSOLE_SCROLL_LINES=5
 CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_CMD_DHRYSTONE=y
 CONFIG_TPM=y
diff --git a/configs/chromebook_link_defconfig b/configs/chromebook_link_defconfig
index 85b7d5f..5ebb556 100644
--- a/configs/chromebook_link_defconfig
+++ b/configs/chromebook_link_defconfig
@@ -69,4 +69,5 @@
 CONFIG_VIDEO_IVYBRIDGE_IGD=y
 CONFIG_CONSOLE_SCROLL_LINES=5
 CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_CMD_DHRYSTONE=y
 CONFIG_TPM=y
diff --git a/configs/evb-rk3399_defconfig b/configs/evb-rk3399_defconfig
index 50b0d74..cef8506 100644
--- a/configs/evb-rk3399_defconfig
+++ b/configs/evb-rk3399_defconfig
@@ -60,3 +60,9 @@
 CONFIG_USB_STORAGE=y
 CONFIG_USE_TINY_PRINTF=y
 CONFIG_ERRNO_STR=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_CHILDREN=y
+CONFIG_SPL_PMIC_CHILDREN=y
+CONFIG_PMIC_RK808=y
+CONFIG_REGULATOR_RK808=y
diff --git a/configs/puma-rk3399_defconfig b/configs/puma-rk3399_defconfig
index d4e12d7..500f220 100644
--- a/configs/puma-rk3399_defconfig
+++ b/configs/puma-rk3399_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
+CONFIG_TARGET_PUMA_RK3399=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_SYS_MALLOC_F_LEN=0x4000
@@ -11,7 +12,7 @@
 CONFIG_FIT=y
 CONFIG_SPL_FIT=y
 CONFIG_SPL_LOAD_FIT=y
-CONFIG_SPL_FIT_SOURCE="board/rockchip/evb_rk3399/fit_spl_atf.its"
+CONFIG_SPL_FIT_SOURCE="board/theobroma-systems/puma_rk3399/fit_spl_atf.its"
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
 # CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set
diff --git a/configs/sama5d3_xplained_mmc_defconfig b/configs/sama5d3_xplained_mmc_defconfig
index 2654aa1..d28d1d9 100644
--- a/configs/sama5d3_xplained_mmc_defconfig
+++ b/configs/sama5d3_xplained_mmc_defconfig
@@ -4,15 +4,19 @@
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
 CONFIG_SPL_LIBDISK_SUPPORT=y
 CONFIG_SPL_FAT_SUPPORT=y
+CONFIG_DEFAULT_DEVICE_TREE="at91-sama5d3_xplained"
 CONFIG_FIT=y
 CONFIG_SYS_EXTRA_OPTIONS="SAMA5D3,SYS_USE_MMC"
 CONFIG_BOOTDELAY=3
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL=y
+CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMI is not set
@@ -29,6 +33,35 @@
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_UBI=y
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_SPL_REMOVE_PROPS="interrupts interrupt-parent dmas dma-names"
+CONFIG_DM=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_CLK_AT91=y
+CONFIG_AT91_UTMI=y
+CONFIG_AT91_H32MX=y
+CONFIG_DM_GPIO=y
+CONFIG_AT91_GPIO=y
+CONFIG_DM_MMC=y
+CONFIG_GENERIC_ATMEL_MCI=y
+CONFIG_DM_ETH=y
+CONFIG_MACB=y
+CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_PINCTRL_AT91=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ATMEL=y
+CONFIG_DEBUG_UART_BASE=0xffffee00
+CONFIG_DEBUG_UART_CLOCK=132000000
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_ATMEL_USART=y
 CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/sama5d3_xplained_nandflash_defconfig b/configs/sama5d3_xplained_nandflash_defconfig
index dc487d9..8cc8169 100644
--- a/configs/sama5d3_xplained_nandflash_defconfig
+++ b/configs/sama5d3_xplained_nandflash_defconfig
@@ -6,6 +6,9 @@
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_NAND_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_DEFAULT_DEVICE_TREE="at91-sama5d3_xplained"
 CONFIG_FIT=y
 CONFIG_SYS_EXTRA_OPTIONS="SAMA5D3,SYS_USE_NANDFLASH"
 CONFIG_BOOTDELAY=3
@@ -27,6 +30,35 @@
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_UBI=y
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_SPL_REMOVE_PROPS="interrupts interrupt-parent dmas dma-names"
+CONFIG_DM=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_CLK_AT91=y
+CONFIG_AT91_UTMI=y
+CONFIG_AT91_H32MX=y
+CONFIG_DM_GPIO=y
+CONFIG_AT91_GPIO=y
+CONFIG_DM_MMC=y
+CONFIG_GENERIC_ATMEL_MCI=y
+CONFIG_DM_ETH=y
+CONFIG_MACB=y
+CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_PINCTRL_AT91=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ATMEL=y
+CONFIG_DEBUG_UART_BASE=0xffffee00
+CONFIG_DEBUG_UART_CLOCK=132000000
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_ATMEL_USART=y
 CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/sama5d3xek_mmc_defconfig b/configs/sama5d3xek_mmc_defconfig
index b73d647..994bc04 100644
--- a/configs/sama5d3xek_mmc_defconfig
+++ b/configs/sama5d3xek_mmc_defconfig
@@ -4,10 +4,13 @@
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
 CONFIG_SPL_LIBDISK_SUPPORT=y
 CONFIG_SPL_FAT_SUPPORT=y
+CONFIG_DEFAULT_DEVICE_TREE="sama5d36ek"
 CONFIG_FIT=y
 CONFIG_SYS_EXTRA_OPTIONS="SAMA5D3,SYS_USE_MMC"
 CONFIG_BOOTDELAY=3
@@ -15,6 +18,7 @@
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL=y
+CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMI is not set
@@ -26,13 +30,47 @@
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_SPL_REMOVE_PROPS="interrupts interrupt-parent dmas dma-names"
+CONFIG_DM=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_CLK_AT91=y
+CONFIG_AT91_UTMI=y
+CONFIG_AT91_H32MX=y
+CONFIG_DM_GPIO=y
+CONFIG_AT91_GPIO=y
+CONFIG_DM_MMC=y
+CONFIG_GENERIC_ATMEL_MCI=y
 CONFIG_MTD_NOR_FLASH=y
+CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_DM_ETH=y
+CONFIG_MACB=y
+CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_PINCTRL_AT91=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ATMEL=y
+CONFIG_DEBUG_UART_BASE=0xffffee00
+CONFIG_DEBUG_UART_CLOCK=132000000
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_ATMEL_USART=y
+CONFIG_DM_SPI=y
+CONFIG_ATMEL_SPI=y
 CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_ATMEL_USBA=y
 CONFIG_LCD=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/sama5d3xek_nandflash_defconfig b/configs/sama5d3xek_nandflash_defconfig
index 7f68d7d..dd0263c 100644
--- a/configs/sama5d3xek_nandflash_defconfig
+++ b/configs/sama5d3xek_nandflash_defconfig
@@ -4,8 +4,11 @@
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
 CONFIG_SPL_NAND_SUPPORT=y
+CONFIG_DEFAULT_DEVICE_TREE="sama5d36ek"
 CONFIG_FIT=y
 CONFIG_SYS_EXTRA_OPTIONS="SAMA5D3,SYS_USE_NANDFLASH"
 CONFIG_BOOTDELAY=3
@@ -25,12 +28,44 @@
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_FAT=y
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_SPL_REMOVE_PROPS="interrupts interrupt-parent dmas dma-names"
+CONFIG_DM=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_CLK_AT91=y
+CONFIG_AT91_UTMI=y
+CONFIG_AT91_H32MX=y
+CONFIG_DM_GPIO=y
+CONFIG_AT91_GPIO=y
+CONFIG_DM_MMC=y
+CONFIG_GENERIC_ATMEL_MCI=y
 CONFIG_MTD_NOR_FLASH=y
+CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_DM_ETH=y
+CONFIG_MACB=y
+CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_PINCTRL_AT91=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ATMEL=y
+CONFIG_DEBUG_UART_BASE=0xffffee00
+CONFIG_DEBUG_UART_CLOCK=132000000
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_ATMEL_USART=y
+CONFIG_DM_SPI=y
+CONFIG_ATMEL_SPI=y
 CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_ATMEL_USBA=y
 CONFIG_LCD=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/sama5d3xek_spiflash_defconfig b/configs/sama5d3xek_spiflash_defconfig
index c7a183f..069fbcc 100644
--- a/configs/sama5d3xek_spiflash_defconfig
+++ b/configs/sama5d3xek_spiflash_defconfig
@@ -4,20 +4,23 @@
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
+CONFIG_DEFAULT_DEVICE_TREE="sama5d36ek"
 CONFIG_FIT=y
 CONFIG_SYS_EXTRA_OPTIONS="SAMA5D3,SYS_USE_SERIALFLASH"
 CONFIG_BOOTDELAY=3
-# CONFIG_CONSOLE_MUX is not set
-CONFIG_SYS_CONSOLE_IS_IN_ENV=y
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL=y
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
 CONFIG_CMD_MMC=y
 CONFIG_CMD_SF=y
 CONFIG_CMD_USB=y
@@ -26,12 +29,44 @@
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_FAT=y
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_SPL_REMOVE_PROPS="interrupts interrupt-parent dmas dma-names"
+CONFIG_DM=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_CLK_AT91=y
+CONFIG_AT91_UTMI=y
+CONFIG_AT91_H32MX=y
+CONFIG_DM_GPIO=y
+CONFIG_AT91_GPIO=y
+CONFIG_DM_MMC=y
+CONFIG_GENERIC_ATMEL_MCI=y
 CONFIG_MTD_NOR_FLASH=y
+CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_DM_ETH=y
+CONFIG_MACB=y
+CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_PINCTRL_AT91=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ATMEL=y
+CONFIG_DEBUG_UART_BASE=0xffffee00
+CONFIG_DEBUG_UART_CLOCK=132000000
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_ATMEL_USART=y
+CONFIG_DM_SPI=y
+CONFIG_ATMEL_SPI=y
 CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_ATMEL_USBA=y
 CONFIG_LCD=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 7f3f5ac..9814ea3 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -83,6 +83,7 @@
 CONFIG_CROS_EC_KEYB=y
 CONFIG_I8042_KEYB=y
 CONFIG_LED=y
+CONFIG_LED_BLINK=y
 CONFIG_LED_GPIO=y
 CONFIG_DM_MAILBOX=y
 CONFIG_SANDBOX_MBOX=y
diff --git a/configs/sandbox_noblk_defconfig b/configs/sandbox_noblk_defconfig
index 3f8e70d..bba7443 100644
--- a/configs/sandbox_noblk_defconfig
+++ b/configs/sandbox_noblk_defconfig
@@ -92,6 +92,7 @@
 CONFIG_CROS_EC_KEYB=y
 CONFIG_I8042_KEYB=y
 CONFIG_LED=y
+CONFIG_LED_BLINK=y
 CONFIG_LED_GPIO=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_I2C=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index ade6714..6fe2125 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -94,6 +94,7 @@
 CONFIG_CROS_EC_KEYB=y
 CONFIG_I8042_KEYB=y
 CONFIG_LED=y
+CONFIG_LED_BLINK=y
 CONFIG_LED_GPIO=y
 CONFIG_DM_MAILBOX=y
 CONFIG_SANDBOX_MBOX=y
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 3e6bbac..a096dad 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -24,6 +24,8 @@
 
 source "drivers/dma/Kconfig"
 
+source "drivers/firmware/Kconfig"
+
 source "drivers/fpga/Kconfig"
 
 source "drivers/gpio/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 5d8baa5..4a4b237 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -23,7 +23,7 @@
 obj-$(CONFIG_SPL_SPI_SUPPORT) += spi/
 obj-$(CONFIG_SPL_POWER_SUPPORT) += power/ power/pmic/
 obj-$(CONFIG_SPL_POWER_SUPPORT) += power/regulator/
-obj-$(CONFIG_SPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/
+obj-$(CONFIG_SPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/ firmware/
 obj-$(CONFIG_SPL_MTD_SUPPORT) += mtd/
 obj-$(CONFIG_SPL_NAND_SUPPORT) += mtd/nand/
 obj-$(CONFIG_SPL_ONENAND_SUPPORT) += mtd/onenand/
@@ -52,7 +52,7 @@
 ifdef CONFIG_TPL_BUILD
 
 obj-$(CONFIG_TPL_I2C_SUPPORT) += i2c/
-obj-$(CONFIG_TPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/
+obj-$(CONFIG_TPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/ firmware/
 obj-$(CONFIG_TPL_MMC_SUPPORT) += mmc/
 obj-$(CONFIG_TPL_MPC8XXX_INIT_DDR_SUPPORT) += ddr/fsl/
 obj-$(CONFIG_TPL_NAND_SUPPORT) += mtd/nand/
@@ -71,6 +71,7 @@
 obj-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount/
 obj-$(CONFIG_CPU) += cpu/
 obj-y += crypto/
+obj-y += firmware/
 obj-$(CONFIG_FPGA) += fpga/
 obj-y += hwmon/
 obj-y += misc/
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index a72feec..f415b33 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -20,7 +20,6 @@
 obj-$(CONFIG_LIBATA) += libata.o
 obj-$(CONFIG_MVSATA_IDE) += mvsata_ide.o
 obj-$(CONFIG_MX51_PATA) += mxc_ata.o
-obj-$(CONFIG_PATA_BFIN) += pata_bfin.o
 obj-$(CONFIG_SATA_CEVA) += sata_ceva.o
 obj-$(CONFIG_SATA_DWC) += sata_dwc.o
 obj-$(CONFIG_SATA_MV) += sata_mv.o
diff --git a/drivers/block/fsl_sata.c b/drivers/block/fsl_sata.c
index e000ebf..31f7fab 100644
--- a/drivers/block/fsl_sata.c
+++ b/drivers/block/fsl_sata.c
@@ -124,7 +124,7 @@
 	length = sizeof(struct cmd_hdr_tbl);
 	align = SATA_HC_CMD_HDR_TBL_ALIGN;
 	sata->cmd_hdr_tbl_offset = (void *)malloc(length + align);
-	if (!sata) {
+	if (!sata->cmd_hdr_tbl_offset) {
 		printf("alloc the command header failed\n\r");
 		return -1;
 	}
diff --git a/drivers/block/pata_bfin.c b/drivers/block/pata_bfin.c
deleted file mode 100644
index 36a1512..0000000
--- a/drivers/block/pata_bfin.c
+++ /dev/null
@@ -1,1209 +0,0 @@
-/*
- * Driver for Blackfin on-chip ATAPI controller.
- *
- * Enter bugs at http://blackfin.uclinux.org/
- *
- * Copyright (c) 2008 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <command.h>
-#include <config.h>
-#include <asm/byteorder.h>
-#include <asm/clock.h>
-#include <asm/io.h>
-#include <linux/errno.h>
-#include <asm/portmux.h>
-#include <asm/mach-common/bits/pata.h>
-#include <ata.h>
-#include <sata.h>
-#include <libata.h>
-#include "pata_bfin.h"
-
-static struct ata_port port[CONFIG_SYS_SATA_MAX_DEVICE];
-
-/**
- * PIO Mode - Frequency compatibility
- */
-/* mode: 0         1         2         3         4 */
-static const u32 pio_fsclk[] =
-{ 33333333, 33333333, 33333333, 33333333, 33333333 };
-
-/**
- * MDMA Mode - Frequency compatibility
- */
-/*               mode:      0         1         2        */
-static const u32 mdma_fsclk[] = { 33333333, 33333333, 33333333 };
-
-/**
- * UDMA Mode - Frequency compatibility
- *
- * UDMA5 - 100 MB/s   - SCLK  = 133 MHz
- * UDMA4 - 66 MB/s    - SCLK >=  80 MHz
- * UDMA3 - 44.4 MB/s  - SCLK >=  50 MHz
- * UDMA2 - 33 MB/s    - SCLK >=  40 MHz
- */
-/* mode: 0         1         2         3         4          5 */
-static const u32 udma_fsclk[] =
-{ 33333333, 33333333, 40000000, 50000000, 80000000, 133333333 };
-
-/**
- * Register transfer timing table
- */
-/*               mode:       0    1    2    3    4    */
-/* Cycle Time                     */
-static const u32 reg_t0min[]   = { 600, 383, 330, 180, 120 };
-/* DIOR/DIOW to end cycle         */
-static const u32 reg_t2min[]   = { 290, 290, 290, 70,  25  };
-/* DIOR/DIOW asserted pulse width */
-static const u32 reg_teocmin[] = { 290, 290, 290, 80,  70  };
-
-/**
- * PIO timing table
- */
-/*               mode:       0    1    2    3    4    */
-/* Cycle Time                     */
-static const u32 pio_t0min[]   = { 600, 383, 240, 180, 120 };
-/* Address valid to DIOR/DIORW    */
-static const u32 pio_t1min[]   = { 70,  50,  30,  30,  25  };
-/* DIOR/DIOW to end cycle         */
-static const u32 pio_t2min[]   = { 165, 125, 100, 80,  70  };
-/* DIOR/DIOW asserted pulse width */
-static const u32 pio_teocmin[] = { 165, 125, 100, 70,  25  };
-/* DIOW data hold                 */
-static const u32 pio_t4min[]   = { 30,  20,  15,  10,  10  };
-
-/* ******************************************************************
- * Multiword DMA timing table
- * ******************************************************************
- */
-/*               mode:       0   1    2        */
-/* Cycle Time                     */
-static const u32 mdma_t0min[]  = { 480, 150, 120 };
-/* DIOR/DIOW asserted pulse width */
-static const u32 mdma_tdmin[]  = { 215, 80,  70  };
-/* DMACK to read data released    */
-static const u32 mdma_thmin[]  = { 20,  15,  10  };
-/* DIOR/DIOW to DMACK hold        */
-static const u32 mdma_tjmin[]  = { 20,  5,   5   };
-/* DIOR negated pulse width       */
-static const u32 mdma_tkrmin[] = { 50,  50,  25  };
-/* DIOR negated pulse width       */
-static const u32 mdma_tkwmin[] = { 215, 50,  25  };
-/* CS[1:0] valid to DIOR/DIOW     */
-static const u32 mdma_tmmin[]  = { 50,  30,  25  };
-/* DMACK to read data released    */
-static const u32 mdma_tzmax[]  = { 20,  25,  25  };
-
-/**
- * Ultra DMA timing table
- */
-/*               mode:         0    1    2    3    4    5       */
-static const u32 udma_tcycmin[]  = { 112, 73,  54,  39,  25,  17 };
-static const u32 udma_tdvsmin[]  = { 70,  48,  31,  20,  7,   5  };
-static const u32 udma_tenvmax[]  = { 70,  70,  70,  55,  55,  50 };
-static const u32 udma_trpmin[]   = { 160, 125, 100, 100, 100, 85 };
-static const u32 udma_tmin[]     = { 5,   5,   5,   5,   3,   3  };
-
-
-static const u32 udma_tmlimin = 20;
-static const u32 udma_tzahmin = 20;
-static const u32 udma_tenvmin = 20;
-static const u32 udma_tackmin = 20;
-static const u32 udma_tssmin = 50;
-
-static void msleep(int count)
-{
-	int i;
-
-	for (i = 0; i < count; i++)
-		udelay(1000);
-}
-
-/**
- *
- *	Function:       num_clocks_min
- *
- *	Description:
- *	calculate number of SCLK cycles to meet minimum timing
- */
-static unsigned short num_clocks_min(unsigned long tmin,
-				unsigned long fsclk)
-{
-	unsigned long tmp ;
-	unsigned short result;
-
-	tmp = tmin * (fsclk/1000/1000) / 1000;
-	result = (unsigned short)tmp;
-	if ((tmp*1000*1000) < (tmin*(fsclk/1000)))
-		result++;
-
-	return result;
-}
-
-/**
- *	bfin_set_piomode - Initialize host controller PATA PIO timings
- *	@ap: Port whose timings we are configuring
- *	@pio_mode: mode
- *
- *	Set PIO mode for device.
- *
- *	LOCKING:
- *	None (inherited from caller).
- */
-
-static void bfin_set_piomode(struct ata_port *ap, int pio_mode)
-{
-	int mode = pio_mode - XFER_PIO_0;
-	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-	unsigned int fsclk = get_sclk();
-	unsigned short teoc_reg, t2_reg, teoc_pio;
-	unsigned short t4_reg, t2_pio, t1_reg;
-	unsigned short n0, n6, t6min = 5;
-
-	/* the most restrictive timing value is t6 and tc, the DIOW - data hold
-	* If one SCLK pulse is longer than this minimum value then register
-	* transfers cannot be supported at this frequency.
-	*/
-	n6 = num_clocks_min(t6min, fsclk);
-	if (mode >= 0 && mode <= 4 && n6 >= 1) {
-		debug("set piomode: mode=%d, fsclk=%ud\n", mode, fsclk);
-		/* calculate the timing values for register transfers. */
-		while (mode > 0 && pio_fsclk[mode] > fsclk)
-			mode--;
-
-		/* DIOR/DIOW to end cycle time */
-		t2_reg = num_clocks_min(reg_t2min[mode], fsclk);
-		/* DIOR/DIOW asserted pulse width */
-		teoc_reg = num_clocks_min(reg_teocmin[mode], fsclk);
-		/* Cycle Time */
-		n0  = num_clocks_min(reg_t0min[mode], fsclk);
-
-		/* increase t2 until we meed the minimum cycle length */
-		if (t2_reg + teoc_reg < n0)
-			t2_reg = n0 - teoc_reg;
-
-		/* calculate the timing values for pio transfers. */
-
-		/* DIOR/DIOW to end cycle time */
-		t2_pio = num_clocks_min(pio_t2min[mode], fsclk);
-		/* DIOR/DIOW asserted pulse width */
-		teoc_pio = num_clocks_min(pio_teocmin[mode], fsclk);
-		/* Cycle Time */
-		n0  = num_clocks_min(pio_t0min[mode], fsclk);
-
-		/* increase t2 until we meed the minimum cycle length */
-		if (t2_pio + teoc_pio < n0)
-			t2_pio = n0 - teoc_pio;
-
-		/* Address valid to DIOR/DIORW */
-		t1_reg = num_clocks_min(pio_t1min[mode], fsclk);
-
-		/* DIOW data hold */
-		t4_reg = num_clocks_min(pio_t4min[mode], fsclk);
-
-		ATAPI_SET_REG_TIM_0(base, (teoc_reg<<8 | t2_reg));
-		ATAPI_SET_PIO_TIM_0(base, (t4_reg<<12 | t2_pio<<4 | t1_reg));
-		ATAPI_SET_PIO_TIM_1(base, teoc_pio);
-		if (mode > 2) {
-			ATAPI_SET_CONTROL(base,
-				ATAPI_GET_CONTROL(base) | IORDY_EN);
-		} else {
-			ATAPI_SET_CONTROL(base,
-				ATAPI_GET_CONTROL(base) & ~IORDY_EN);
-		}
-
-		/* Disable host ATAPI PIO interrupts */
-		ATAPI_SET_INT_MASK(base, ATAPI_GET_INT_MASK(base)
-			& ~(PIO_DONE_MASK | HOST_TERM_XFER_MASK));
-		SSYNC();
-	}
-}
-
-/**
- *
- *    Function:       wait_complete
- *
- *    Description:    Waits the interrupt from device
- *
- */
-static inline void wait_complete(void __iomem *base, unsigned short mask)
-{
-	unsigned short status;
-	unsigned int i = 0;
-
-	for (i = 0; i < PATA_BFIN_WAIT_TIMEOUT; i++) {
-		status = ATAPI_GET_INT_STATUS(base) & mask;
-		if (status)
-			break;
-	}
-
-	ATAPI_SET_INT_STATUS(base, mask);
-}
-
-/**
- *
- *    Function:       write_atapi_register
- *
- *    Description:    Writes to ATA Device Resgister
- *
- */
-
-static void write_atapi_register(void __iomem *base,
-		unsigned long ata_reg, unsigned short value)
-{
-	/* Program the ATA_DEV_TXBUF register with write data (to be
-	 * written into the device).
-	 */
-	ATAPI_SET_DEV_TXBUF(base, value);
-
-	/* Program the ATA_DEV_ADDR register with address of the
-	 * device register (0x01 to 0x0F).
-	 */
-	ATAPI_SET_DEV_ADDR(base, ata_reg);
-
-	/* Program the ATA_CTRL register with dir set to write (1)
-	 */
-	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | XFER_DIR));
-
-	/* ensure PIO DMA is not set */
-	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA));
-
-	/* and start the transfer */
-	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START));
-
-	/* Wait for the interrupt to indicate the end of the transfer.
-	 * (We need to wait on and clear rhe ATA_DEV_INT interrupt status)
-	 */
-	wait_complete(base, PIO_DONE_INT);
-}
-
-/**
- *
- *	Function:       read_atapi_register
- *
- *Description:    Reads from ATA Device Resgister
- *
- */
-
-static unsigned short read_atapi_register(void __iomem *base,
-		unsigned long ata_reg)
-{
-	/* Program the ATA_DEV_ADDR register with address of the
-	 * device register (0x01 to 0x0F).
-	 */
-	ATAPI_SET_DEV_ADDR(base, ata_reg);
-
-	/* Program the ATA_CTRL register with dir set to read (0) and
-	 */
-	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~XFER_DIR));
-
-	/* ensure PIO DMA is not set */
-	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA));
-
-	/* and start the transfer */
-	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START));
-
-	/* Wait for the interrupt to indicate the end of the transfer.
-	 * (PIO_DONE interrupt is set and it doesn't seem to matter
-	 * that we don't clear it)
-	 */
-	wait_complete(base, PIO_DONE_INT);
-
-	/* Read the ATA_DEV_RXBUF register with write data (to be
-	 * written into the device).
-	 */
-	return ATAPI_GET_DEV_RXBUF(base);
-}
-
-/**
- *
- *    Function:       write_atapi_register_data
- *
- *    Description:    Writes to ATA Device Resgister
- *
- */
-
-static void write_atapi_data(void __iomem *base,
-		int len, unsigned short *buf)
-{
-	int i;
-
-	/* Set transfer length to 1 */
-	ATAPI_SET_XFER_LEN(base, 1);
-
-	/* Program the ATA_DEV_ADDR register with address of the
-	 * ATA_REG_DATA
-	 */
-	ATAPI_SET_DEV_ADDR(base, ATA_REG_DATA);
-
-	/* Program the ATA_CTRL register with dir set to write (1)
-	 */
-	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | XFER_DIR));
-
-	/* ensure PIO DMA is not set */
-	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA));
-
-	for (i = 0; i < len; i++) {
-		/* Program the ATA_DEV_TXBUF register with write data (to be
-		 * written into the device).
-		 */
-		ATAPI_SET_DEV_TXBUF(base, buf[i]);
-
-		/* and start the transfer */
-		ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START));
-
-		/* Wait for the interrupt to indicate the end of the transfer.
-		 * (We need to wait on and clear rhe ATA_DEV_INT
-		 * interrupt status)
-		 */
-		wait_complete(base, PIO_DONE_INT);
-	}
-}
-
-/**
- *
- *	Function:       read_atapi_register_data
- *
- *	Description:    Reads from ATA Device Resgister
- *
- */
-
-static void read_atapi_data(void __iomem *base,
-		int len, unsigned short *buf)
-{
-	int i;
-
-	/* Set transfer length to 1 */
-	ATAPI_SET_XFER_LEN(base, 1);
-
-	/* Program the ATA_DEV_ADDR register with address of the
-	 * ATA_REG_DATA
-	 */
-	ATAPI_SET_DEV_ADDR(base, ATA_REG_DATA);
-
-	/* Program the ATA_CTRL register with dir set to read (0) and
-	 */
-	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~XFER_DIR));
-
-	/* ensure PIO DMA is not set */
-	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA));
-
-	for (i = 0; i < len; i++) {
-		/* and start the transfer */
-		ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START));
-
-		/* Wait for the interrupt to indicate the end of the transfer.
-		 * (PIO_DONE interrupt is set and it doesn't seem to matter
-		 * that we don't clear it)
-		 */
-		wait_complete(base, PIO_DONE_INT);
-
-		/* Read the ATA_DEV_RXBUF register with write data (to be
-		 * written into the device).
-		 */
-		buf[i] = ATAPI_GET_DEV_RXBUF(base);
-	}
-}
-
-/**
- *	bfin_check_status - Read device status reg & clear interrupt
- *	@ap: port where the device is
- *
- *	Note: Original code is ata_check_status().
- */
-
-static u8 bfin_check_status(struct ata_port *ap)
-{
-	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-	return read_atapi_register(base, ATA_REG_STATUS);
-}
-
-/**
- *	bfin_check_altstatus - Read device alternate status reg
- *	@ap: port where the device is
- */
-
-static u8 bfin_check_altstatus(struct ata_port *ap)
-{
-	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-	return read_atapi_register(base, ATA_REG_ALTSTATUS);
-}
-
-/**
- *      bfin_ata_busy_wait - Wait for a port status register
- *      @ap: Port to wait for.
- *      @bits: bits that must be clear
- *      @max: number of 10uS waits to perform
- *
- *      Waits up to max*10 microseconds for the selected bits in the port's
- *      status register to be cleared.
- *      Returns final value of status register.
- *
- *      LOCKING:
- *      Inherited from caller.
- */
-static inline u8 bfin_ata_busy_wait(struct ata_port *ap, unsigned int bits,
-				unsigned int max, u8 usealtstatus)
-{
-	u8 status;
-
-	do {
-		udelay(10);
-		if (usealtstatus)
-			status = bfin_check_altstatus(ap);
-		else
-			status = bfin_check_status(ap);
-		max--;
-	} while (status != 0xff && (status & bits) && (max > 0));
-
-	return status;
-}
-
-/**
- *	bfin_ata_busy_sleep - sleep until BSY clears, or timeout
- *	@ap: port containing status register to be polled
- *	@tmout_pat: impatience timeout in msecs
- *	@tmout: overall timeout in msecs
- *
- *	Sleep until ATA Status register bit BSY clears,
- *	or a timeout occurs.
- *
- *	RETURNS:
- *	0 on success, -errno otherwise.
- */
-static int bfin_ata_busy_sleep(struct ata_port *ap,
-		       long tmout_pat, unsigned long tmout)
-{
-	u8 status;
-
-	status = bfin_ata_busy_wait(ap, ATA_BUSY, 300, 0);
-	while (status != 0xff && (status & ATA_BUSY) && tmout_pat > 0) {
-		msleep(50);
-		tmout_pat -= 50;
-		status = bfin_ata_busy_wait(ap, ATA_BUSY, 3, 0);
-	}
-
-	if (status != 0xff && (status & ATA_BUSY))
-		printf("port is slow to respond, please be patient "
-				"(Status 0x%x)\n", status);
-
-	while (status != 0xff && (status & ATA_BUSY) && tmout_pat > 0) {
-		msleep(50);
-		tmout_pat -= 50;
-		status = bfin_check_status(ap);
-	}
-
-	if (status == 0xff)
-		return -ENODEV;
-
-	if (status & ATA_BUSY) {
-		printf("port failed to respond "
-				"(%lu secs, Status 0x%x)\n",
-				DIV_ROUND_UP(tmout, 1000), status);
-		return -EBUSY;
-	}
-
-	return 0;
-}
-
-/**
- *	bfin_dev_select - Select device 0/1 on ATA bus
- *	@ap: ATA channel to manipulate
- *	@device: ATA device (numbered from zero) to select
- *
- *	Note: Original code is ata_sff_dev_select().
- */
-
-static void bfin_dev_select(struct ata_port *ap, unsigned int device)
-{
-	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-	u8 tmp;
-
-
-	if (device == 0)
-		tmp = ATA_DEVICE_OBS;
-	else
-		tmp = ATA_DEVICE_OBS | ATA_DEV1;
-
-	write_atapi_register(base, ATA_REG_DEVICE, tmp);
-	udelay(1);
-}
-
-/**
- *	bfin_devchk - PATA device presence detection
- *	@ap: ATA channel to examine
- *	@device: Device to examine (starting at zero)
- *
- *	Note: Original code is ata_devchk().
- */
-
-static unsigned int bfin_devchk(struct ata_port *ap,
-				unsigned int device)
-{
-	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-	u8 nsect, lbal;
-
-	bfin_dev_select(ap, device);
-
-	write_atapi_register(base, ATA_REG_NSECT, 0x55);
-	write_atapi_register(base, ATA_REG_LBAL, 0xaa);
-
-	write_atapi_register(base, ATA_REG_NSECT, 0xaa);
-	write_atapi_register(base, ATA_REG_LBAL, 0x55);
-
-	write_atapi_register(base, ATA_REG_NSECT, 0x55);
-	write_atapi_register(base, ATA_REG_LBAL, 0xaa);
-
-	nsect = read_atapi_register(base, ATA_REG_NSECT);
-	lbal = read_atapi_register(base, ATA_REG_LBAL);
-
-	if ((nsect == 0x55) && (lbal == 0xaa))
-		return 1;	/* we found a device */
-
-	return 0;		/* nothing found */
-}
-
-/**
- *	bfin_bus_post_reset - PATA device post reset
- *
- *	Note: Original code is ata_bus_post_reset().
- */
-
-static void bfin_bus_post_reset(struct ata_port *ap, unsigned int devmask)
-{
-	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-	unsigned int dev0 = devmask & (1 << 0);
-	unsigned int dev1 = devmask & (1 << 1);
-	long deadline;
-
-	/* if device 0 was found in ata_devchk, wait for its
-	 * BSY bit to clear
-	 */
-	if (dev0)
-		bfin_ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
-
-	/* if device 1 was found in ata_devchk, wait for
-	 * register access, then wait for BSY to clear
-	 */
-	deadline = ATA_TMOUT_BOOT;
-	while (dev1) {
-		u8 nsect, lbal;
-
-		bfin_dev_select(ap, 1);
-		nsect = read_atapi_register(base, ATA_REG_NSECT);
-		lbal = read_atapi_register(base, ATA_REG_LBAL);
-		if ((nsect == 1) && (lbal == 1))
-			break;
-		if (deadline <= 0) {
-			dev1 = 0;
-			break;
-		}
-		msleep(50);	/* give drive a breather */
-		deadline -= 50;
-	}
-	if (dev1)
-		bfin_ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
-
-	/* is all this really necessary? */
-	bfin_dev_select(ap, 0);
-	if (dev1)
-		bfin_dev_select(ap, 1);
-	if (dev0)
-		bfin_dev_select(ap, 0);
-}
-
-/**
- *	bfin_bus_softreset - PATA device software reset
- *
- *	Note: Original code is ata_bus_softreset().
- */
-
-static unsigned int bfin_bus_softreset(struct ata_port *ap,
-				       unsigned int devmask)
-{
-	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-
-	/* software reset.  causes dev0 to be selected */
-	write_atapi_register(base, ATA_REG_CTRL, ap->ctl_reg);
-	udelay(20);
-	write_atapi_register(base, ATA_REG_CTRL, ap->ctl_reg | ATA_SRST);
-	udelay(20);
-	write_atapi_register(base, ATA_REG_CTRL, ap->ctl_reg);
-
-	/* spec mandates ">= 2ms" before checking status.
-	 * We wait 150ms, because that was the magic delay used for
-	 * ATAPI devices in Hale Landis's ATADRVR, for the period of time
-	 * between when the ATA command register is written, and then
-	 * status is checked.  Because waiting for "a while" before
-	 * checking status is fine, post SRST, we perform this magic
-	 * delay here as well.
-	 *
-	 * Old drivers/ide uses the 2mS rule and then waits for ready
-	 */
-	msleep(150);
-
-	/* Before we perform post reset processing we want to see if
-	 * the bus shows 0xFF because the odd clown forgets the D7
-	 * pulldown resistor.
-	 */
-	if (bfin_check_status(ap) == 0xFF)
-		return 0;
-
-	bfin_bus_post_reset(ap, devmask);
-
-	return 0;
-}
-
-/**
- *	bfin_softreset - reset host port via ATA SRST
- *	@ap: port to reset
- *
- *	Note: Original code is ata_sff_softreset().
- */
-
-static int bfin_softreset(struct ata_port *ap)
-{
-	unsigned int err_mask;
-
-	ap->dev_mask = 0;
-
-	/* determine if device 0/1 are present.
-	 * only one device is supported on one port by now.
-	*/
-	if (bfin_devchk(ap, 0))
-		ap->dev_mask |= (1 << 0);
-	else if (bfin_devchk(ap, 1))
-		ap->dev_mask |= (1 << 1);
-	else
-		return -ENODEV;
-
-	/* select device 0 again */
-	bfin_dev_select(ap, 0);
-
-	/* issue bus reset */
-	err_mask = bfin_bus_softreset(ap, ap->dev_mask);
-	if (err_mask) {
-		printf("SRST failed (err_mask=0x%x)\n",
-				err_mask);
-		ap->dev_mask = 0;
-		return -EIO;
-	}
-
-	return 0;
-}
-
-/**
- *	bfin_irq_clear - Clear ATAPI interrupt.
- *	@ap: Port associated with this ATA transaction.
- *
- *	Note: Original code is ata_sff_irq_clear().
- */
-
-static void bfin_irq_clear(struct ata_port *ap)
-{
-	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-
-	ATAPI_SET_INT_STATUS(base, ATAPI_GET_INT_STATUS(base)|ATAPI_DEV_INT
-		| MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT
-		| MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT);
-}
-
-static u8 bfin_wait_for_irq(struct ata_port *ap, unsigned int max)
-{
-	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-
-	do {
-		if (ATAPI_GET_INT_STATUS(base) & (ATAPI_DEV_INT
-		| MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT
-		| MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT)) {
-			break;
-		}
-		udelay(1000);
-		max--;
-	} while ((max > 0));
-
-	return max == 0;
-}
-
-/**
- *	bfin_ata_reset_port - initialize BFIN ATAPI port.
- */
-
-static int bfin_ata_reset_port(struct ata_port *ap)
-{
-	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-	int count;
-	unsigned short status;
-
-	/* Disable all ATAPI interrupts */
-	ATAPI_SET_INT_MASK(base, 0);
-	SSYNC();
-
-	/* Assert the RESET signal 25us*/
-	ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | DEV_RST);
-	udelay(30);
-
-	/* Negate the RESET signal for 2ms*/
-	ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) & ~DEV_RST);
-	msleep(2);
-
-	/* Wait on Busy flag to clear */
-	count = 10000000;
-	do {
-		status = read_atapi_register(base, ATA_REG_STATUS);
-	} while (--count && (status & ATA_BUSY));
-
-	/* Enable only ATAPI Device interrupt */
-	ATAPI_SET_INT_MASK(base, 1);
-	SSYNC();
-
-	return !count;
-}
-
-/**
- *
- *	Function:       bfin_config_atapi_gpio
- *
- *	Description:    Configures the ATAPI pins for use
- *
- */
-static int bfin_config_atapi_gpio(struct ata_port *ap)
-{
-	const unsigned short pins[] = {
-		P_ATAPI_RESET, P_ATAPI_DIOR, P_ATAPI_DIOW, P_ATAPI_CS0,
-		P_ATAPI_CS1, P_ATAPI_DMACK, P_ATAPI_DMARQ, P_ATAPI_INTRQ,
-		P_ATAPI_IORDY, P_ATAPI_D0A, P_ATAPI_D1A, P_ATAPI_D2A,
-		P_ATAPI_D3A, P_ATAPI_D4A, P_ATAPI_D5A, P_ATAPI_D6A,
-		P_ATAPI_D7A, P_ATAPI_D8A, P_ATAPI_D9A, P_ATAPI_D10A,
-		P_ATAPI_D11A, P_ATAPI_D12A, P_ATAPI_D13A, P_ATAPI_D14A,
-		P_ATAPI_D15A, P_ATAPI_A0A, P_ATAPI_A1A, P_ATAPI_A2A, 0,
-	};
-
-	peripheral_request_list(pins, "pata_bfin");
-
-	return 0;
-}
-
-/**
- *	bfin_atapi_probe	-	attach a bfin atapi interface
- *	@pdev: platform device
- *
- *	Register a bfin atapi interface.
- *
- *
- *	Platform devices are expected to contain 2 resources per port:
- *
- *		- I/O Base (IORESOURCE_IO)
- *		- IRQ	   (IORESOURCE_IRQ)
- *
- */
-static int bfin_ata_probe_port(struct ata_port *ap)
-{
-	if (bfin_config_atapi_gpio(ap)) {
-		printf("Requesting Peripherals faild\n");
-		return -EFAULT;
-	}
-
-	if (bfin_ata_reset_port(ap)) {
-		printf("Fail to reset ATAPI device\n");
-		return -EFAULT;
-	}
-
-	if (ap->ata_mode >= XFER_PIO_0 && ap->ata_mode <= XFER_PIO_4)
-		bfin_set_piomode(ap, ap->ata_mode);
-	else {
-		printf("Given ATA data transfer mode is not supported.\n");
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-#define ATA_SECTOR_WORDS (ATA_SECT_SIZE/2)
-
-static void bfin_ata_identify(struct ata_port *ap, int dev)
-{
-	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-	u8 status = 0;
-	static u16 iobuf[ATA_SECTOR_WORDS];
-	u64 n_sectors = 0;
-	hd_driveid_t *iop = (hd_driveid_t *)iobuf;
-
-	memset(iobuf, 0, sizeof(iobuf));
-
-	if (!(ap->dev_mask & (1 << dev)))
-		return;
-
-	debug("port=%d dev=%d\n", ap->port_no, dev);
-
-	bfin_dev_select(ap, dev);
-
-	status = 0;
-	/* Device Identify Command */
-	write_atapi_register(base, ATA_REG_CMD, ATA_CMD_ID_ATA);
-	bfin_check_altstatus(ap);
-	udelay(10);
-
-	status = bfin_ata_busy_wait(ap, ATA_BUSY, 1000, 0);
-	if (status & ATA_ERR) {
-		printf("\ndevice not responding\n");
-		ap->dev_mask &= ~(1 << dev);
-		return;
-	}
-
-	read_atapi_data(base, ATA_SECTOR_WORDS, iobuf);
-
-	ata_swap_buf_le16(iobuf, ATA_SECTOR_WORDS);
-
-	/* we require LBA and DMA support (bits 8 & 9 of word 49) */
-	if (!ata_id_has_dma(iobuf) || !ata_id_has_lba(iobuf))
-		printf("ata%u: no dma/lba\n", ap->port_no);
-
-#ifdef DEBUG
-	ata_dump_id(iobuf);
-#endif
-
-	n_sectors = ata_id_n_sectors(iobuf);
-
-	if (n_sectors == 0) {
-		ap->dev_mask &= ~(1 << dev);
-		return;
-	}
-
-	ata_id_c_string(iobuf, (unsigned char *)sata_dev_desc[ap->port_no].revision,
-			 ATA_ID_FW_REV, sizeof(sata_dev_desc[ap->port_no].revision));
-	ata_id_c_string(iobuf, (unsigned char *)sata_dev_desc[ap->port_no].vendor,
-			 ATA_ID_PROD, sizeof(sata_dev_desc[ap->port_no].vendor));
-	ata_id_c_string(iobuf, (unsigned char *)sata_dev_desc[ap->port_no].product,
-			 ATA_ID_SERNO, sizeof(sata_dev_desc[ap->port_no].product));
-
-	if ((iop->config & 0x0080) == 0x0080)
-		sata_dev_desc[ap->port_no].removable = 1;
-	else
-		sata_dev_desc[ap->port_no].removable = 0;
-
-	sata_dev_desc[ap->port_no].lba = (u32) n_sectors;
-	debug("lba=0x%lx\n", sata_dev_desc[ap->port_no].lba);
-
-#ifdef CONFIG_LBA48
-	if (iop->command_set_2 & 0x0400)
-		sata_dev_desc[ap->port_no].lba48 = 1;
-	else
-		sata_dev_desc[ap->port_no].lba48 = 0;
-#endif
-
-	/* assuming HD */
-	sata_dev_desc[ap->port_no].type = DEV_TYPE_HARDDISK;
-	sata_dev_desc[ap->port_no].blksz = ATA_SECT_SIZE;
-	sata_dev_desc[ap->port_no].log2blksz =
-		LOG2(sata_dev_desc[ap->port_no].blksz);
-	sata_dev_desc[ap->port_no].lun = 0;	/* just to fill something in... */
-
-	printf("PATA device#%d %s is found on ata port#%d.\n",
-		ap->port_no%PATA_DEV_NUM_PER_PORT,
-		sata_dev_desc[ap->port_no].vendor,
-		ap->port_no/PATA_DEV_NUM_PER_PORT);
-}
-
-static void bfin_ata_set_Feature_cmd(struct ata_port *ap, int dev)
-{
-	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-	u8 status = 0;
-
-	if (!(ap->dev_mask & (1 << dev)))
-		return;
-
-	bfin_dev_select(ap, dev);
-
-	write_atapi_register(base, ATA_REG_FEATURE, SETFEATURES_XFER);
-	write_atapi_register(base, ATA_REG_NSECT, ap->ata_mode);
-	write_atapi_register(base, ATA_REG_LBAL, 0);
-	write_atapi_register(base, ATA_REG_LBAM, 0);
-	write_atapi_register(base, ATA_REG_LBAH, 0);
-
-	write_atapi_register(base, ATA_REG_DEVICE, ATA_DEVICE_OBS);
-	write_atapi_register(base, ATA_REG_CMD, ATA_CMD_SET_FEATURES);
-
-	udelay(50);
-	msleep(150);
-
-	status = bfin_ata_busy_wait(ap, ATA_BUSY, 5000, 0);
-	if ((status & (ATA_BUSY | ATA_ERR))) {
-		printf("Error  : status 0x%02x\n", status);
-		ap->dev_mask &= ~(1 << dev);
-	}
-}
-
-int scan_sata(int dev)
-{
-	/* dev is the index of each ata device in the system. one PATA port
-	 * contains 2 devices. one element in scan_done array indicates one
-	 * PATA port. device connected to one PATA port is selected by
-	 * bfin_dev_select() before access.
-	 */
-	struct ata_port *ap = &port[dev];
-	static int scan_done[(CONFIG_SYS_SATA_MAX_DEVICE+1)/PATA_DEV_NUM_PER_PORT];
-
-	if (scan_done[dev/PATA_DEV_NUM_PER_PORT])
-		return 0;
-
-	/* Check for attached device */
-	if (!bfin_ata_probe_port(ap)) {
-		if (bfin_softreset(ap)) {
-			/* soft reset failed, try a hard one */
-			bfin_ata_reset_port(ap);
-			if (bfin_softreset(ap))
-				scan_done[dev/PATA_DEV_NUM_PER_PORT] = 1;
-		} else {
-			scan_done[dev/PATA_DEV_NUM_PER_PORT] = 1;
-		}
-	}
-	if (scan_done[dev/PATA_DEV_NUM_PER_PORT]) {
-		/* Probe device and set xfer mode */
-		bfin_ata_identify(ap, dev%PATA_DEV_NUM_PER_PORT);
-		bfin_ata_set_Feature_cmd(ap, dev%PATA_DEV_NUM_PER_PORT);
-		part_init(&sata_dev_desc[dev]);
-		return 0;
-	}
-
-	printf("PATA device#%d is not present on ATA port#%d.\n",
-		ap->port_no%PATA_DEV_NUM_PER_PORT,
-		ap->port_no/PATA_DEV_NUM_PER_PORT);
-
-	return -1;
-}
-
-int init_sata(int dev)
-{
-	struct ata_port *ap = &port[dev];
-	static u8 init_done;
-	int res = 1;
-
-	if (init_done)
-		return res;
-
-	init_done = 1;
-
-	switch (dev/PATA_DEV_NUM_PER_PORT) {
-	case 0:
-		ap->ioaddr.ctl_addr = ATAPI_CONTROL;
-		ap->ata_mode = CONFIG_BFIN_ATA_MODE;
-		break;
-	default:
-		printf("Tried to scan unknown port %d.\n", dev);
-		return res;
-	}
-
-	if (ap->ata_mode < XFER_PIO_0 || ap->ata_mode > XFER_PIO_4) {
-		ap->ata_mode = XFER_PIO_4;
-		printf("DMA mode is not supported. Set to PIO mode 4.\n");
-	}
-
-	ap->port_no = dev;
-	ap->ctl_reg = 0x8;	/*Default value of control reg */
-
-	res = 0;
-	return res;
-}
-
-int reset_sata(int dev)
-{
-	return 0;
-}
-
-/* Read up to 255 sectors
- *
- * Returns sectors read
-*/
-static u8 do_one_read(struct ata_port *ap, u64 blknr, u8 blkcnt, u16 *buffer,
-			uchar lba48)
-{
-	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-	u8 sr = 0;
-	u8 status;
-	u16 err = 0;
-
-	if (!(bfin_check_status(ap) & ATA_DRDY)) {
-		printf("Device ata%d not ready\n", ap->port_no);
-		return 0;
-	}
-
-	/* Set up transfer */
-#ifdef CONFIG_LBA48
-	if (lba48) {
-		/* write high bits */
-		write_atapi_register(base, ATA_REG_NSECT, 0);
-		write_atapi_register(base, ATA_REG_LBAL, (blknr >> 24) & 0xFF);
-		write_atapi_register(base, ATA_REG_LBAM, (blknr >> 32) & 0xFF);
-		write_atapi_register(base, ATA_REG_LBAH, (blknr >> 40) & 0xFF);
-	}
-#endif
-	write_atapi_register(base, ATA_REG_NSECT, blkcnt);
-	write_atapi_register(base, ATA_REG_LBAL, (blknr >> 0) & 0xFF);
-	write_atapi_register(base, ATA_REG_LBAM, (blknr >> 8) & 0xFF);
-	write_atapi_register(base, ATA_REG_LBAH, (blknr >> 16) & 0xFF);
-
-#ifdef CONFIG_LBA48
-	if (lba48) {
-		write_atapi_register(base, ATA_REG_DEVICE, ATA_LBA);
-		write_atapi_register(base, ATA_REG_CMD, ATA_CMD_PIO_READ_EXT);
-	} else
-#endif
-	{
-		write_atapi_register(base, ATA_REG_DEVICE, ATA_LBA | ((blknr >> 24) & 0xF));
-		write_atapi_register(base, ATA_REG_CMD, ATA_CMD_PIO_READ);
-	}
-	status = bfin_ata_busy_wait(ap, ATA_BUSY, 500000, 1);
-
-	if (status & (ATA_BUSY | ATA_ERR)) {
-		printf("Device %d not responding status 0x%x.\n", ap->port_no, status);
-		err = read_atapi_register(base, ATA_REG_ERR);
-		printf("Error reg = 0x%x\n", err);
-		return sr;
-	}
-
-	while (blkcnt--) {
-		if (bfin_wait_for_irq(ap, 500)) {
-			printf("ata%u irq failed\n", ap->port_no);
-			return sr;
-		}
-
-		status = bfin_check_status(ap);
-		if (status & ATA_ERR) {
-			err = read_atapi_register(base, ATA_REG_ERR);
-			printf("ata%u error %d\n", ap->port_no, err);
-			return sr;
-		}
-		bfin_irq_clear(ap);
-
-		/* Read one sector */
-		read_atapi_data(base, ATA_SECTOR_WORDS, buffer);
-		buffer += ATA_SECTOR_WORDS;
-		sr++;
-	}
-
-	return sr;
-}
-
-ulong sata_read(int dev, ulong block, lbaint_t blkcnt, void *buff)
-{
-	struct ata_port *ap = &port[dev];
-	ulong n = 0, sread;
-	u16 *buffer = (u16 *) buff;
-	u8 status = 0;
-	u64 blknr = (u64) block;
-	unsigned char lba48 = 0;
-
-#ifdef CONFIG_LBA48
-	if (blknr > 0xfffffff) {
-		if (!sata_dev_desc[dev].lba48) {
-			printf("Drive doesn't support 48-bit addressing\n");
-			return 0;
-		}
-		/* more than 28 bits used, use 48bit mode */
-		lba48 = 1;
-	}
-#endif
-	bfin_dev_select(ap, dev%PATA_DEV_NUM_PER_PORT);
-
-	while (blkcnt > 0) {
-
-		if (blkcnt > 255)
-			sread = 255;
-		else
-			sread = blkcnt;
-
-		status = do_one_read(ap, blknr, sread, buffer, lba48);
-		if (status != sread) {
-			printf("Read failed\n");
-			return n;
-		}
-
-		blkcnt -= sread;
-		blknr += sread;
-		n += sread;
-		buffer += sread * ATA_SECTOR_WORDS;
-	}
-	return n;
-}
-
-ulong sata_write(int dev, ulong block, lbaint_t blkcnt, const void *buff)
-{
-	struct ata_port *ap = &port[dev];
-	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-	ulong n = 0;
-	u16 *buffer = (u16 *) buff;
-	unsigned char status = 0;
-	u64 blknr = (u64) block;
-#ifdef CONFIG_LBA48
-	unsigned char lba48 = 0;
-
-	if (blknr > 0xfffffff) {
-		if (!sata_dev_desc[dev].lba48) {
-			printf("Drive doesn't support 48-bit addressing\n");
-			return 0;
-		}
-		/* more than 28 bits used, use 48bit mode */
-		lba48 = 1;
-	}
-#endif
-
-	bfin_dev_select(ap, dev%PATA_DEV_NUM_PER_PORT);
-
-	while (blkcnt-- > 0) {
-		status = bfin_ata_busy_wait(ap, ATA_BUSY, 50000, 0);
-		if (status & ATA_BUSY) {
-			printf("ata%u failed to respond\n", ap->port_no);
-			return n;
-		}
-#ifdef CONFIG_LBA48
-		if (lba48) {
-			/* write high bits */
-			write_atapi_register(base, ATA_REG_NSECT, 0);
-			write_atapi_register(base, ATA_REG_LBAL,
-				(blknr >> 24) & 0xFF);
-			write_atapi_register(base, ATA_REG_LBAM,
-				(blknr >> 32) & 0xFF);
-			write_atapi_register(base, ATA_REG_LBAH,
-				(blknr >> 40) & 0xFF);
-		}
-#endif
-		write_atapi_register(base, ATA_REG_NSECT, 1);
-		write_atapi_register(base, ATA_REG_LBAL, (blknr >> 0) & 0xFF);
-		write_atapi_register(base, ATA_REG_LBAM, (blknr >> 8) & 0xFF);
-		write_atapi_register(base, ATA_REG_LBAH, (blknr >> 16) & 0xFF);
-#ifdef CONFIG_LBA48
-		if (lba48) {
-			write_atapi_register(base, ATA_REG_DEVICE, ATA_LBA);
-			write_atapi_register(base, ATA_REG_CMD,
-				ATA_CMD_PIO_WRITE_EXT);
-		} else
-#endif
-		{
-			write_atapi_register(base, ATA_REG_DEVICE,
-				ATA_LBA | ((blknr >> 24) & 0xF));
-			write_atapi_register(base, ATA_REG_CMD,
-				ATA_CMD_PIO_WRITE);
-		}
-
-		/*may take up to 5 sec */
-		status = bfin_ata_busy_wait(ap, ATA_BUSY, 50000, 0);
-		if ((status & (ATA_DRQ | ATA_BUSY | ATA_ERR)) != ATA_DRQ) {
-			printf("Error no DRQ dev %d blk %ld: sts 0x%02x\n",
-				ap->port_no, (ulong) blknr, status);
-			return n;
-		}
-
-		write_atapi_data(base, ATA_SECTOR_WORDS, buffer);
-		bfin_check_altstatus(ap);
-		udelay(1);
-
-		++n;
-		++blknr;
-		buffer += ATA_SECTOR_WORDS;
-	}
-	return n;
-}
diff --git a/drivers/block/pata_bfin.h b/drivers/block/pata_bfin.h
deleted file mode 100644
index b678f60..0000000
--- a/drivers/block/pata_bfin.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Driver for Blackfin on-chip ATAPI controller.
- *
- * Enter bugs at http://blackfin.uclinux.org/
- *
- * Copyright (c) 2008 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#ifndef PATA_BFIN_H
-#define PATA_BFIN_H
-
-#include <asm/blackfin_local.h>
-
-struct ata_ioports {
-	unsigned long cmd_addr;
-	unsigned long data_addr;
-	unsigned long error_addr;
-	unsigned long feature_addr;
-	unsigned long nsect_addr;
-	unsigned long lbal_addr;
-	unsigned long lbam_addr;
-	unsigned long lbah_addr;
-	unsigned long device_addr;
-	unsigned long status_addr;
-	unsigned long command_addr;
-	unsigned long altstatus_addr;
-	unsigned long ctl_addr;
-	unsigned long bmdma_addr;
-	unsigned long scr_addr;
-};
-
-struct ata_port {
-	unsigned int port_no;		/* primary=0, secondary=1       */
-	struct ata_ioports ioaddr;	/* ATA cmd/ctl/dma reg blks     */
-	unsigned long flag;
-	unsigned int ata_mode;
-	unsigned char ctl_reg;
-	unsigned char last_ctl;
-	unsigned char dev_mask;
-};
-
-#define DRV_NAME		"pata-bfin"
-#define DRV_VERSION		"0.9"
-
-#define ATA_REG_CTRL		0x0E
-#define ATA_REG_ALTSTATUS	ATA_REG_CTRL
-#define ATA_TMOUT_BOOT		30000
-#define ATA_TMOUT_BOOT_QUICK	7000
-
-#define PATA_BFIN_WAIT_TIMEOUT		10000
-#define PATA_DEV_NUM_PER_PORT	2
-
-/* These are the offset of the controller's registers */
-#define ATAPI_OFFSET_CONTROL		0x00
-#define ATAPI_OFFSET_STATUS		0x04
-#define ATAPI_OFFSET_DEV_ADDR		0x08
-#define ATAPI_OFFSET_DEV_TXBUF		0x0c
-#define ATAPI_OFFSET_DEV_RXBUF		0x10
-#define ATAPI_OFFSET_INT_MASK		0x14
-#define ATAPI_OFFSET_INT_STATUS		0x18
-#define ATAPI_OFFSET_XFER_LEN		0x1c
-#define ATAPI_OFFSET_LINE_STATUS	0x20
-#define ATAPI_OFFSET_SM_STATE		0x24
-#define ATAPI_OFFSET_TERMINATE		0x28
-#define ATAPI_OFFSET_PIO_TFRCNT		0x2c
-#define ATAPI_OFFSET_DMA_TFRCNT		0x30
-#define ATAPI_OFFSET_UMAIN_TFRCNT	0x34
-#define ATAPI_OFFSET_UDMAOUT_TFRCNT	0x38
-#define ATAPI_OFFSET_REG_TIM_0		0x40
-#define ATAPI_OFFSET_PIO_TIM_0		0x44
-#define ATAPI_OFFSET_PIO_TIM_1		0x48
-#define ATAPI_OFFSET_MULTI_TIM_0	0x50
-#define ATAPI_OFFSET_MULTI_TIM_1	0x54
-#define ATAPI_OFFSET_MULTI_TIM_2	0x58
-#define ATAPI_OFFSET_ULTRA_TIM_0	0x60
-#define ATAPI_OFFSET_ULTRA_TIM_1	0x64
-#define ATAPI_OFFSET_ULTRA_TIM_2	0x68
-#define ATAPI_OFFSET_ULTRA_TIM_3	0x6c
-
-
-#define ATAPI_GET_CONTROL(base)\
-	bfin_read16(base + ATAPI_OFFSET_CONTROL)
-#define ATAPI_SET_CONTROL(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_CONTROL, val)
-#define ATAPI_GET_STATUS(base)\
-	bfin_read16(base + ATAPI_OFFSET_STATUS)
-#define ATAPI_GET_DEV_ADDR(base)\
-	bfin_read16(base + ATAPI_OFFSET_DEV_ADDR)
-#define ATAPI_SET_DEV_ADDR(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_DEV_ADDR, val)
-#define ATAPI_GET_DEV_TXBUF(base)\
-	bfin_read16(base + ATAPI_OFFSET_DEV_TXBUF)
-#define ATAPI_SET_DEV_TXBUF(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_DEV_TXBUF, val)
-#define ATAPI_GET_DEV_RXBUF(base)\
-	bfin_read16(base + ATAPI_OFFSET_DEV_RXBUF)
-#define ATAPI_SET_DEV_RXBUF(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_DEV_RXBUF, val)
-#define ATAPI_GET_INT_MASK(base)\
-	bfin_read16(base + ATAPI_OFFSET_INT_MASK)
-#define ATAPI_SET_INT_MASK(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_INT_MASK, val)
-#define ATAPI_GET_INT_STATUS(base)\
-	bfin_read16(base + ATAPI_OFFSET_INT_STATUS)
-#define ATAPI_SET_INT_STATUS(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_INT_STATUS, val)
-#define ATAPI_GET_XFER_LEN(base)\
-	bfin_read16(base + ATAPI_OFFSET_XFER_LEN)
-#define ATAPI_SET_XFER_LEN(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_XFER_LEN, val)
-#define ATAPI_GET_LINE_STATUS(base)\
-	bfin_read16(base + ATAPI_OFFSET_LINE_STATUS)
-#define ATAPI_GET_SM_STATE(base)\
-	bfin_read16(base + ATAPI_OFFSET_SM_STATE)
-#define ATAPI_GET_TERMINATE(base)\
-	bfin_read16(base + ATAPI_OFFSET_TERMINATE)
-#define ATAPI_SET_TERMINATE(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_TERMINATE, val)
-#define ATAPI_GET_PIO_TFRCNT(base)\
-	bfin_read16(base + ATAPI_OFFSET_PIO_TFRCNT)
-#define ATAPI_GET_DMA_TFRCNT(base)\
-	bfin_read16(base + ATAPI_OFFSET_DMA_TFRCNT)
-#define ATAPI_GET_UMAIN_TFRCNT(base)\
-	bfin_read16(base + ATAPI_OFFSET_UMAIN_TFRCNT)
-#define ATAPI_GET_UDMAOUT_TFRCNT(base)\
-	bfin_read16(base + ATAPI_OFFSET_UDMAOUT_TFRCNT)
-#define ATAPI_GET_REG_TIM_0(base)\
-	bfin_read16(base + ATAPI_OFFSET_REG_TIM_0)
-#define ATAPI_SET_REG_TIM_0(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_REG_TIM_0, val)
-#define ATAPI_GET_PIO_TIM_0(base)\
-	bfin_read16(base + ATAPI_OFFSET_PIO_TIM_0)
-#define ATAPI_SET_PIO_TIM_0(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_PIO_TIM_0, val)
-#define ATAPI_GET_PIO_TIM_1(base)\
-	bfin_read16(base + ATAPI_OFFSET_PIO_TIM_1)
-#define ATAPI_SET_PIO_TIM_1(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_PIO_TIM_1, val)
-#define ATAPI_GET_MULTI_TIM_0(base)\
-	bfin_read16(base + ATAPI_OFFSET_MULTI_TIM_0)
-#define ATAPI_SET_MULTI_TIM_0(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_MULTI_TIM_0, val)
-#define ATAPI_GET_MULTI_TIM_1(base)\
-	bfin_read16(base + ATAPI_OFFSET_MULTI_TIM_1)
-#define ATAPI_SET_MULTI_TIM_1(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_MULTI_TIM_1, val)
-#define ATAPI_GET_MULTI_TIM_2(base)\
-	bfin_read16(base + ATAPI_OFFSET_MULTI_TIM_2)
-#define ATAPI_SET_MULTI_TIM_2(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_MULTI_TIM_2, val)
-#define ATAPI_GET_ULTRA_TIM_0(base)\
-	bfin_read16(base + ATAPI_OFFSET_ULTRA_TIM_0)
-#define ATAPI_SET_ULTRA_TIM_0(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_ULTRA_TIM_0, val)
-#define ATAPI_GET_ULTRA_TIM_1(base)\
-	bfin_read16(base + ATAPI_OFFSET_ULTRA_TIM_1)
-#define ATAPI_SET_ULTRA_TIM_1(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_ULTRA_TIM_1, val)
-#define ATAPI_GET_ULTRA_TIM_2(base)\
-	bfin_read16(base + ATAPI_OFFSET_ULTRA_TIM_2)
-#define ATAPI_SET_ULTRA_TIM_2(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_ULTRA_TIM_2, val)
-#define ATAPI_GET_ULTRA_TIM_3(base)\
-	bfin_read16(base + ATAPI_OFFSET_ULTRA_TIM_3)
-#define ATAPI_SET_ULTRA_TIM_3(base, val)\
-	bfin_write16(base + ATAPI_OFFSET_ULTRA_TIM_3, val)
-
-#endif
diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c
index f4f6c16..986eabf 100644
--- a/drivers/crypto/fsl/jr.c
+++ b/drivers/crypto/fsl/jr.c
@@ -47,8 +47,7 @@
 		 * VIRT_EN_INCL = 1 & VIRT_EN_POR = 0 & SEC_SCFGR_VIRT_EN = 1
 		 */
 		if ((ctpr_ms & SEC_CTPR_MS_VIRT_EN_POR) ||
-		    (!(ctpr_ms & SEC_CTPR_MS_VIRT_EN_POR) &&
-					(scfgr & SEC_SCFGR_VIRT_EN)))
+		    (scfgr & SEC_SCFGR_VIRT_EN))
 			sec_out32(&sec->jrstartr, CONFIG_JRSTARTR_JR0);
 	} else {
 		/* VIRT_EN_INCL = 0 && VIRT_EN_POR_VALUE = 1 */
diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c
index 1b81a7a..b45a879 100644
--- a/drivers/ddr/fsl/options.c
+++ b/drivers/ddr/fsl/options.c
@@ -916,7 +916,7 @@
 		if ((pdimm[0].data_width >= 64) && \
 			(pdimm[0].data_width <= 72))
 			popts->data_bus_width = 0;
-		else if ((pdimm[0].data_width >= 32) || \
+		else if ((pdimm[0].data_width >= 32) && \
 			(pdimm[0].data_width <= 40))
 			popts->data_bus_width = 1;
 		else {
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
new file mode 100644
index 0000000..4c32426
--- /dev/null
+++ b/drivers/firmware/Kconfig
@@ -0,0 +1,6 @@
+config FIRMWARE
+	bool
+
+config ARM_PSCI_FW
+	bool
+	select FIRMWARE
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
new file mode 100644
index 0000000..b208255
--- /dev/null
+++ b/drivers/firmware/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_FIRMWARE)		+= firmware-uclass.o
+obj-$(CONFIG_ARM_PSCI_FW)	+= psci.o
diff --git a/drivers/firmware/firmware-uclass.c b/drivers/firmware/firmware-uclass.c
new file mode 100644
index 0000000..01b6a44
--- /dev/null
+++ b/drivers/firmware/firmware-uclass.c
@@ -0,0 +1,11 @@
+/*
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <dm/uclass.h>
+
+/* Firmware access is platform-dependent.  No generic code in uclass */
+UCLASS_DRIVER(firmware) = {
+	.id		= UCLASS_FIRMWARE,
+	.name		= "firmware",
+};
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
new file mode 100644
index 0000000..40fba64
--- /dev/null
+++ b/drivers/firmware/psci.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * Based on drivers/firmware/psci.c from Linux:
+ * Copyright (C) 2015 ARM Limited
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm/device.h>
+#include <dm/lists.h>
+#include <libfdt.h>
+#include <linux/arm-smccc.h>
+#include <linux/errno.h>
+#include <linux/psci.h>
+
+psci_fn *invoke_psci_fn;
+
+static unsigned long __invoke_psci_fn_hvc(unsigned long function_id,
+			unsigned long arg0, unsigned long arg1,
+			unsigned long arg2)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_hvc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+	return res.a0;
+}
+
+static unsigned long __invoke_psci_fn_smc(unsigned long function_id,
+			unsigned long arg0, unsigned long arg1,
+			unsigned long arg2)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+	return res.a0;
+}
+
+static int psci_bind(struct udevice *dev)
+{
+	/* No SYSTEM_RESET support for PSCI 0.1 */
+	if (of_device_is_compatible(dev, "arm,psci-0.2") ||
+	    of_device_is_compatible(dev, "arm,psci-1.0")) {
+		int ret;
+
+		/* bind psci-sysreset optionally */
+		ret = device_bind_driver(dev, "psci-sysreset", "psci-sysreset",
+					 NULL);
+		if (ret)
+			debug("PSCI System Reset was not bound.\n");
+	}
+
+	return 0;
+}
+
+static int psci_probe(struct udevice *dev)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	const char *method;
+
+	method = fdt_stringlist_get(gd->fdt_blob, dev->of_offset, "method", 0,
+				    NULL);
+	if (!method) {
+		printf("missing \"method\" property\n");
+		return -ENXIO;
+	}
+
+	if (!strcmp("hvc", method)) {
+		invoke_psci_fn = __invoke_psci_fn_hvc;
+	} else if (!strcmp("smc", method)) {
+		invoke_psci_fn = __invoke_psci_fn_smc;
+	} else {
+		printf("invalid \"method\" property: %s\n", method);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id psci_of_match[] = {
+	{ .compatible = "arm,psci" },
+	{ .compatible = "arm,psci-0.2" },
+	{ .compatible = "arm,psci-1.0" },
+	{},
+};
+
+U_BOOT_DRIVER(psci) = {
+	.name = "psci",
+	.id = UCLASS_FIRMWARE,
+	.of_match = psci_of_match,
+	.bind = psci_bind,
+	.probe = psci_probe,
+};
diff --git a/drivers/fpga/ivm_core.c b/drivers/fpga/ivm_core.c
index 03aea62..78e9cc4 100644
--- a/drivers/fpga/ivm_core.c
+++ b/drivers/fpga/ivm_core.c
@@ -3142,7 +3142,7 @@
 	}
 
 #ifdef DEBUG
-	printf(");\n", a_usLVDSCount);
+	printf(");\n");
 #endif /* DEBUG */
 
 	return 0;
diff --git a/drivers/i2c/rk_i2c.c b/drivers/i2c/rk_i2c.c
index af925ce..76f41f7 100644
--- a/drivers/i2c/rk_i2c.c
+++ b/drivers/i2c/rk_i2c.c
@@ -383,6 +383,7 @@
 	{ .compatible = "rockchip,rk3066-i2c" },
 	{ .compatible = "rockchip,rk3188-i2c" },
 	{ .compatible = "rockchip,rk3288-i2c" },
+	{ .compatible = "rockchip,rk3399-i2c" },
 	{ }
 };
 
diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
index 609b1fa..309372a 100644
--- a/drivers/led/Kconfig
+++ b/drivers/led/Kconfig
@@ -9,6 +9,15 @@
 	  can provide access to board-specific LEDs. Use of the device tree
 	  for configuration is encouraged.
 
+config LED_BLINK
+	bool "Support LED blinking"
+	depends on LED
+	help
+	  Some drivers can support automatic blinking of LEDs with a given
+	  period, without needing timers or extra code to handle the timing.
+	  This option enables support for this which adds slightly to the
+	  code size.
+
 config SPL_LED
 	bool "Enable LED support in SPL"
 	depends on SPL && SPL_DM
@@ -17,6 +26,7 @@
 	  If this is acceptable and you have a need to use LEDs in SPL,
 	  enable this option. You will need to enable device tree in SPL
 	  for this to work.
+
 config LED_GPIO
 	bool "LED support for GPIO-connected LEDs"
 	depends on LED && DM_GPIO
diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c
index 784ac87..78ab760 100644
--- a/drivers/led/led-uclass.c
+++ b/drivers/led/led-uclass.c
@@ -22,7 +22,7 @@
 	if (ret)
 		return ret;
 	uclass_foreach_dev(dev, uc) {
-		struct led_uclass_plat *uc_plat = dev_get_uclass_platdata(dev);
+		struct led_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
 
 		/* Ignore the top-level LED node */
 		if (uc_plat->label && !strcmp(label, uc_plat->label))
@@ -32,18 +32,40 @@
 	return -ENODEV;
 }
 
-int led_set_on(struct udevice *dev, int on)
+int led_set_state(struct udevice *dev, enum led_state_t state)
 {
 	struct led_ops *ops = led_get_ops(dev);
 
-	if (!ops->set_on)
+	if (!ops->set_state)
 		return -ENOSYS;
 
-	return ops->set_on(dev, on);
+	return ops->set_state(dev, state);
 }
 
+enum led_state_t led_get_state(struct udevice *dev)
+{
+	struct led_ops *ops = led_get_ops(dev);
+
+	if (!ops->get_state)
+		return -ENOSYS;
+
+	return ops->get_state(dev);
+}
+
+#ifdef CONFIG_LED_BLINK
+int led_set_period(struct udevice *dev, int period_ms)
+{
+	struct led_ops *ops = led_get_ops(dev);
+
+	if (!ops->set_period)
+		return -ENOSYS;
+
+	return ops->set_period(dev, period_ms);
+}
+#endif
+
 UCLASS_DRIVER(led) = {
 	.id		= UCLASS_LED,
 	.name		= "led",
-	.per_device_platdata_auto_alloc_size = sizeof(struct led_uclass_plat),
+	.per_device_platdata_auto_alloc_size = sizeof(struct led_uc_plat),
 };
diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c
index 5b11990..4106ecb 100644
--- a/drivers/led/led_gpio.c
+++ b/drivers/led/led_gpio.c
@@ -18,19 +18,47 @@
 	struct gpio_desc gpio;
 };
 
-static int gpio_led_set_on(struct udevice *dev, int on)
+static int gpio_led_set_state(struct udevice *dev, enum led_state_t state)
 {
 	struct led_gpio_priv *priv = dev_get_priv(dev);
+	int ret;
 
 	if (!dm_gpio_is_valid(&priv->gpio))
 		return -EREMOTEIO;
+	switch (state) {
+	case LEDST_OFF:
+	case LEDST_ON:
+		break;
+	case LEDST_TOGGLE:
+		ret = dm_gpio_get_value(&priv->gpio);
+		if (ret < 0)
+			return ret;
+		state = !ret;
+		break;
+	default:
+		return -ENOSYS;
+	}
 
-	return dm_gpio_set_value(&priv->gpio, on);
+	return dm_gpio_set_value(&priv->gpio, state);
+}
+
+static enum led_state_t gpio_led_get_state(struct udevice *dev)
+{
+	struct led_gpio_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	if (!dm_gpio_is_valid(&priv->gpio))
+		return -EREMOTEIO;
+	ret = dm_gpio_get_value(&priv->gpio);
+	if (ret < 0)
+		return ret;
+
+	return ret ? LEDST_ON : LEDST_OFF;
 }
 
 static int led_gpio_probe(struct udevice *dev)
 {
-	struct led_uclass_plat *uc_plat = dev_get_uclass_platdata(dev);
+	struct led_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
 	struct led_gpio_priv *priv = dev_get_priv(dev);
 
 	/* Ignore the top-level LED node */
@@ -65,7 +93,7 @@
 	for (node = fdt_first_subnode(blob, dev_of_offset(parent));
 	     node > 0;
 	     node = fdt_next_subnode(blob, node)) {
-		struct led_uclass_plat *uc_plat;
+		struct led_uc_plat *uc_plat;
 		const char *label;
 
 		label = fdt_getprop(blob, node, "label", NULL);
@@ -87,7 +115,8 @@
 }
 
 static const struct led_ops gpio_led_ops = {
-	.set_on		= gpio_led_set_on,
+	.set_state	= gpio_led_set_state,
+	.get_state	= gpio_led_get_state,
 };
 
 static const struct udevice_id led_gpio_ids[] = {
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index a61a9e9..de91f14 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -14,7 +14,6 @@
 endif
 
 obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
-obj-$(CONFIG_BFIN_SDH) += bfin_sdh.o
 obj-$(CONFIG_MMC_DAVINCI)		+= davinci_mmc.o
 
 obj-$(CONFIG_MMC_DW)			+= dw_mmc.o
diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c
deleted file mode 100644
index 1627dca..0000000
--- a/drivers/mmc/bfin_sdh.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Driver for Blackfin on-chip SDH controller
- *
- * Copyright (c) 2008-2009 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <malloc.h>
-#include <part.h>
-#include <mmc.h>
-
-#include <asm/io.h>
-#include <linux/errno.h>
-#include <asm/byteorder.h>
-#include <asm/blackfin.h>
-#include <asm/clock.h>
-#include <asm/portmux.h>
-#include <asm/mach-common/bits/sdh.h>
-#include <asm/mach-common/bits/dma.h>
-
-#if defined(__ADSPBF50x__) || defined(__ADSPBF51x__) || defined(__ADSPBF60x__)
-# define bfin_read_SDH_CLK_CTL		bfin_read_RSI_CLK_CONTROL
-# define bfin_write_SDH_CLK_CTL		bfin_write_RSI_CLK_CONTROL
-# define bfin_write_SDH_ARGUMENT	bfin_write_RSI_ARGUMENT
-# define bfin_write_SDH_COMMAND		bfin_write_RSI_COMMAND
-# define bfin_read_SDH_RESPONSE0	bfin_read_RSI_RESPONSE0
-# define bfin_read_SDH_RESPONSE1	bfin_read_RSI_RESPONSE1
-# define bfin_read_SDH_RESPONSE2	bfin_read_RSI_RESPONSE2
-# define bfin_read_SDH_RESPONSE3	bfin_read_RSI_RESPONSE3
-# define bfin_write_SDH_DATA_TIMER	bfin_write_RSI_DATA_TIMER
-# define bfin_write_SDH_DATA_LGTH	bfin_write_RSI_DATA_LGTH
-# define bfin_read_SDH_DATA_CTL		bfin_read_RSI_DATA_CONTROL
-# define bfin_write_SDH_DATA_CTL	bfin_write_RSI_DATA_CONTROL
-# define bfin_read_SDH_STATUS		bfin_read_RSI_STATUS
-# define bfin_write_SDH_STATUS_CLR 	bfin_write_RSI_STATUSCL
-# define bfin_read_SDH_CFG		bfin_read_RSI_CONFIG
-# define bfin_write_SDH_CFG		bfin_write_RSI_CONFIG
-# if defined(__ADSPBF60x__)
-# define bfin_read_SDH_BLK_SIZE		bfin_read_RSI_BLKSZ
-# define bfin_write_SDH_BLK_SIZE	bfin_write_RSI_BLKSZ
-# define bfin_write_DMA_START_ADDR	bfin_write_DMA10_START_ADDR
-# define bfin_write_DMA_X_COUNT		bfin_write_DMA10_X_COUNT
-# define bfin_write_DMA_X_MODIFY	bfin_write_DMA10_X_MODIFY
-# define bfin_write_DMA_CONFIG		bfin_write_DMA10_CONFIG
-# else
-# define bfin_read_SDH_PWR_CTL		bfin_read_RSI_PWR_CONTROL
-# define bfin_write_SDH_PWR_CTL		bfin_write_RSI_PWR_CONTROL
-# define bfin_write_DMA_START_ADDR	bfin_write_DMA4_START_ADDR
-# define bfin_write_DMA_X_COUNT		bfin_write_DMA4_X_COUNT
-# define bfin_write_DMA_X_MODIFY	bfin_write_DMA4_X_MODIFY
-# define bfin_write_DMA_CONFIG		bfin_write_DMA4_CONFIG
-# endif
-# define PORTMUX_PINS \
-	{ P_RSI_DATA0, P_RSI_DATA1, P_RSI_DATA2, P_RSI_DATA3, P_RSI_CMD, P_RSI_CLK, 0 }
-#elif defined(__ADSPBF54x__)
-# define bfin_write_DMA_START_ADDR	bfin_write_DMA22_START_ADDR
-# define bfin_write_DMA_X_COUNT		bfin_write_DMA22_X_COUNT
-# define bfin_write_DMA_X_MODIFY	bfin_write_DMA22_X_MODIFY
-# define bfin_write_DMA_CONFIG		bfin_write_DMA22_CONFIG
-# define PORTMUX_PINS \
-	{ P_SD_D0, P_SD_D1, P_SD_D2, P_SD_D3, P_SD_CLK, P_SD_CMD, 0 }
-#else
-# error no support for this proc yet
-#endif
-
-static int
-sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
-{
-	unsigned int status, timeout;
-	int cmd = mmc_cmd->cmdidx;
-	int flags = mmc_cmd->resp_type;
-	int arg = mmc_cmd->cmdarg;
-	int ret;
-	u16 sdh_cmd;
-
-	sdh_cmd = cmd | CMD_E;
-	if (flags & MMC_RSP_PRESENT)
-		sdh_cmd |= CMD_RSP;
-	if (flags & MMC_RSP_136)
-		sdh_cmd |= CMD_L_RSP;
-#ifdef RSI_BLKSZ
-	sdh_cmd |= CMD_DATA0_BUSY;
-#endif
-
-	bfin_write_SDH_ARGUMENT(arg);
-	bfin_write_SDH_COMMAND(sdh_cmd);
-
-	/* wait for a while */
-	timeout = 0;
-	do {
-		if (++timeout > 1000000) {
-			status = CMD_TIME_OUT;
-			break;
-		}
-		udelay(1);
-		status = bfin_read_SDH_STATUS();
-	} while (!(status & (CMD_SENT | CMD_RESP_END | CMD_TIME_OUT |
-		CMD_CRC_FAIL)));
-
-	if (flags & MMC_RSP_PRESENT) {
-		mmc_cmd->response[0] = bfin_read_SDH_RESPONSE0();
-		if (flags & MMC_RSP_136) {
-			mmc_cmd->response[1] = bfin_read_SDH_RESPONSE1();
-			mmc_cmd->response[2] = bfin_read_SDH_RESPONSE2();
-			mmc_cmd->response[3] = bfin_read_SDH_RESPONSE3();
-		}
-	}
-
-	if (status & CMD_TIME_OUT)
-		ret = -ETIMEDOUT;
-	else if (status & CMD_CRC_FAIL && flags & MMC_RSP_CRC)
-		ret = -ECOMM;
-	else
-		ret = 0;
-
-	bfin_write_SDH_STATUS_CLR(CMD_SENT_STAT | CMD_RESP_END_STAT |
-				CMD_TIMEOUT_STAT | CMD_CRC_FAIL_STAT);
-#ifdef RSI_BLKSZ
-	/* wait till card ready */
-	while (!(bfin_read_RSI_ESTAT() & SD_CARD_READY))
-		continue;
-	bfin_write_RSI_ESTAT(SD_CARD_READY);
-#endif
-
-	return ret;
-}
-
-/* set data for single block transfer */
-static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data)
-{
-	u16 data_ctl = 0;
-	u16 dma_cfg = 0;
-	unsigned long data_size = data->blocksize * data->blocks;
-
-	/* Don't support write yet. */
-	if (data->flags & MMC_DATA_WRITE)
-		return -EOPNOTSUPP;
-#ifndef RSI_BLKSZ
-	data_ctl |= ((ffs(data->blocksize) - 1) << 4);
-#else
-	bfin_write_SDH_BLK_SIZE(data->blocksize);
-#endif
-	data_ctl |= DTX_DIR;
-	bfin_write_SDH_DATA_CTL(data_ctl);
-	dma_cfg = WDSIZE_32 | PSIZE_32 | RESTART | WNR | DMAEN;
-
-	bfin_write_SDH_DATA_TIMER(-1);
-
-	blackfin_dcache_flush_invalidate_range(data->dest,
-			data->dest + data_size);
-	/* configure DMA */
-	bfin_write_DMA_START_ADDR(data->dest);
-	bfin_write_DMA_X_COUNT(data_size / 4);
-	bfin_write_DMA_X_MODIFY(4);
-	bfin_write_DMA_CONFIG(dma_cfg);
-	bfin_write_SDH_DATA_LGTH(data_size);
-	/* kick off transfer */
-	bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E);
-
-	return 0;
-}
-
-
-static int bfin_sdh_request(struct mmc *mmc, struct mmc_cmd *cmd,
-		struct mmc_data *data)
-{
-	u32 status;
-	int ret = 0;
-
-	if (data) {
-		ret = sdh_setup_data(mmc, data);
-		if (ret)
-			return ret;
-	}
-
-	ret = sdh_send_cmd(mmc, cmd);
-	if (ret) {
-		bfin_write_SDH_COMMAND(0);
-		bfin_write_DMA_CONFIG(0);
-		bfin_write_SDH_DATA_CTL(0);
-		SSYNC();
-		printf("sending CMD%d failed\n", cmd->cmdidx);
-		return ret;
-	}
-
-	if (data) {
-		do {
-			udelay(1);
-			status = bfin_read_SDH_STATUS();
-		} while (!(status & (DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL |
-			 RX_OVERRUN)));
-
-		if (status & DAT_TIME_OUT) {
-			bfin_write_SDH_STATUS_CLR(DAT_TIMEOUT_STAT);
-			ret = -ETIMEDOUT;
-		} else if (status & (DAT_CRC_FAIL | RX_OVERRUN)) {
-			bfin_write_SDH_STATUS_CLR(DAT_CRC_FAIL_STAT | RX_OVERRUN_STAT);
-			ret = -ECOMM;
-		} else
-			bfin_write_SDH_STATUS_CLR(DAT_BLK_END_STAT | DAT_END_STAT);
-
-		if (ret) {
-			printf("tranfering data failed\n");
-			return ret;
-		}
-	}
-	return 0;
-}
-
-static void sdh_set_clk(unsigned long clk)
-{
-	unsigned long sys_clk;
-	unsigned long clk_div;
-	u16 clk_ctl = 0;
-
-	clk_ctl = bfin_read_SDH_CLK_CTL();
-	if (clk) {
-		/* setting SD_CLK */
-		sys_clk = get_sclk();
-		bfin_write_SDH_CLK_CTL(clk_ctl & ~CLK_E);
-		if (sys_clk % (2 * clk) == 0)
-			clk_div = sys_clk / (2 * clk) - 1;
-		else
-			clk_div = sys_clk / (2 * clk);
-
-		if (clk_div > 0xff)
-			clk_div = 0xff;
-		clk_ctl |= (clk_div & 0xff);
-		clk_ctl |= CLK_E;
-		bfin_write_SDH_CLK_CTL(clk_ctl);
-	} else
-		bfin_write_SDH_CLK_CTL(clk_ctl & ~CLK_E);
-}
-
-static int bfin_sdh_set_ios(struct mmc *mmc)
-{
-	u16 cfg = 0;
-	u16 clk_ctl = 0;
-
-	if (mmc->bus_width == 4) {
-		cfg = bfin_read_SDH_CFG();
-#ifndef RSI_BLKSZ
-		cfg &= ~PD_SDDAT3;
-#endif
-		cfg |= PUP_SDDAT3;
-		bfin_write_SDH_CFG(cfg);
-		clk_ctl |= WIDE_BUS_4;
-	}
-	bfin_write_SDH_CLK_CTL(clk_ctl);
-	sdh_set_clk(mmc->clock);
-
-	return 0;
-}
-
-static int bfin_sdh_init(struct mmc *mmc)
-{
-	const unsigned short pins[] = PORTMUX_PINS;
-	int ret;
-
-	/* Initialize sdh controller */
-	ret = peripheral_request_list(pins, "bfin_sdh");
-	if (ret < 0)
-		return ret;
-#if defined(__ADSPBF54x__)
-	bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);
-#endif
-	bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);
-	/* Disable card detect pin */
-	bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | 0x60);
-#ifndef RSI_BLKSZ
-	bfin_write_SDH_PWR_CTL(PWR_ON | ROD_CTL);
-#else
-	bfin_write_SDH_CFG(bfin_read_SDH_CFG() | PWR_ON);
-#endif
-	return 0;
-}
-
-static const struct mmc_ops bfin_mmc_ops = {
-	.send_cmd	= bfin_sdh_request,
-	.set_ios	= bfin_sdh_set_ios,
-	.init		= bfin_sdh_init,
-};
-
-static struct mmc_config bfin_mmc_cfg = {
-	.name		= "Blackfin SDH",
-	.ops		= &bfin_mmc_ops,
-	.host_caps	= MMC_MODE_4BIT,
-	.voltages	= MMC_VDD_32_33 | MMC_VDD_33_34,
-	.b_max		= CONFIG_SYS_MMC_MAX_BLK_COUNT,
-};
-
-int bfin_mmc_init(bd_t *bis)
-{
-	struct mmc *mmc;
-
-	bfin_mmc_cfg.f_max = get_sclk();
-	bfin_mmc_cfg.f_min = bfin_mmc_cfg.f_max >> 9;
-
-	mmc = mmc_create(&bfin_mmc_cfg, NULL);
-	if (mmc == NULL)
-		return -1;
-
-	return 0;
-}
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index fd4bb66..82358f6 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -42,7 +42,6 @@
 
 obj-$(CONFIG_NAND_ATMEL) += atmel_nand.o
 obj-$(CONFIG_NAND_ARASAN) += arasan_nfc.o
-obj-$(CONFIG_DRIVER_NAND_BFIN) += bfin_nand.o
 obj-$(CONFIG_NAND_DAVINCI) += davinci_nand.o
 obj-$(CONFIG_NAND_DENALI) += denali.o
 obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
diff --git a/drivers/mtd/nand/bfin_nand.c b/drivers/mtd/nand/bfin_nand.c
deleted file mode 100644
index 7c11868..0000000
--- a/drivers/mtd/nand/bfin_nand.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Driver for Blackfin on-chip NAND controller.
- *
- * Enter bugs at http://blackfin.uclinux.org/
- *
- * Copyright (c) 2007-2008 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-/* TODO:
- * - move bit defines into mach-common/bits/nand.h
- * - try and replace all IRQSTAT usage with STAT polling
- * - have software ecc mode use same algo as hw ecc ?
- */
-
-#include <common.h>
-#include <console.h>
-#include <asm/io.h>
-
-#ifdef DEBUG
-# define pr_stamp() printf("%s:%s:%i: here i am\n", __FILE__, __func__, __LINE__)
-#else
-# define pr_stamp()
-#endif
-
-#include <nand.h>
-
-#include <asm/blackfin.h>
-#include <asm/portmux.h>
-
-/* Bit masks for NFC_CTL */
-
-#define                    WR_DLY  0xf        /* Write Strobe Delay */
-#define                    RD_DLY  0xf0       /* Read Strobe Delay */
-#define                    NWIDTH  0x100      /* NAND Data Width */
-#define                   PG_SIZE  0x200      /* Page Size */
-
-/* Bit masks for NFC_STAT */
-
-#define                     NBUSY  0x1        /* Not Busy */
-#define                   WB_FULL  0x2        /* Write Buffer Full */
-#define                PG_WR_STAT  0x4        /* Page Write Pending */
-#define                PG_RD_STAT  0x8        /* Page Read Pending */
-#define                  WB_EMPTY  0x10       /* Write Buffer Empty */
-
-/* Bit masks for NFC_IRQSTAT */
-
-#define                  NBUSYIRQ  0x1        /* Not Busy IRQ */
-#define                    WB_OVF  0x2        /* Write Buffer Overflow */
-#define                   WB_EDGE  0x4        /* Write Buffer Edge Detect */
-#define                    RD_RDY  0x8        /* Read Data Ready */
-#define                   WR_DONE  0x10       /* Page Write Done */
-
-#define NAND_IS_512() (CONFIG_BFIN_NFC_CTL_VAL & 0x200)
-
-/*
- * hardware specific access to control-lines
- */
-static void bfin_nfc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
-{
-	pr_stamp();
-
-	if (cmd == NAND_CMD_NONE)
-		return;
-
-	while (bfin_read_NFC_STAT() & WB_FULL)
-		continue;
-
-	if (ctrl & NAND_CLE)
-		bfin_write_NFC_CMD(cmd);
-	else
-		bfin_write_NFC_ADDR(cmd);
-	SSYNC();
-}
-
-static int bfin_nfc_devready(struct mtd_info *mtd)
-{
-	pr_stamp();
-	return (bfin_read_NFC_STAT() & NBUSY) ? 1 : 0;
-}
-
-/*
- * PIO mode for buffer writing and reading
- */
-static void bfin_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
-{
-	pr_stamp();
-
-	int i;
-
-	/*
-	 * Data reads are requested by first writing to NFC_DATA_RD
-	* and then reading back from NFC_READ.
-	*/
-	for (i = 0; i < len; ++i) {
-		while (bfin_read_NFC_STAT() & WB_FULL)
-			if (ctrlc())
-				return;
-
-		/* Contents do not matter */
-		bfin_write_NFC_DATA_RD(0x0000);
-		SSYNC();
-
-		while (!(bfin_read_NFC_IRQSTAT() & RD_RDY))
-			if (ctrlc())
-				return;
-
-		buf[i] = bfin_read_NFC_READ();
-
-		bfin_write_NFC_IRQSTAT(RD_RDY);
-	}
-}
-
-static uint8_t bfin_nfc_read_byte(struct mtd_info *mtd)
-{
-	pr_stamp();
-
-	uint8_t val;
-	bfin_nfc_read_buf(mtd, &val, 1);
-	return val;
-}
-
-static void bfin_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
-{
-	pr_stamp();
-
-	int i;
-
-	for (i = 0; i < len; ++i) {
-		while (bfin_read_NFC_STAT() & WB_FULL)
-			if (ctrlc())
-				return;
-
-		bfin_write_NFC_DATA_WR(buf[i]);
-	}
-
-	/* Wait for the buffer to drain before we return */
-	while (!(bfin_read_NFC_STAT() & WB_EMPTY))
-		if (ctrlc())
-			return;
-}
-
-/*
- * ECC functions
- * These allow the bfin to use the controller's ECC
- * generator block to ECC the data as it passes through
- */
-
-/*
- * ECC error correction function
- */
-static int bfin_nfc_correct_data_256(struct mtd_info *mtd, u_char *dat,
-					u_char *read_ecc, u_char *calc_ecc)
-{
-	u32 syndrome[5];
-	u32 calced, stored;
-	unsigned short failing_bit, failing_byte;
-	u_char data;
-
-	pr_stamp();
-
-	calced = calc_ecc[0] | (calc_ecc[1] << 8) | (calc_ecc[2] << 16);
-	stored = read_ecc[0] | (read_ecc[1] << 8) | (read_ecc[2] << 16);
-
-	syndrome[0] = (calced ^ stored);
-
-	/*
-	 * syndrome 0: all zero
-	 * No error in data
-	 * No action
-	 */
-	if (!syndrome[0] || !calced || !stored)
-		return 0;
-
-	/*
-	 * sysdrome 0: only one bit is one
-	 * ECC data was incorrect
-	 * No action
-	 */
-	if (hweight32(syndrome[0]) == 1)
-		return 1;
-
-	syndrome[1] = (calced & 0x7FF) ^ (stored & 0x7FF);
-	syndrome[2] = (calced & 0x7FF) ^ ((calced >> 11) & 0x7FF);
-	syndrome[3] = (stored & 0x7FF) ^ ((stored >> 11) & 0x7FF);
-	syndrome[4] = syndrome[2] ^ syndrome[3];
-
-	/*
-	 * sysdrome 0: exactly 11 bits are one, each parity
-	 * and parity' pair is 1 & 0 or 0 & 1.
-	 * 1-bit correctable error
-	 * Correct the error
-	 */
-	if (hweight32(syndrome[0]) == 11 && syndrome[4] == 0x7FF) {
-		failing_bit = syndrome[1] & 0x7;
-		failing_byte = syndrome[1] >> 0x3;
-		data = *(dat + failing_byte);
-		data = data ^ (0x1 << failing_bit);
-		*(dat + failing_byte) = data;
-
-		return 0;
-	}
-
-	/*
-	 * sysdrome 0: random data
-	 * More than 1-bit error, non-correctable error
-	 * Discard data, mark bad block
-	 */
-
-	return 1;
-}
-
-static int bfin_nfc_correct_data(struct mtd_info *mtd, u_char *dat,
-					u_char *read_ecc, u_char *calc_ecc)
-{
-	int ret;
-
-	pr_stamp();
-
-	ret = bfin_nfc_correct_data_256(mtd, dat, read_ecc, calc_ecc);
-
-	/* If page size is 512, correct second 256 bytes */
-	if (NAND_IS_512()) {
-		dat += 256;
-		read_ecc += 8;
-		calc_ecc += 8;
-		ret |= bfin_nfc_correct_data_256(mtd, dat, read_ecc, calc_ecc);
-	}
-
-	return ret;
-}
-
-static void reset_ecc(void)
-{
-	bfin_write_NFC_RST(0x1);
-	while (bfin_read_NFC_RST() & 1)
-		continue;
-}
-
-static void bfin_nfc_enable_hwecc(struct mtd_info *mtd, int mode)
-{
-	reset_ecc();
-}
-
-static int bfin_nfc_calculate_ecc(struct mtd_info *mtd,
-		const u_char *dat, u_char *ecc_code)
-{
-	u16 ecc0, ecc1;
-	u32 code[2];
-	u8 *p;
-
-	pr_stamp();
-
-	/* first 4 bytes ECC code for 256 page size */
-	ecc0 = bfin_read_NFC_ECC0();
-	ecc1 = bfin_read_NFC_ECC1();
-
-	code[0] = (ecc0 & 0x7FF) | ((ecc1 & 0x7FF) << 11);
-
-	/* first 3 bytes in ecc_code for 256 page size */
-	p = (u8 *) code;
-	memcpy(ecc_code, p, 3);
-
-	/* second 4 bytes ECC code for 512 page size */
-	if (NAND_IS_512()) {
-		ecc0 = bfin_read_NFC_ECC2();
-		ecc1 = bfin_read_NFC_ECC3();
-		code[1] = (ecc0 & 0x7FF) | ((ecc1 & 0x7FF) << 11);
-
-		/* second 3 bytes in ecc_code for second 256
-		 * bytes of 512 page size
-		 */
-		p = (u8 *) (code + 1);
-		memcpy((ecc_code + 3), p, 3);
-	}
-
-	reset_ecc();
-
-	return 0;
-}
-
-#ifdef CONFIG_BFIN_NFC_BOOTROM_ECC
-# define BOOTROM_ECC 1
-#else
-# define BOOTROM_ECC 0
-#endif
-
-static uint8_t bbt_pattern[] = { 0xff };
-
-static struct nand_bbt_descr bootrom_bbt = {
-	.options = 0,
-	.offs = 63,
-	.len = 1,
-	.pattern = bbt_pattern,
-};
-
-static struct nand_ecclayout bootrom_ecclayout = {
-	.eccbytes = 24,
-	.eccpos = {
-		0x8 * 0, 0x8 * 0 + 1, 0x8 * 0 + 2,
-		0x8 * 1, 0x8 * 1 + 1, 0x8 * 1 + 2,
-		0x8 * 2, 0x8 * 2 + 1, 0x8 * 2 + 2,
-		0x8 * 3, 0x8 * 3 + 1, 0x8 * 3 + 2,
-		0x8 * 4, 0x8 * 4 + 1, 0x8 * 4 + 2,
-		0x8 * 5, 0x8 * 5 + 1, 0x8 * 5 + 2,
-		0x8 * 6, 0x8 * 6 + 1, 0x8 * 6 + 2,
-		0x8 * 7, 0x8 * 7 + 1, 0x8 * 7 + 2
-	},
-	.oobfree = {
-		{ 0x8 * 0 + 3, 5 },
-		{ 0x8 * 1 + 3, 5 },
-		{ 0x8 * 2 + 3, 5 },
-		{ 0x8 * 3 + 3, 5 },
-		{ 0x8 * 4 + 3, 5 },
-		{ 0x8 * 5 + 3, 5 },
-		{ 0x8 * 6 + 3, 5 },
-		{ 0x8 * 7 + 3, 5 },
-	}
-};
-
-/*
- * Board-specific NAND initialization. The following members of the
- * argument are board-specific (per include/linux/mtd/nand.h):
- * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
- * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
- * - cmd_ctrl: hardwarespecific function for accesing control-lines
- * - dev_ready: hardwarespecific function for  accesing device ready/busy line
- * - enable_hwecc?: function to enable (reset)  hardware ecc generator. Must
- *   only be provided if a hardware ECC is available
- * - ecc.mode: mode of ecc, see defines
- * - chip_delay: chip dependent delay for transfering data from array to
- *   read regs (tR)
- * - options: various chip options. They can partly be set to inform
- *   nand_scan about special functionality. See the defines for further
- *   explanation
- * Members with a "?" were not set in the merged testing-NAND branch,
- * so they are not set here either.
- */
-int board_nand_init(struct nand_chip *chip)
-{
-	const unsigned short pins[] = {
-		P_NAND_CE, P_NAND_RB, P_NAND_D0, P_NAND_D1, P_NAND_D2,
-		P_NAND_D3, P_NAND_D4, P_NAND_D5, P_NAND_D6, P_NAND_D7,
-		P_NAND_WE, P_NAND_RE, P_NAND_CLE, P_NAND_ALE, 0,
-	};
-
-	pr_stamp();
-
-	/* set width/ecc/timings/etc... */
-	bfin_write_NFC_CTL(CONFIG_BFIN_NFC_CTL_VAL);
-
-	/* clear interrupt status */
-	bfin_write_NFC_IRQMASK(0x0);
-	bfin_write_NFC_IRQSTAT(0xffff);
-
-	/* enable GPIO function enable register */
-	peripheral_request_list(pins, "bfin_nand");
-
-	chip->cmd_ctrl = bfin_nfc_cmd_ctrl;
-	chip->read_buf = bfin_nfc_read_buf;
-	chip->write_buf = bfin_nfc_write_buf;
-	chip->read_byte = bfin_nfc_read_byte;
-
-#ifdef CONFIG_BFIN_NFC_NO_HW_ECC
-# define ECC_HW 0
-#else
-# define ECC_HW 1
-#endif
-	if (ECC_HW) {
-		if (BOOTROM_ECC) {
-			chip->badblock_pattern = &bootrom_bbt;
-			chip->ecc.layout = &bootrom_ecclayout;
-		}
-		if (!NAND_IS_512()) {
-			chip->ecc.bytes = 3;
-			chip->ecc.size = 256;
-			chip->ecc.strength = 1;
-		} else {
-			chip->ecc.bytes = 6;
-			chip->ecc.size = 512;
-			chip->ecc.strength = 2;
-		}
-		chip->ecc.mode = NAND_ECC_HW;
-		chip->ecc.calculate = bfin_nfc_calculate_ecc;
-		chip->ecc.correct   = bfin_nfc_correct_data;
-		chip->ecc.hwctl     = bfin_nfc_enable_hwecc;
-	} else
-		chip->ecc.mode = NAND_ECC_SOFT;
-	chip->dev_ready = bfin_nfc_devready;
-	chip->chip_delay = 0;
-
-	return 0;
-}
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index ac7e07b..aedb2cc 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -13,7 +13,6 @@
 obj-$(CONFIG_DRIVER_AX88180) += ax88180.o
 obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o
 obj-$(CONFIG_BCM_SF2_ETH_GMAC) += bcm-sf2-eth-gmac.o
-obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
 obj-$(CONFIG_CALXEDA_XGMAC) += calxedaxgmac.o
 obj-$(CONFIG_CS8900) += cs8900.o
 obj-$(CONFIG_TULIP) += dc2114x.o
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
deleted file mode 100644
index 26a626b..0000000
--- a/drivers/net/bfin_mac.c
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- * Driver for Blackfin On-Chip MAC device
- *
- * Copyright (c) 2005-2008 Analog Device, Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <config.h>
-#include <net.h>
-#include <netdev.h>
-#include <command.h>
-#include <malloc.h>
-#include <miiphy.h>
-#include <linux/mdio.h>
-#include <linux/mii.h>
-
-#include <asm/blackfin.h>
-#include <asm/clock.h>
-#include <asm/portmux.h>
-#include <asm/mach-common/bits/dma.h>
-#include <asm/mach-common/bits/emac.h>
-#include <asm/mach-common/bits/pll.h>
-
-#include "bfin_mac.h"
-
-#ifndef CONFIG_PHY_ADDR
-# define CONFIG_PHY_ADDR 1
-#endif
-#ifndef CONFIG_PHY_CLOCK_FREQ
-# define CONFIG_PHY_CLOCK_FREQ 2500000
-#endif
-
-#ifdef CONFIG_POST
-#include <post.h>
-#endif
-
-#define RXBUF_BASE_ADDR		0xFF900000
-#define TXBUF_BASE_ADDR		0xFF800000
-#define TX_BUF_CNT		1
-
-#define TOUT_LOOP		1000000
-
-static ADI_ETHER_BUFFER *txbuf[TX_BUF_CNT];
-static ADI_ETHER_BUFFER *rxbuf[PKTBUFSRX];
-static u16 txIdx;		/* index of the current RX buffer */
-static u16 rxIdx;		/* index of the current TX buffer */
-
-/* DMAx_CONFIG values at DMA Restart */
-static const union {
-	u16 data;
-	ADI_DMA_CONFIG_REG reg;
-} txdmacfg = {
-	.reg = {
-		.b_DMA_EN  = 1,	/* enabled */
-		.b_WNR     = 0,	/* read from memory */
-		.b_WDSIZE  = 2,	/* wordsize is 32 bits */
-		.b_DMA2D   = 0,
-		.b_RESTART = 0,
-		.b_DI_SEL  = 0,
-		.b_DI_EN   = 0,	/* no interrupt */
-		.b_NDSIZE  = 5,	/* 5 half words is desc size */
-		.b_FLOW    = 7	/* large desc flow */
-	},
-};
-
-static int bfin_miiphy_wait(void)
-{
-	/* poll the STABUSY bit */
-	while (bfin_read_EMAC_STAADD() & STABUSY)
-		continue;
-	return 0;
-}
-
-static int bfin_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
-{
-	ushort val = 0;
-	if (bfin_miiphy_wait())
-		return 1;
-	bfin_write_EMAC_STAADD(SET_PHYAD(addr) | SET_REGAD(reg) | STABUSY);
-	if (bfin_miiphy_wait())
-		return 1;
-	val = bfin_read_EMAC_STADAT();
-	return val;
-}
-
-static int bfin_miiphy_write(struct mii_dev *bus, int addr, int devad,
-			     int reg, u16 val)
-{
-	if (bfin_miiphy_wait())
-		return 1;
-	bfin_write_EMAC_STADAT(val);
-	bfin_write_EMAC_STAADD(SET_PHYAD(addr) | SET_REGAD(reg) | STAOP | STABUSY);
-	return 0;
-}
-
-int bfin_EMAC_initialize(bd_t *bis)
-{
-	struct eth_device *dev;
-	dev = malloc(sizeof(*dev));
-	if (dev == NULL)
-		hang();
-
-	memset(dev, 0, sizeof(*dev));
-	strcpy(dev->name, "bfin_mac");
-
-	dev->iobase = 0;
-	dev->priv = 0;
-	dev->init = bfin_EMAC_init;
-	dev->halt = bfin_EMAC_halt;
-	dev->send = bfin_EMAC_send;
-	dev->recv = bfin_EMAC_recv;
-	dev->write_hwaddr = bfin_EMAC_setup_addr;
-
-	eth_register(dev);
-
-#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-	int retval;
-	struct mii_dev *mdiodev = mdio_alloc();
-	if (!mdiodev)
-		return -ENOMEM;
-	strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
-	mdiodev->read = bfin_miiphy_read;
-	mdiodev->write = bfin_miiphy_write;
-
-	retval = mdio_register(mdiodev);
-	if (retval < 0)
-		return retval;
-
-	dev->priv = mdiodev;
-#endif
-
-	return 0;
-}
-
-static int bfin_EMAC_send(struct eth_device *dev, void *packet, int length)
-{
-	int i;
-	int result = 0;
-
-	if (length <= 0) {
-		printf("Ethernet: bad packet size: %d\n", length);
-		goto out;
-	}
-
-	if (bfin_read_DMA2_IRQ_STATUS() & DMA_ERR) {
-		printf("Ethernet: tx DMA error\n");
-		goto out;
-	}
-
-	for (i = 0; (bfin_read_DMA2_IRQ_STATUS() & DMA_RUN); ++i) {
-		if (i > TOUT_LOOP) {
-			puts("Ethernet: tx time out\n");
-			goto out;
-		}
-	}
-	txbuf[txIdx]->FrmData->NoBytes = length;
-	memcpy(txbuf[txIdx]->FrmData->Dest, (void *)packet, length);
-	txbuf[txIdx]->Dma[0].START_ADDR = (u32) txbuf[txIdx]->FrmData;
-	bfin_write_DMA2_NEXT_DESC_PTR(txbuf[txIdx]->Dma);
-	bfin_write_DMA2_CONFIG(txdmacfg.data);
-	bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);
-
-	for (i = 0; (txbuf[txIdx]->StatusWord & TX_COMP) == 0; i++) {
-		if (i > TOUT_LOOP) {
-			puts("Ethernet: tx error\n");
-			goto out;
-		}
-	}
-	result = txbuf[txIdx]->StatusWord;
-	txbuf[txIdx]->StatusWord = 0;
-	if ((txIdx + 1) >= TX_BUF_CNT)
-		txIdx = 0;
-	else
-		txIdx++;
- out:
-	debug("BFIN EMAC send: length = %d\n", length);
-	return result;
-}
-
-static int bfin_EMAC_recv(struct eth_device *dev)
-{
-	int length = 0;
-
-	for (;;) {
-		if ((rxbuf[rxIdx]->StatusWord & RX_COMP) == 0) {
-			length = -1;
-			break;
-		}
-		if ((rxbuf[rxIdx]->StatusWord & RX_DMAO) != 0) {
-			printf("Ethernet: rx dma overrun\n");
-			break;
-		}
-		if ((rxbuf[rxIdx]->StatusWord & RX_OK) == 0) {
-			printf("Ethernet: rx error\n");
-			break;
-		}
-		length = rxbuf[rxIdx]->StatusWord & 0x000007FF;
-		if (length <= 4) {
-			printf("Ethernet: bad frame\n");
-			break;
-		}
-
-		debug("%s: len = %d\n", __func__, length - 4);
-
-		net_rx_packets[rxIdx] = rxbuf[rxIdx]->FrmData->Dest;
-		net_process_received_packet(net_rx_packets[rxIdx], length - 4);
-		bfin_write_DMA1_IRQ_STATUS(DMA_DONE | DMA_ERR);
-		rxbuf[rxIdx]->StatusWord = 0x00000000;
-		if ((rxIdx + 1) >= PKTBUFSRX)
-			rxIdx = 0;
-		else
-			rxIdx++;
-	}
-
-	return length;
-}
-
-/**************************************************************
- *
- * Ethernet Initialization Routine
- *
- *************************************************************/
-
-/* MDC = SCLK / MDC_freq / 2 - 1 */
-#define MDC_FREQ_TO_DIV(mdc_freq) (get_sclk() / (mdc_freq) / 2 - 1)
-
-#ifndef CONFIG_BFIN_MAC_PINS
-# ifdef CONFIG_RMII
-#  define CONFIG_BFIN_MAC_PINS P_RMII0
-# else
-#  define CONFIG_BFIN_MAC_PINS P_MII0
-# endif
-#endif
-
-static int bfin_miiphy_init(struct eth_device *dev, int *opmode)
-{
-	const unsigned short pins[] = CONFIG_BFIN_MAC_PINS;
-	int phydat;
-	size_t count;
-	struct mii_dev *mdiodev = dev->priv;
-
-	/* Enable PHY output */
-	bfin_write_VR_CTL(bfin_read_VR_CTL() | CLKBUFOE);
-
-	/* Set all the pins to peripheral mode */
-	peripheral_request_list(pins, "bfin_mac");
-
-	/* Odd word alignment for Receive Frame DMA word */
-	/* Configure checksum support and rcve frame word alignment */
-	bfin_write_EMAC_SYSCTL(RXDWA | RXCKS | SET_MDCDIV(MDC_FREQ_TO_DIV(CONFIG_PHY_CLOCK_FREQ)));
-
-	/* turn on auto-negotiation and wait for link to come up */
-	bfin_miiphy_write(mdiodev, CONFIG_PHY_ADDR, MDIO_DEVAD_NONE, MII_BMCR,
-			  BMCR_ANENABLE);
-	count = 0;
-	while (1) {
-		++count;
-		phydat = bfin_miiphy_read(mdiodev, CONFIG_PHY_ADDR,
-					  MDIO_DEVAD_NONE, MII_BMSR);
-		if (phydat < 0)
-			return phydat;
-		if (phydat & BMSR_LSTATUS)
-			break;
-		if (count > 30000) {
-			printf("%s: link down, check cable\n", dev->name);
-			return -1;
-		}
-		udelay(100);
-	}
-
-	/* see what kind of link we have */
-	phydat = bfin_miiphy_read(mdiodev, CONFIG_PHY_ADDR, MDIO_DEVAD_NONE,
-				  MII_LPA);
-	if (phydat < 0)
-		return phydat;
-	if (phydat & LPA_DUPLEX)
-		*opmode = FDMODE;
-	else
-		*opmode = 0;
-
-	bfin_write_EMAC_MMC_CTL(RSTC | CROLL);
-	bfin_write_EMAC_VLAN1(EMAC_VLANX_DEF_VAL);
-	bfin_write_EMAC_VLAN2(EMAC_VLANX_DEF_VAL);
-
-	/* Initialize the TX DMA channel registers */
-	bfin_write_DMA2_X_COUNT(0);
-	bfin_write_DMA2_X_MODIFY(4);
-	bfin_write_DMA2_Y_COUNT(0);
-	bfin_write_DMA2_Y_MODIFY(0);
-
-	/* Initialize the RX DMA channel registers */
-	bfin_write_DMA1_X_COUNT(0);
-	bfin_write_DMA1_X_MODIFY(4);
-	bfin_write_DMA1_Y_COUNT(0);
-	bfin_write_DMA1_Y_MODIFY(0);
-
-	return 0;
-}
-
-static int bfin_EMAC_setup_addr(struct eth_device *dev)
-{
-	bfin_write_EMAC_ADDRLO(
-		dev->enetaddr[0] |
-		dev->enetaddr[1] << 8 |
-		dev->enetaddr[2] << 16 |
-		dev->enetaddr[3] << 24
-	);
-	bfin_write_EMAC_ADDRHI(
-		dev->enetaddr[4] |
-		dev->enetaddr[5] << 8
-	);
-	return 0;
-}
-
-static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd)
-{
-	u32 opmode;
-	int dat;
-	int i;
-	debug("Eth_init: ......\n");
-
-	txIdx = 0;
-	rxIdx = 0;
-
-	/* Initialize System Register */
-	if (bfin_miiphy_init(dev, &dat) < 0)
-		return -1;
-
-	/* Initialize EMAC address */
-	bfin_EMAC_setup_addr(dev);
-
-	/* Initialize TX and RX buffer */
-	for (i = 0; i < PKTBUFSRX; i++) {
-		rxbuf[i] = SetupRxBuffer(i);
-		if (i > 0) {
-			rxbuf[i - 1]->Dma[1].NEXT_DESC_PTR = rxbuf[i]->Dma;
-			if (i == (PKTBUFSRX - 1))
-				rxbuf[i]->Dma[1].NEXT_DESC_PTR = rxbuf[0]->Dma;
-		}
-	}
-	for (i = 0; i < TX_BUF_CNT; i++) {
-		txbuf[i] = SetupTxBuffer(i);
-		if (i > 0) {
-			txbuf[i - 1]->Dma[1].NEXT_DESC_PTR = txbuf[i]->Dma;
-			if (i == (TX_BUF_CNT - 1))
-				txbuf[i]->Dma[1].NEXT_DESC_PTR = txbuf[0]->Dma;
-		}
-	}
-
-	/* Set RX DMA */
-	bfin_write_DMA1_NEXT_DESC_PTR(rxbuf[0]->Dma);
-	bfin_write_DMA1_CONFIG(rxbuf[0]->Dma[0].CONFIG_DATA);
-
-	/* Wait MII done */
-	bfin_miiphy_wait();
-
-	/* We enable only RX here */
-	/* ASTP   : Enable Automatic Pad Stripping
-	   PR     : Promiscuous Mode for test
-	   PSF    : Receive frames with total length less than 64 bytes.
-	   FDMODE : Full Duplex Mode
-	   LB	  : Internal Loopback for test
-	   RE     : Receiver Enable */
-	if (dat == FDMODE)
-		opmode = ASTP | FDMODE | PSF;
-	else
-		opmode = ASTP | PSF;
-	opmode |= RE;
-#ifdef CONFIG_RMII
-	opmode |= TE | RMII;
-#endif
-	/* Turn on the EMAC */
-	bfin_write_EMAC_OPMODE(opmode);
-	return 0;
-}
-
-static void bfin_EMAC_halt(struct eth_device *dev)
-{
-	debug("Eth_halt: ......\n");
-	/* Turn off the EMAC */
-	bfin_write_EMAC_OPMODE(0);
-	/* Turn off the EMAC RX DMA */
-	bfin_write_DMA1_CONFIG(0);
-	bfin_write_DMA2_CONFIG(0);
-}
-
-ADI_ETHER_BUFFER *SetupRxBuffer(int no)
-{
-	ADI_ETHER_FRAME_BUFFER *frmbuf;
-	ADI_ETHER_BUFFER *buf;
-	int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2;	/* ensure a multi. of 4 */
-	int total_size = nobytes_buffer + RECV_BUFSIZE;
-
-	buf = (void *) (RXBUF_BASE_ADDR + no * total_size);
-	frmbuf = (void *) (RXBUF_BASE_ADDR + no * total_size + nobytes_buffer);
-
-	memset(buf, 0x00, nobytes_buffer);
-	buf->FrmData = frmbuf;
-	memset(frmbuf, 0xfe, RECV_BUFSIZE);
-
-	/* set up first desc to point to receive frame buffer */
-	buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]);
-	buf->Dma[0].START_ADDR = (u32) buf->FrmData;
-	buf->Dma[0].CONFIG.b_DMA_EN = 1;	/* enabled */
-	buf->Dma[0].CONFIG.b_WNR = 1;	/* Write to memory */
-	buf->Dma[0].CONFIG.b_WDSIZE = 2;	/* wordsize is 32 bits */
-	buf->Dma[0].CONFIG.b_NDSIZE = 5;	/* 5 half words is desc size. */
-	buf->Dma[0].CONFIG.b_FLOW = 7;	/* large desc flow */
-
-	/* set up second desc to point to status word */
-	buf->Dma[1].NEXT_DESC_PTR = buf->Dma;
-	buf->Dma[1].START_ADDR = (u32) & buf->IPHdrChksum;
-	buf->Dma[1].CONFIG.b_DMA_EN = 1;	/* enabled */
-	buf->Dma[1].CONFIG.b_WNR = 1;	/* Write to memory */
-	buf->Dma[1].CONFIG.b_WDSIZE = 2;	/* wordsize is 32 bits */
-	buf->Dma[1].CONFIG.b_DI_EN = 1;	/* enable interrupt */
-	buf->Dma[1].CONFIG.b_NDSIZE = 5;	/* must be 0 when FLOW is 0 */
-	buf->Dma[1].CONFIG.b_FLOW = 7;	/* stop */
-
-	return buf;
-}
-
-ADI_ETHER_BUFFER *SetupTxBuffer(int no)
-{
-	ADI_ETHER_FRAME_BUFFER *frmbuf;
-	ADI_ETHER_BUFFER *buf;
-	int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2;	/* ensure a multi. of 4 */
-	int total_size = nobytes_buffer + RECV_BUFSIZE;
-
-	buf = (void *) (TXBUF_BASE_ADDR + no * total_size);
-	frmbuf = (void *) (TXBUF_BASE_ADDR + no * total_size + nobytes_buffer);
-
-	memset(buf, 0x00, nobytes_buffer);
-	buf->FrmData = frmbuf;
-	memset(frmbuf, 0x00, RECV_BUFSIZE);
-
-	/* set up first desc to point to receive frame buffer */
-	buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]);
-	buf->Dma[0].START_ADDR = (u32) buf->FrmData;
-	buf->Dma[0].CONFIG.b_DMA_EN = 1;	/* enabled */
-	buf->Dma[0].CONFIG.b_WNR = 0;	/* Read to memory */
-	buf->Dma[0].CONFIG.b_WDSIZE = 2;	/* wordsize is 32 bits */
-	buf->Dma[0].CONFIG.b_NDSIZE = 5;	/* 5 half words is desc size. */
-	buf->Dma[0].CONFIG.b_FLOW = 7;	/* large desc flow */
-
-	/* set up second desc to point to status word */
-	buf->Dma[1].NEXT_DESC_PTR = &(buf->Dma[0]);
-	buf->Dma[1].START_ADDR = (u32) & buf->StatusWord;
-	buf->Dma[1].CONFIG.b_DMA_EN = 1;	/* enabled */
-	buf->Dma[1].CONFIG.b_WNR = 1;	/* Write to memory */
-	buf->Dma[1].CONFIG.b_WDSIZE = 2;	/* wordsize is 32 bits */
-	buf->Dma[1].CONFIG.b_DI_EN = 1;	/* enable interrupt */
-	buf->Dma[1].CONFIG.b_NDSIZE = 0;	/* must be 0 when FLOW is 0 */
-	buf->Dma[1].CONFIG.b_FLOW = 0;	/* stop */
-
-	return buf;
-}
-
-#if defined(CONFIG_POST) && defined(CONFIG_SYS_POST_ETHER)
-int ether_post_test(int flags)
-{
-	uchar buf[64];
-	int i, value = 0;
-	int length;
-	uint addr;
-
-	printf("\n--------");
-	bfin_EMAC_init(NULL, NULL);
-	/* construct the package */
-	addr = bfin_read_EMAC_ADDRLO();
-	buf[0] = buf[6] = addr;
-	buf[1] = buf[7] = addr >> 8;
-	buf[2] = buf[8] = addr >> 16;
-	buf[3] = buf[9] = addr >> 24;
-	addr = bfin_read_EMAC_ADDRHI();
-	buf[4] = buf[10] = addr;
-	buf[5] = buf[11] = addr >> 8;
-	buf[12] = 0x08;		/* Type: ARP */
-	buf[13] = 0x06;
-	buf[14] = 0x00;		/* Hardware type: Ethernet */
-	buf[15] = 0x01;
-	buf[16] = 0x08;		/* Protocal type: IP */
-	buf[17] = 0x00;
-	buf[18] = 0x06;		/* Hardware size    */
-	buf[19] = 0x04;		/* Protocol size    */
-	buf[20] = 0x00;		/* Opcode: request  */
-	buf[21] = 0x01;
-
-	for (i = 0; i < 42; i++)
-		buf[i + 22] = i;
-	printf("--------Send 64 bytes......\n");
-	bfin_EMAC_send(NULL, buf, 64);
-	for (i = 0; i < 100; i++) {
-		udelay(10000);
-		if ((rxbuf[rxIdx]->StatusWord & RX_COMP) != 0) {
-			value = 1;
-			break;
-		}
-	}
-	if (value == 0) {
-		printf("--------EMAC can't receive any data\n");
-		eth_halt();
-		return -1;
-	}
-	length = rxbuf[rxIdx]->StatusWord & 0x000007FF - 4;
-	for (i = 0; i < length; i++) {
-		if (rxbuf[rxIdx]->FrmData->Dest[i] != buf[i]) {
-			printf("--------EMAC receive error data!\n");
-			eth_halt();
-			return -1;
-		}
-	}
-	printf("--------receive %d bytes, matched\n", length);
-	bfin_EMAC_halt(NULL);
-	return 0;
-}
-#endif
diff --git a/drivers/net/bfin_mac.h b/drivers/net/bfin_mac.h
deleted file mode 100644
index 54ffb38..0000000
--- a/drivers/net/bfin_mac.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * bfin_mac.h - some defines/structures for the Blackfin on-chip MAC.
- *
- * Copyright (c) 2005-2008 Analog Device, Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#ifndef __BFIN_MAC_H__
-#define __BFIN_MAC_H__
-
-#define RECV_BUFSIZE		(0x614)
-
-typedef struct ADI_DMA_CONFIG_REG {
-	u16 b_DMA_EN:1;		/* 0	Enabled				*/
-	u16 b_WNR:1;		/* 1	Direction			*/
-	u16 b_WDSIZE:2;		/* 2:3	Transfer word size		*/
-	u16 b_DMA2D:1;		/* 4	DMA mode			*/
-	u16 b_RESTART:1;	/* 5	Retain FIFO			*/
-	u16 b_DI_SEL:1;		/* 6	Data interrupt timing select	*/
-	u16 b_DI_EN:1;		/* 7	Data interrupt enabled		*/
-	u16 b_NDSIZE:4;		/* 8:11	Flex descriptor size		*/
-	u16 b_FLOW:3;		/* 12:14Flow				*/
-} ADI_DMA_CONFIG_REG;
-
-typedef struct adi_ether_frame_buffer {
-	u16 NoBytes;		/* the no. of following bytes	*/
-	u8 Dest[6];		/* destination MAC address	*/
-	u8 Srce[6];		/* source MAC address		*/
-	u16 LTfield;		/* length/type field		*/
-	u8 Data[0];		/* payload bytes		*/
-} ADI_ETHER_FRAME_BUFFER;
-/* 16 bytes/struct	*/
-
-typedef struct dma_descriptor {
-	struct dma_descriptor *NEXT_DESC_PTR;
-	u32 START_ADDR;
-	union {
-		u16 CONFIG_DATA;
-		ADI_DMA_CONFIG_REG CONFIG;
-	};
-} DMA_DESCRIPTOR;
-/* 10 bytes/struct in 12 bytes */
-
-typedef struct adi_ether_buffer {
-	DMA_DESCRIPTOR Dma[2];		/* first for the frame, second for the status */
-	ADI_ETHER_FRAME_BUFFER *FrmData;/* pointer to data */
-	struct adi_ether_buffer *pNext;	/* next buffer */
-	struct adi_ether_buffer *pPrev;	/* prev buffer */
-	u16 IPHdrChksum;		/* the IP header checksum */
-	u16 IPPayloadChksum;		/* the IP header and payload checksum */
-	volatile u32 StatusWord;	/* the frame status word */
-} ADI_ETHER_BUFFER;
-/* 40 bytes/struct in 44 bytes */
-
-static ADI_ETHER_BUFFER *SetupRxBuffer(int no);
-static ADI_ETHER_BUFFER *SetupTxBuffer(int no);
-
-static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd);
-static void bfin_EMAC_halt(struct eth_device *dev);
-static int bfin_EMAC_send(struct eth_device *dev, void *packet, int length);
-static int bfin_EMAC_recv(struct eth_device *dev);
-static int bfin_EMAC_setup_addr(struct eth_device *dev);
-
-#endif
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index c919427..87c3d9c 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -9,7 +9,6 @@
 obj-$(CONFIG_DM_RTC) += rtc-uclass.o
 
 obj-$(CONFIG_RTC_AT91SAM9_RTT) += at91sam9_rtt.o
-obj-$(CONFIG_RTC_BFIN) += bfin_rtc.o
 obj-y += date.o
 obj-$(CONFIG_RTC_DAVINCI) += davinci.o
 obj-$(CONFIG_RTC_DS1302) += ds1302.o
diff --git a/drivers/rtc/bfin_rtc.c b/drivers/rtc/bfin_rtc.c
deleted file mode 100644
index a079a1d..0000000
--- a/drivers/rtc/bfin_rtc.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Analog Devices Inc.
- *
- * (C) Copyright 2001
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-
-#if defined(CONFIG_CMD_DATE)
-
-#include <asm/blackfin.h>
-#include <asm/mach-common/bits/rtc.h>
-
-#define pr_stamp() debug("%s:%s:%i: here i am\n", __FILE__, __func__, __LINE__)
-
-#define MIN_TO_SECS(x)    (60 * (x))
-#define HRS_TO_SECS(x)    (60 * MIN_TO_SECS(x))
-#define DAYS_TO_SECS(x)   (24 * HRS_TO_SECS(x))
-
-#define NUM_SECS_IN_MIN   MIN_TO_SECS(1)
-#define NUM_SECS_IN_HR    HRS_TO_SECS(1)
-#define NUM_SECS_IN_DAY   DAYS_TO_SECS(1)
-
-/* Enable the RTC prescaler enable register */
-void rtc_init(void)
-{
-	if (!(bfin_read_RTC_PREN() & 0x1))
-		bfin_write_RTC_PREN(0x1);
-}
-
-/* Our on-chip RTC has no notion of "reset" */
-void rtc_reset(void)
-{
-	rtc_init();
-}
-
-/* Wait for pending writes to complete */
-static void wait_for_complete(void)
-{
-	pr_stamp();
-	while (!(bfin_read_RTC_ISTAT() & WRITE_COMPLETE))
-		if (!(bfin_read_RTC_ISTAT() & WRITE_PENDING))
-			break;
-	bfin_write_RTC_ISTAT(WRITE_COMPLETE);
-}
-
-/* Set the time. Get the time_in_secs which is the number of seconds since Jan 1970 and set the RTC registers
- * based on this value.
- */
-int rtc_set(struct rtc_time *tmp)
-{
-	unsigned long remain, days, hrs, mins, secs;
-
-	pr_stamp();
-
-	if (tmp == NULL) {
-		puts("Error setting the date/time\n");
-		return -1;
-	}
-
-	rtc_init();
-	wait_for_complete();
-
-	/* Calculate number of seconds this incoming time represents */
-	remain = rtc_mktime(tmp);
-
-	/* Figure out how many days since epoch */
-	days = remain / NUM_SECS_IN_DAY;
-
-	/* From the remaining secs, compute the hrs(0-23), mins(0-59) and secs(0-59) */
-	remain = remain % NUM_SECS_IN_DAY;
-	hrs = remain / NUM_SECS_IN_HR;
-	remain = remain % NUM_SECS_IN_HR;
-	mins = remain / NUM_SECS_IN_MIN;
-	secs = remain % NUM_SECS_IN_MIN;
-
-	/* Encode these time values into our RTC_STAT register */
-	bfin_write_RTC_STAT(SET_ALARM(days, hrs, mins, secs));
-
-	return 0;
-}
-
-/* Read the time from the RTC_STAT. time_in_seconds is seconds since Jan 1970 */
-int rtc_get(struct rtc_time *tmp)
-{
-	uint32_t cur_rtc_stat;
-	int time_in_sec;
-	int tm_sec, tm_min, tm_hr, tm_day;
-
-	pr_stamp();
-
-	if (tmp == NULL) {
-		puts("Error getting the date/time\n");
-		return -1;
-	}
-
-	rtc_init();
-	wait_for_complete();
-
-	/* Read the RTC_STAT register */
-	cur_rtc_stat = bfin_read_RTC_STAT();
-
-	/* Convert our encoded format into actual time values */
-	tm_sec = (cur_rtc_stat & RTC_SEC) >> RTC_SEC_P;
-	tm_min = (cur_rtc_stat & RTC_MIN) >> RTC_MIN_P;
-	tm_hr  = (cur_rtc_stat & RTC_HR ) >> RTC_HR_P;
-	tm_day = (cur_rtc_stat & RTC_DAY) >> RTC_DAY_P;
-
-	/* Calculate the total number of seconds since epoch */
-	time_in_sec = (tm_sec) + MIN_TO_SECS(tm_min) + HRS_TO_SECS(tm_hr) + DAYS_TO_SECS(tm_day);
-	rtc_to_tm(time_in_sec, tmp);
-
-	return 0;
-}
-
-#endif
diff --git a/drivers/serial/usbtty.c b/drivers/serial/usbtty.c
index 2e19813..29799dc 100644
--- a/drivers/serial/usbtty.c
+++ b/drivers/serial/usbtty.c
@@ -850,6 +850,13 @@
 	struct urb *current_urb = NULL;
 
 	current_urb = next_urb (device_instance, endpoint);
+
+	if (!current_urb) {
+		TTYERR ("current_urb is NULL, buf->size %d\n",
+		buf->size);
+		return 0;
+	}
+
 	/* TX data still exists - send it now
 	 */
 	if(endpoint->sent < current_urb->actual_length){
@@ -871,12 +878,6 @@
 		 */
 		while (buf->size > 0) {
 
-			if (!current_urb) {
-				TTYERR ("current_urb is NULL, buf->size %d\n",
-					buf->size);
-				return total;
-			}
-
 			dest = (char*)current_urb->buffer +
 				current_urb->actual_length;
 
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index 05a37b9..9664630 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -13,4 +13,14 @@
 	  to effect a reset. The uclass will try all available drivers when
 	  reset_walk() is called.
 
+if SYSRESET
+
+config SYSRESET_PSCI
+	bool "Enable support for PSCI System Reset"
+	depends on ARM_PSCI_FW
+	help
+	  Enable PSCI SYSTEM_RESET function call.  To use this, PSCI firmware
+	  must be running on your system.
+
+endif
 endmenu
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index 49b8bb6..7bb8406 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -5,6 +5,7 @@
 #
 
 obj-$(CONFIG_SYSRESET) += sysreset-uclass.o
+obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
 
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_ROCKCHIP_RK3036) += sysreset_rk3036.o
diff --git a/drivers/sysreset/sysreset_psci.c b/drivers/sysreset/sysreset_psci.c
new file mode 100644
index 0000000..a4911b7
--- /dev/null
+++ b/drivers/sysreset/sysreset_psci.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <dm/device.h>
+#include <sysreset.h>
+#include <linux/errno.h>
+#include <linux/psci.h>
+
+static int psci_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+	unsigned long function_id;
+
+	switch (type) {
+	case SYSRESET_WARM:
+	case SYSRESET_COLD:
+		function_id = PSCI_0_2_FN_SYSTEM_RESET;
+		break;
+	case SYSRESET_POWER:
+		function_id = PSCI_0_2_FN_SYSTEM_OFF;
+		break;
+	default:
+		return -ENOSYS;
+	}
+
+	invoke_psci_fn(function_id, 0, 0, 0);
+
+	return -EINPROGRESS;
+}
+
+static struct sysreset_ops psci_sysreset_ops = {
+	.request = psci_sysreset_request,
+};
+
+U_BOOT_DRIVER(psci_sysreset) = {
+	.name = "psci-sysreset",
+	.id = UCLASS_SYSRESET,
+	.ops = &psci_sysreset_ops,
+};
diff --git a/drivers/sysreset/sysreset_rk3188.c b/drivers/sysreset/sysreset_rk3188.c
index 36ae476..053a634 100644
--- a/drivers/sysreset/sysreset_rk3188.c
+++ b/drivers/sysreset/sysreset_rk3188.c
@@ -7,21 +7,36 @@
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
+#include <syscon.h>
 #include <sysreset.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/cru_rk3188.h>
+#include <asm/arch/grf_rk3188.h>
 #include <asm/arch/hardware.h>
 #include <linux/err.h>
 
 int rk3188_sysreset_request(struct udevice *dev, enum sysreset_t type)
 {
 	struct rk3188_cru *cru = rockchip_get_cru();
+	struct rk3188_grf *grf;
 
 	if (IS_ERR(cru))
 		return PTR_ERR(cru);
 	switch (type) {
 	case SYSRESET_WARM:
+		grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+		if (IS_ERR(grf))
+			return -EPROTONOSUPPORT;
+
+		/*
+		 * warm-reset keeps the remap value,
+		 * so make sure it's disabled.
+		 */
+		rk_clrsetreg(&grf->soc_con0,
+			NOC_REMAP_MASK << NOC_REMAP_SHIFT,
+			0 << NOC_REMAP_SHIFT);
+
 		rk_clrreg(&cru->cru_mode_con, 0xffff);
 		writel(0xeca8, &cru->cru_glb_srst_snd_value);
 		break;
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index dea1836..36745ca 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -12,7 +12,6 @@
 endif
 obj-$(CONFIG_S5P)               += s5p_wdt.o
 obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o
-obj-$(CONFIG_BFIN_WATCHDOG)  += bfin_wdt.o
 obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
 obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o
 obj-$(CONFIG_ULP_WATCHDOG) += ulp_wdog.o
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c
deleted file mode 100644
index 6a8db59..0000000
--- a/drivers/watchdog/bfin_wdt.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * watchdog.c - driver for Blackfin on-chip watchdog
- *
- * Copyright (c) 2007-2009 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <watchdog.h>
-#include <asm/blackfin.h>
-#include <asm/clock.h>
-#include <asm/mach-common/bits/watchdog.h>
-
-void hw_watchdog_reset(void)
-{
-	bfin_write_WDOG_STAT(0);
-}
-
-void hw_watchdog_init(void)
-{
-	bfin_write_WDOG_CTL(WDDIS);
-	SSYNC();
-	bfin_write_WDOG_CNT(CONFIG_WATCHDOG_TIMEOUT_MSECS / 1000 * get_sclk());
-	hw_watchdog_reset();
-	bfin_write_WDOG_CTL(WDEN);
-}
diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c
index 05ed272..228f599 100644
--- a/fs/cramfs/cramfs.c
+++ b/fs/cramfs/cramfs.c
@@ -49,6 +49,9 @@
 #define PART_OFFSET(x)	((ulong)x->offset)
 #endif
 
+static int cramfs_uncompress (unsigned long begin, unsigned long offset,
+			      unsigned long loadoffset);
+
 static int cramfs_read_super (struct part_info *info)
 {
 	unsigned long root_offset;
@@ -94,6 +97,22 @@
 	return 0;
 }
 
+/* Unpack to an allocated buffer, trusting in the inode's size field. */
+static char *cramfs_uncompress_link (unsigned long begin, unsigned long offset)
+{
+	struct cramfs_inode *inode = (struct cramfs_inode *)(begin + offset);
+	unsigned long size = CRAMFS_24 (inode->size);
+	char *link = malloc (size + 1);
+
+	if (!link || cramfs_uncompress (begin, offset, (unsigned long)link) != size) {
+		free (link);
+		link = NULL;
+	} else {
+		link[size] = '\0';
+	}
+	return link;
+}
+
 static unsigned long cramfs_resolve (unsigned long begin, unsigned long offset,
 				     unsigned long size, int raw,
 				     char *filename)
@@ -143,6 +162,33 @@
 						       p);
 			} else if (S_ISREG (CRAMFS_16 (inode->mode))) {
 				return offset + inodeoffset;
+			} else if (S_ISLNK (CRAMFS_16 (inode->mode))) {
+				unsigned long ret;
+				char *link;
+				if (p && strlen(p)) {
+					printf ("unsupported symlink to \
+						 non-terminal path\n");
+					return 0;
+				}
+				link = cramfs_uncompress_link (begin,
+						offset + inodeoffset);
+				if (!link) {
+					printf ("%*.*s: Error reading link\n",
+						namelen, namelen, name);
+					return 0;
+				} else if (link[0] == '/') {
+					printf ("unsupported symlink to \
+						 absolute path\n");
+					free (link);
+					return 0;
+				}
+				ret = cramfs_resolve (begin,
+						      offset,
+						      size,
+						      raw,
+						      strtok(link, "/"));
+				free (link);
+				return ret;
 			} else {
 				printf ("%*.*s: unsupported file type (%x)\n",
 					namelen, namelen, name,
@@ -162,7 +208,7 @@
 			      unsigned long loadoffset)
 {
 	struct cramfs_inode *inode = (struct cramfs_inode *) (begin + offset);
-	unsigned long *block_ptrs = (unsigned long *)
+	u32 *block_ptrs = (u32 *)
 		(begin + (CRAMFS_GET_OFFSET (inode) << 2));
 	unsigned long curr_block = (CRAMFS_GET_OFFSET (inode) +
 				    (((CRAMFS_24 (inode->size)) +
@@ -235,20 +281,12 @@
 		CRAMFS_24 (inode->size), namelen, namelen, name);
 
 	if ((CRAMFS_16 (inode->mode) & S_IFMT) == S_IFLNK) {
-		/* symbolic link.
-		 * Unpack the link target, trusting in the inode's size field.
-		 */
-		unsigned long size = CRAMFS_24 (inode->size);
-		char *link = malloc (size);
-
-		if (link != NULL && cramfs_uncompress (PART_OFFSET(info), offset,
-						       (unsigned long) link)
-		    == size)
-			printf (" -> %*.*s\n", (int) size, (int) size, link);
+		char *link = cramfs_uncompress_link (PART_OFFSET(info), offset);
+		if (link)
+			printf (" -> %s\n", link);
 		else
 			printf (" [Error reading link]\n");
-		if (link)
-			free (link);
+		free (link);
 	} else
 		printf ("\n");
 
diff --git a/fs/yaffs2/yaffsfs.c b/fs/yaffs2/yaffsfs.c
index 41e5f01..ba76a5c 100644
--- a/fs/yaffs2/yaffsfs.c
+++ b/fs/yaffs2/yaffsfs.c
@@ -3018,7 +3018,7 @@
 		yaffsfs_SetError(-ENFILE);
 	else if (parent->my_dev->read_only)
 		yaffsfs_SetError(-EROFS);
-	else if (parent) {
+	else {
 		obj = yaffs_create_symlink(parent, name, mode, 0, 0, oldpath);
 		if (obj)
 			retVal = 0;
diff --git a/include/configs/puma_rk3399.h b/include/configs/puma_rk3399.h
new file mode 100644
index 0000000..fd62c72
--- /dev/null
+++ b/include/configs/puma_rk3399.h
@@ -0,0 +1,27 @@
+/*
+ * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __PUMA_RK3399_H
+#define __PUMA_RK3399_H
+
+#include <configs/rk3399_common.h>
+
+/*
+ * SPL @ 32kB for ~130kB
+ * ENV @ 240KB for 8kB
+ * FIT payload (ATF, U-Boot, FDT) @ 256kB
+ */
+#undef CONFIG_ENV_OFFSET
+#define CONFIG_ENV_OFFSET (240 * 1024)
+
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV 1
+
+#define SDRAM_BANK_SIZE			(2UL << 30)
+
+#define CONFIG_SYS_WHITE_ON_BLACK
+
+#endif
diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
index 9d22e0c..b7b89b0 100644
--- a/include/configs/rk3399_common.h
+++ b/include/configs/rk3399_common.h
@@ -57,8 +57,8 @@
 #ifndef CONFIG_SPL_BUILD
 
 #define ENV_MEM_LAYOUT_SETTINGS \
-	"scriptaddr=0x00000000\0" \
-	"pxefile_addr_r=0x00100000\0" \
+	"scriptaddr=0x00500000\0" \
+	"pxefile_addr_r=0x00600000\0" \
 	"fdt_addr_r=0x01f00000\0" \
 	"kernel_addr_r=0x02000000\0" \
 	"ramdisk_addr_r=0x04000000\0"
diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h
index fd930c1..9d183ce 100644
--- a/include/configs/rockchip-common.h
+++ b/include/configs/rockchip-common.h
@@ -12,11 +12,20 @@
 #include <config_distro_defaults.h>
 
 /* First try to boot from SD (index 0), then eMMC (index 1 */
+#ifdef CONFIG_CMD_USB
+#define BOOT_TARGET_DEVICES(func) \
+	func(MMC, mmc, 0) \
+	func(MMC, mmc, 1) \
+	func(USB, usb, 0) \
+	func(PXE, pxe, na) \
+	func(DHCP, dchp, na)
+#else
 #define BOOT_TARGET_DEVICES(func) \
 	func(MMC, mmc, 0) \
 	func(MMC, mmc, 1) \
 	func(PXE, pxe, na) \
 	func(DHCP, dchp, na)
+#endif
 
 #define CONFIG_RANDOM_UUID
 #define PARTS_DEFAULT \
diff --git a/include/configs/sama5d3_xplained.h b/include/configs/sama5d3_xplained.h
index 3c9f49e..b4a62bd 100644
--- a/include/configs/sama5d3_xplained.h
+++ b/include/configs/sama5d3_xplained.h
@@ -12,11 +12,6 @@
 
 #include "at91-sama5_common.h"
 
-/* serial console */
-#define CONFIG_ATMEL_USART
-#define CONFIG_USART_BASE		ATMEL_BASE_DBGU
-#define CONFIG_USART_ID			ATMEL_ID_DBGU
-
 /*
  * This needs to be defined for the OHCI code to work but it is defined as
  * ATMEL_ID_UHPHS in the CPU specific header files.
@@ -34,10 +29,10 @@
 #define CONFIG_SYS_SDRAM_SIZE		0x10000000
 
 #ifdef CONFIG_SPL_BUILD
-#define CONFIG_SYS_INIT_SP_ADDR		0x310000
+#define CONFIG_SYS_INIT_SP_ADDR		0x318000
 #else
 #define CONFIG_SYS_INIT_SP_ADDR \
-	(CONFIG_SYS_SDRAM_BASE + 4 * 1024 - GENERATED_GBL_DATA_SIZE)
+	(CONFIG_SYS_SDRAM_BASE + 16 * 1024 - GENERATED_GBL_DATA_SIZE)
 #endif
 
 /* NAND flash */
@@ -67,21 +62,6 @@
 #define CONFIG_CMD_UBIFS
 #endif
 
-/* Ethernet Hardware */
-#define CONFIG_MACB
-#define CONFIG_RMII
-#define CONFIG_NET_RETRY_COUNT		20
-#define CONFIG_MACB_SEARCH_PHY
-#define CONFIG_RGMII
-#define CONFIG_PHYLIB
-
-/* MMC */
-
-#ifdef CONFIG_CMD_MMC
-#define CONFIG_GENERIC_ATMEL_MCI
-#define CONFIG_ATMEL_MCI_8BIT
-#endif
-
 /* USB */
 
 #ifdef CONFIG_CMD_USB
@@ -111,7 +91,7 @@
 /* SPL */
 #define CONFIG_SPL_FRAMEWORK
 #define CONFIG_SPL_TEXT_BASE		0x300000
-#define CONFIG_SPL_MAX_SIZE		0x10000
+#define CONFIG_SPL_MAX_SIZE		0x18000
 #define CONFIG_SPL_BSS_START_ADDR	0x20000000
 #define CONFIG_SPL_BSS_MAX_SIZE		0x80000
 #define CONFIG_SYS_SPL_MALLOC_START	0x20080000
diff --git a/include/configs/sama5d3xek.h b/include/configs/sama5d3xek.h
index 13790e7..6c28c4c 100644
--- a/include/configs/sama5d3xek.h
+++ b/include/configs/sama5d3xek.h
@@ -17,11 +17,6 @@
 
 #define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 
-/* serial console */
-#define CONFIG_ATMEL_USART
-#define CONFIG_USART_BASE		ATMEL_BASE_DBGU
-#define	CONFIG_USART_ID			ATMEL_ID_DBGU
-
 /*
  * This needs to be defined for the OHCI code to work but it is defined as
  * ATMEL_ID_UHPHS in the CPU specific header files.
@@ -62,16 +57,15 @@
 #define CONFIG_SYS_SDRAM_SIZE		0x20000000
 
 #ifdef CONFIG_SPL_BUILD
-#define CONFIG_SYS_INIT_SP_ADDR		0x310000
+#define CONFIG_SYS_INIT_SP_ADDR		0x318000
 #else
 #define CONFIG_SYS_INIT_SP_ADDR \
-	(CONFIG_SYS_SDRAM_BASE + 4 * 1024 - GENERATED_GBL_DATA_SIZE)
+	(CONFIG_SYS_SDRAM_BASE + 16 * 1024 - GENERATED_GBL_DATA_SIZE)
 #endif
 
 /* SerialFlash */
 
 #ifdef CONFIG_CMD_SF
-#define CONFIG_ATMEL_SPI
 #define CONFIG_SF_DEFAULT_SPEED		30000000
 #endif
 
@@ -95,27 +89,11 @@
 #define CONFIG_CMD_NAND_TRIMFFS
 #endif
 
-/* Ethernet Hardware */
-#define CONFIG_MACB
-#define CONFIG_RMII
-#define CONFIG_NET_RETRY_COUNT		20
-#define CONFIG_MACB_SEARCH_PHY
-#define CONFIG_RGMII
-#define CONFIG_PHYLIB
-#define CONFIG_PHY_MICREL
 #define CONFIG_PHY_MICREL_KSZ9021
 
-/* MMC */
-
-#ifdef CONFIG_CMD_MMC
-#define CONFIG_GENERIC_ATMEL_MCI
-#define ATMEL_BASE_MMCI			ATMEL_BASE_MCI0
-#endif
-
 /* USB */
 
 #ifdef CONFIG_CMD_USB
-#define CONFIG_USB_ATMEL
 #define CONFIG_USB_ATMEL_CLK_SEL_UPLL
 #define CONFIG_USB_OHCI_NEW
 #define CONFIG_SYS_USB_OHCI_CPU_INIT
@@ -124,11 +102,6 @@
 #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS	3
 #endif
 
-/* USB device */
-#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_FAT_WRITE
 #endif
@@ -148,7 +121,7 @@
 /* SPL */
 #define CONFIG_SPL_FRAMEWORK
 #define CONFIG_SPL_TEXT_BASE		0x300000
-#define CONFIG_SPL_MAX_SIZE		0x10000
+#define CONFIG_SPL_MAX_SIZE		0x18000
 #define CONFIG_SPL_BSS_START_ADDR	0x20000000
 #define CONFIG_SPL_BSS_MAX_SIZE		0x80000
 #define CONFIG_SYS_SPL_MALLOC_START	0x20080000
@@ -176,7 +149,7 @@
 
 #elif CONFIG_SYS_USE_SERIALFLASH
 #define CONFIG_SPL_SPI_LOAD
-#define CONFIG_SYS_SPI_U_BOOT_OFFS	0x8000
+#define CONFIG_SYS_SPI_U_BOOT_OFFS	0x10000
 
 #endif
 
diff --git a/include/configs/tinker_rk3288.h b/include/configs/tinker_rk3288.h
index 5228528..402ae2d 100644
--- a/include/configs/tinker_rk3288.h
+++ b/include/configs/tinker_rk3288.h
@@ -13,7 +13,10 @@
 #undef BOOT_TARGET_DEVICES
 
 #define BOOT_TARGET_DEVICES(func) \
-	func(MMC, mmc, 1)
+	func(MMC, mmc, 1) \
+	func(USB, usb, 0) \
+	func(PXE, pxe, na) \
+	func(DHCP, dchp, na)
 
 #define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_SYS_MMC_ENV_DEV 1
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 8c92d0b..1b635e4 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -35,6 +35,7 @@
 	UCLASS_DMA,		/* Direct Memory Access */
 	UCLASS_ETH,		/* Ethernet device */
 	UCLASS_GPIO,		/* Bank of general-purpose I/O pins */
+	UCLASS_FIRMWARE,	/* Firmware */
 	UCLASS_I2C,		/* I2C bus */
 	UCLASS_I2C_EEPROM,	/* I2C EEPROM device */
 	UCLASS_I2C_GENERIC,	/* Generic I2C device */
diff --git a/include/led.h b/include/led.h
index b929d0c..c67af22 100644
--- a/include/led.h
+++ b/include/led.h
@@ -9,23 +9,65 @@
 #define __LED_H
 
 /**
- * struct led_uclass_plat - Platform data the uclass stores about each device
+ * struct led_uc_plat - Platform data the uclass stores about each device
  *
  * @label:	LED label
  */
-struct led_uclass_plat {
+struct led_uc_plat {
 	const char *label;
 };
 
+/**
+ * struct led_uc_priv - Private data the uclass stores about each device
+ *
+ * @period_ms:	Flash period in milliseconds
+ */
+struct led_uc_priv {
+	int period_ms;
+};
+
+enum led_state_t {
+	LEDST_OFF = 0,
+	LEDST_ON = 1,
+	LEDST_TOGGLE,
+#ifdef CONFIG_LED_BLINK
+	LEDST_BLINK,
+#endif
+
+	LEDST_COUNT,
+};
+
 struct led_ops {
 	/**
-	 * set_on() - set the state of an LED
+	 * set_state() - set the state of an LED
 	 *
 	 * @dev:	LED device to change
-	 * @on:		1 to turn the LED on, 0 to turn it off
+	 * @state:	LED state to set
 	 * @return 0 if OK, -ve on error
 	 */
-	int (*set_on)(struct udevice *dev, int on);
+	int (*set_state)(struct udevice *dev, enum led_state_t state);
+
+	/**
+	 * led_get_state() - get the state of an LED
+	 *
+	 * @dev:	LED device to change
+	 * @return LED state led_state_t, or -ve on error
+	 */
+	enum led_state_t (*get_state)(struct udevice *dev);
+
+#ifdef CONFIG_LED_BLINK
+	/**
+	 * led_set_period() - set the blink period of an LED
+	 *
+	 * Thie records the period if supported, or returns -ENOSYS if not.
+	 * To start the LED blinking, use set_state().
+	 *
+	 * @dev:	LED device to change
+	 * @period_ms:	LED blink period in milliseconds
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*set_period)(struct udevice *dev, int period_ms);
+#endif
 };
 
 #define led_get_ops(dev)	((struct led_ops *)(dev)->driver->ops)
@@ -40,12 +82,29 @@
 int led_get_by_label(const char *label, struct udevice **devp);
 
 /**
- * led_set_on() - set the state of an LED
+ * led_set_state() - set the state of an LED
  *
  * @dev:	LED device to change
- * @on:		1 to turn the LED on, 0 to turn it off
+ * @state:	LED state to set
  * @return 0 if OK, -ve on error
  */
-int led_set_on(struct udevice *dev, int on);
+int led_set_state(struct udevice *dev, enum led_state_t state);
+
+/**
+ * led_get_state() - get the state of an LED
+ *
+ * @dev:	LED device to change
+ * @return LED state led_state_t, or -ve on error
+ */
+enum led_state_t led_get_state(struct udevice *dev);
+
+/**
+ * led_set_period() - set the blink period of an LED
+ *
+ * @dev:	LED device to change
+ * @period_ms:	LED blink period in milliseconds
+ * @return 0 if OK, -ve on error
+ */
+int led_set_period(struct udevice *dev, int period_ms);
 
 #endif
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
new file mode 100644
index 0000000..28e61ce
--- /dev/null
+++ b/include/linux/arm-smccc.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+#ifndef __LINUX_ARM_SMCCC_H
+#define __LINUX_ARM_SMCCC_H
+
+/*
+ * This file provides common defines for ARM SMC Calling Convention as
+ * specified in
+ * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
+ */
+
+#define ARM_SMCCC_STD_CALL		0
+#define ARM_SMCCC_FAST_CALL		1
+#define ARM_SMCCC_TYPE_SHIFT		31
+
+#define ARM_SMCCC_SMC_32		0
+#define ARM_SMCCC_SMC_64		1
+#define ARM_SMCCC_CALL_CONV_SHIFT	30
+
+#define ARM_SMCCC_OWNER_MASK		0x3F
+#define ARM_SMCCC_OWNER_SHIFT		24
+
+#define ARM_SMCCC_FUNC_MASK		0xFFFF
+
+#define ARM_SMCCC_IS_FAST_CALL(smc_val)	\
+	((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
+#define ARM_SMCCC_IS_64(smc_val) \
+	((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
+#define ARM_SMCCC_FUNC_NUM(smc_val)	((smc_val) & ARM_SMCCC_FUNC_MASK)
+#define ARM_SMCCC_OWNER_NUM(smc_val) \
+	(((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
+
+#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
+	(((type) << ARM_SMCCC_TYPE_SHIFT) | \
+	((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
+	(((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
+	((func_num) & ARM_SMCCC_FUNC_MASK))
+
+#define ARM_SMCCC_OWNER_ARCH		0
+#define ARM_SMCCC_OWNER_CPU		1
+#define ARM_SMCCC_OWNER_SIP		2
+#define ARM_SMCCC_OWNER_OEM		3
+#define ARM_SMCCC_OWNER_STANDARD	4
+#define ARM_SMCCC_OWNER_TRUSTED_APP	48
+#define ARM_SMCCC_OWNER_TRUSTED_APP_END	49
+#define ARM_SMCCC_OWNER_TRUSTED_OS	50
+#define ARM_SMCCC_OWNER_TRUSTED_OS_END	63
+
+#define ARM_SMCCC_QUIRK_NONE		0
+#define ARM_SMCCC_QUIRK_QCOM_A6		1 /* Save/restore register a6 */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/linkage.h>
+#include <linux/types.h>
+/**
+ * struct arm_smccc_res - Result from SMC/HVC call
+ * @a0-a3 result values from registers 0 to 3
+ */
+struct arm_smccc_res {
+	unsigned long a0;
+	unsigned long a1;
+	unsigned long a2;
+	unsigned long a3;
+};
+
+/**
+ * struct arm_smccc_quirk - Contains quirk information
+ * @id: quirk identification
+ * @state: quirk specific information
+ * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
+ */
+struct arm_smccc_quirk {
+	int	id;
+	union {
+		unsigned long a6;
+	} state;
+};
+
+/**
+ * __arm_smccc_smc() - make SMC calls
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
+ *
+ * This function is used to make SMC calls following SMC Calling Convention.
+ * The content of the supplied param are copied to registers 0 to 7 prior
+ * to the SMC instruction. The return values are updated with the content
+ * from register 0 to 3 on return from the SMC instruction.  An optional
+ * quirk structure provides vendor specific behavior.
+ */
+asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
+			unsigned long a2, unsigned long a3, unsigned long a4,
+			unsigned long a5, unsigned long a6, unsigned long a7,
+			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
+
+/**
+ * __arm_smccc_hvc() - make HVC calls
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
+ *
+ * This function is used to make HVC calls following SMC Calling
+ * Convention.  The content of the supplied param are copied to registers 0
+ * to 7 prior to the HVC instruction. The return values are updated with
+ * the content from register 0 to 3 on return from the HVC instruction.  An
+ * optional quirk structure provides vendor specific behavior.
+ */
+asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
+			unsigned long a2, unsigned long a3, unsigned long a4,
+			unsigned long a5, unsigned long a6, unsigned long a7,
+			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
+
+#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
+
+#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
+
+#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
+
+#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
+
+#endif /*__ASSEMBLY__*/
+#endif /*__LINUX_ARM_SMCCC_H*/
diff --git a/include/linux/psci.h b/include/linux/psci.h
index 310d83e..8d13bd2 100644
--- a/include/linux/psci.h
+++ b/include/linux/psci.h
@@ -87,4 +87,17 @@
 #define PSCI_RET_NOT_PRESENT			-7
 #define PSCI_RET_DISABLED			-8
 
+#ifdef CONFIG_ARM_PSCI_FW
+typedef unsigned long (psci_fn)(unsigned long, unsigned long,
+				unsigned long, unsigned long);
+
+extern psci_fn *invoke_psci_fn;
+#else
+unsigned long invoke_psci_fn(unsigned long a0, unsigned long a1,
+			     unsigned long a2, unsigned long a3)
+{
+	return PSCI_RET_DISABLED;
+}
+#endif
+
 #endif /* _UAPI_LINUX_PSCI_H */
diff --git a/test/dm/led.c b/test/dm/led.c
index 8ee075c..fde700b 100644
--- a/test/dm/led.c
+++ b/test/dm/led.c
@@ -41,15 +41,43 @@
 	ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev));
 	ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio));
 	ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
-	led_set_on(dev, 1);
+	ut_assertok(led_set_state(dev, LEDST_ON));
 	ut_asserteq(1, sandbox_gpio_get_value(gpio, offset));
-	led_set_on(dev, 0);
+	ut_asserteq(LEDST_ON, led_get_state(dev));
+
+	ut_assertok(led_set_state(dev, LEDST_OFF));
 	ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
+	ut_asserteq(LEDST_OFF, led_get_state(dev));
 
 	return 0;
 }
 DM_TEST(dm_test_led_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 
+/* Test that we can toggle LEDs */
+static int dm_test_led_toggle(struct unit_test_state *uts)
+{
+	const int offset = 1;
+	struct udevice *dev, *gpio;
+
+	/*
+	 * Check that we can manipulate an LED. LED 1 is connected to GPIO
+	 * bank gpio_a, offset 1.
+	 */
+	ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev));
+	ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio));
+	ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
+	ut_assertok(led_set_state(dev, LEDST_TOGGLE));
+	ut_asserteq(1, sandbox_gpio_get_value(gpio, offset));
+	ut_asserteq(LEDST_ON, led_get_state(dev));
+
+	ut_assertok(led_set_state(dev, LEDST_TOGGLE));
+	ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
+	ut_asserteq(LEDST_OFF, led_get_state(dev));
+
+	return 0;
+}
+DM_TEST(dm_test_led_toggle, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
 /* Test obtaining an LED by label */
 static int dm_test_led_label(struct unit_test_state *uts)
 {
@@ -70,3 +98,27 @@
 	return 0;
 }
 DM_TEST(dm_test_led_label, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test LED blinking */
+#ifdef CONFIG_LED_BLINK
+static int dm_test_led_blink(struct unit_test_state *uts)
+{
+	const int offset = 1;
+	struct udevice *dev, *gpio;
+
+	/*
+	 * Check that we get an error when trying to blink an LED, since it is
+	 * not supported by the GPIO LED driver.
+	 */
+	ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev));
+	ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio));
+	ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
+	ut_asserteq(-ENOSYS, led_set_state(dev, LEDST_BLINK));
+	ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
+	ut_asserteq(LEDST_OFF, led_get_state(dev));
+	ut_asserteq(-ENOSYS, led_set_period(dev, 100));
+
+	return 0;
+}
+DM_TEST(dm_test_led_blink, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+#endif
diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py
index 4778876..5cf97ac 100644
--- a/tools/buildman/toolchain.py
+++ b/tools/buildman/toolchain.py
@@ -120,8 +120,9 @@
             Priority of toolchain, PRIORITY_CALC=highest, 20=lowest.
         """
         priority_list = ['-elf', '-unknown-linux-gnu', '-linux',
-            '-none-linux-gnueabi', '-uclinux', '-none-eabi',
-            '-gentoo-linux-gnu', '-linux-gnueabi', '-le-linux', '-uclinux']
+            '-none-linux-gnueabi', '-none-linux-gnueabihf', '-uclinux',
+            '-none-eabi', '-gentoo-linux-gnu', '-linux-gnueabi',
+            '-linux-gnueabihf', '-le-linux', '-uclinux']
         for prio in range(len(priority_list)):
             if priority_list[prio] in fname:
                 return PRIORITY_CALC + prio
diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c
index 299e0c9..2861656 100644
--- a/tools/env/fw_env.c
+++ b/tools/env/fw_env.c
@@ -473,6 +473,7 @@
 	int i;
 	size_t len;
 	char *name, **valv;
+	char *oldval;
 	char *value = NULL;
 	int valc;
 	int ret;
@@ -507,11 +508,13 @@
 
 		if (value)
 			value[len - 1] = ' ';
+		oldval = value;
 		value = realloc(value, len + val_len + 1);
 		if (!value) {
 			fprintf(stderr,
 				"Cannot malloc %zu bytes: %s\n",
 				len, strerror(errno));
+			free(oldval);
 			return -1;
 		}
 
diff --git a/tools/moveconfig.py b/tools/moveconfig.py
index 228d098..dcca0ec 100755
--- a/tools/moveconfig.py
+++ b/tools/moveconfig.py
@@ -199,28 +199,21 @@
 # Most of them are available at kernel.org
 # (https://www.kernel.org/pub/tools/crosstool/files/bin/), except the following:
 # arc: https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/releases
-# blackfin: http://sourceforge.net/projects/adi-toolchain/files/
 # nds32: http://osdk.andestech.com/packages/nds32le-linux-glibc-v1.tgz
 # nios2: https://sourcery.mentor.com/GNUToolchain/subscription42545
 # sh: http://sourcery.mentor.com/public/gnu_toolchain/sh-linux-gnu
-#
-# openrisc kernel.org toolchain is out of date, download latest one from
-# http://opencores.org/or1k/OpenRISC_GNU_tool_chain#Prebuilt_versions
 CROSS_COMPILE = {
     'arc': 'arc-linux-',
     'aarch64': 'aarch64-linux-',
     'arm': 'arm-unknown-linux-gnueabi-',
     'avr32': 'avr32-linux-',
-    'blackfin': 'bfin-elf-',
     'm68k': 'm68k-linux-',
     'microblaze': 'microblaze-linux-',
     'mips': 'mips-linux-',
     'nds32': 'nds32le-linux-',
     'nios2': 'nios2-linux-gnu-',
-    'openrisc': 'or1k-elf-',
     'powerpc': 'powerpc-linux-',
     'sh': 'sh-linux-gnu-',
-    'sparc': 'sparc-linux-',
     'x86': 'i386-linux-',
     'xtensa': 'xtensa-linux-'
 }