Merge tag 'u-boot-rockchip-20200531' of https://gitlab.denx.de/u-boot/custodians/u-boot-rockchip

- Fix mmc of path after syncfrom kernel dts;
- Add dwc3 host support with DM for rk3399;
- Add usb2phy and typec phy for rockchip platform;
- Migrate board list doc to rockchip.rst;
- Add rk3399 Pinebook Pro board support;
- Update dram_init in board_init and add memory node in SPL;
diff --git a/arch/arm/dts/meson-gxl-s805x-libretech-ac-u-boot.dtsi b/arch/arm/dts/meson-gxl-s805x-libretech-ac-u-boot.dtsi
index c35158d..474a3e1 100644
--- a/arch/arm/dts/meson-gxl-s805x-libretech-ac-u-boot.dtsi
+++ b/arch/arm/dts/meson-gxl-s805x-libretech-ac-u-boot.dtsi
@@ -4,4 +4,8 @@
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  */
 
-#include "meson-gx-u-boot.dtsi"
+#include "meson-gxl-u-boot.dtsi"
+
+&dwc2 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/meson-gxl-s905d-libretech-pc-u-boot.dtsi b/arch/arm/dts/meson-gxl-s905d-libretech-pc-u-boot.dtsi
index c35158d..474a3e1 100644
--- a/arch/arm/dts/meson-gxl-s905d-libretech-pc-u-boot.dtsi
+++ b/arch/arm/dts/meson-gxl-s905d-libretech-pc-u-boot.dtsi
@@ -4,4 +4,8 @@
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  */
 
-#include "meson-gx-u-boot.dtsi"
+#include "meson-gxl-u-boot.dtsi"
+
+&dwc2 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/meson-gxl-s905x-khadas-vim-u-boot.dtsi b/arch/arm/dts/meson-gxl-s905x-khadas-vim-u-boot.dtsi
index 39270ea..474a3e1 100644
--- a/arch/arm/dts/meson-gxl-s905x-khadas-vim-u-boot.dtsi
+++ b/arch/arm/dts/meson-gxl-s905x-khadas-vim-u-boot.dtsi
@@ -5,3 +5,7 @@
  */
 
 #include "meson-gxl-u-boot.dtsi"
+
+&dwc2 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/meson-gxm-khadas-vim2-u-boot.dtsi b/arch/arm/dts/meson-gxm-khadas-vim2-u-boot.dtsi
index bec9e05..7aecf26 100644
--- a/arch/arm/dts/meson-gxm-khadas-vim2-u-boot.dtsi
+++ b/arch/arm/dts/meson-gxm-khadas-vim2-u-boot.dtsi
@@ -4,7 +4,7 @@
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  */
 
-#include "meson-gx-u-boot.dtsi"
+#include "meson-gxl-u-boot.dtsi"
 
 / {
 	aliases {
@@ -12,6 +12,10 @@
 	};
 };
 
+&dwc2 {
+	status = "okay";
+};
+
 &sd_emmc_c {
 	status = "okay";
 	pinctrl-0 = <&emmc_pins>;
diff --git a/arch/arm/dts/meson-gxm-s912-libretech-pc-u-boot.dtsi b/arch/arm/dts/meson-gxm-s912-libretech-pc-u-boot.dtsi
index c35158d..474a3e1 100644
--- a/arch/arm/dts/meson-gxm-s912-libretech-pc-u-boot.dtsi
+++ b/arch/arm/dts/meson-gxm-s912-libretech-pc-u-boot.dtsi
@@ -4,4 +4,8 @@
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  */
 
-#include "meson-gx-u-boot.dtsi"
+#include "meson-gxl-u-boot.dtsi"
+
+&dwc2 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/meson-khadas-vim3-u-boot.dtsi b/arch/arm/dts/meson-khadas-vim3-u-boot.dtsi
index 81fd5be..b5da4fd 100644
--- a/arch/arm/dts/meson-khadas-vim3-u-boot.dtsi
+++ b/arch/arm/dts/meson-khadas-vim3-u-boot.dtsi
@@ -4,6 +4,8 @@
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  */
 
+#include "meson-g12-common-u-boot.dtsi"
+
 / {
 	aliases {
 		spi0 = &spifc;
diff --git a/board/renesas/r2dplus/r2dplus.c b/board/renesas/r2dplus/r2dplus.c
index e4d0967..0bbdb0e 100644
--- a/board/renesas/r2dplus/r2dplus.c
+++ b/board/renesas/r2dplus/r2dplus.c
@@ -46,7 +46,9 @@
 	}
 }
 
+#ifndef CONFIG_DM_ETH
 int board_eth_init(bd_t *bis)
 {
 	return pci_eth_init(bis);
 }
+#endif
diff --git a/configs/khadas-vim3_defconfig b/configs/khadas-vim3_defconfig
index 692138e..4aeab0e 100644
--- a/configs/khadas-vim3_defconfig
+++ b/configs/khadas-vim3_defconfig
@@ -40,6 +40,8 @@
 CONFIG_MESON_G12A_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_G12A=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MESON_EE_POWER_DOMAIN=y
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_RESET=y
@@ -55,6 +57,7 @@
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_DWC3=y
+CONFIG_USB_KEYBOARD=y
 # CONFIG_USB_DWC3_GADGET is not set
 CONFIG_USB_DWC3_MESON_G12A=y
 CONFIG_USB_GADGET=y
@@ -63,4 +66,10 @@
 CONFIG_USB_GADGET_DWC2_OTG=y
 CONFIG_USB_GADGET_DWC2_OTG_PHY_BUS_WIDTH_8=y
 CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_DM_VIDEO=y
+# CONFIG_VIDEO_BPP8 is not set
+# CONFIG_VIDEO_BPP16 is not set
+CONFIG_SYS_WHITE_ON_BLACK=y
+CONFIG_VIDEO_MESON=y
+CONFIG_VIDEO_DT_SIMPLEFB=y
 CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/khadas-vim3l_defconfig b/configs/khadas-vim3l_defconfig
index 28c20c0..887885f 100644
--- a/configs/khadas-vim3l_defconfig
+++ b/configs/khadas-vim3l_defconfig
@@ -57,6 +57,7 @@
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_DWC3=y
+CONFIG_USB_KEYBOARD=y
 # CONFIG_USB_DWC3_GADGET is not set
 CONFIG_USB_DWC3_MESON_G12A=y
 CONFIG_USB_GADGET=y
@@ -66,6 +67,9 @@
 CONFIG_USB_GADGET_DWC2_OTG_PHY_BUS_WIDTH_8=y
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_DM_VIDEO=y
+# CONFIG_VIDEO_BPP8 is not set
+# CONFIG_VIDEO_BPP16 is not set
+CONFIG_SYS_WHITE_ON_BLACK=y
 CONFIG_VIDEO_MESON=y
 CONFIG_VIDEO_DT_SIMPLEFB=y
 CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/r2dplus_defconfig b/configs/r2dplus_defconfig
index 8ae4ba1..900428a 100644
--- a/configs/r2dplus_defconfig
+++ b/configs/r2dplus_defconfig
@@ -7,8 +7,7 @@
 CONFIG_BOOTDELAY=-1
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttySC0,115200"
-# CONFIG_CMDLINE_EDITING is not set
-# CONFIG_AUTO_COMPLETE is not set
+CONFIG_HUSH_PARSER=y
 CONFIG_CMD_IMLS=y
 CONFIG_CMD_DM=y
 CONFIG_CMD_IDE=y
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index c1237ea..a3f049e 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -80,7 +80,6 @@
 CONFIG_OF_LIVE=y
 CONFIG_OF_HOSTFILE=y
 CONFIG_DEFAULT_DEVICE_TREE="sandbox64"
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
 CONFIG_REGMAP=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 9445d78..c09bf33 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -89,7 +89,6 @@
 CONFIG_OF_LIVE=y
 CONFIG_OF_HOSTFILE=y
 CONFIG_DEFAULT_DEVICE_TREE="sandbox"
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
 CONFIG_REGMAP=y
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index a4a7ae8..21f9047 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -63,7 +63,6 @@
 CONFIG_OF_CONTROL=y
 CONFIG_OF_HOSTFILE=y
 CONFIG_DEFAULT_DEVICE_TREE="sandbox"
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
 CONFIG_REGMAP=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index 945fe54..fc8b26e 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -79,7 +79,6 @@
 CONFIG_OF_HOSTFILE=y
 CONFIG_DEFAULT_DEVICE_TREE="sandbox"
 CONFIG_SPL_OF_PLATDATA=y
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
 CONFIG_SPL_DM=y
diff --git a/doc/SPI/README.sandbox-spi b/doc/SPI/README.sandbox-spi
index dfa845c..f6a55fe 100644
--- a/doc/SPI/README.sandbox-spi
+++ b/doc/SPI/README.sandbox-spi
@@ -2,59 +2,37 @@
 ====================================
 
 U-Boot supports SPI and SPI flash emulation in sandbox. This must be enabled
-using the --spi_sf paramter when starting U-Boot.
+via a device tree.
 
 For example:
 
-$ make O=sandbox sandbox_config
-$ make O=sandbox
-$ ./sandbox/u-boot --spi_sf 0:0:W25Q128:b/chromeos_peach/out/image.bin
-
-The four parameters to spi_sf are:
-
-   SPI bus number (typically 0)
-   SPI chip select number (typically 0)
-   SPI chip to emulate
-   File containing emulated data
+	spi@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0 1>;
+		compatible = "sandbox,spi";
+		cs-gpios = <0>, <&gpio_a 0>;
+		spi.bin@0 {
+			reg = <0>;
+			compatible = "spansion,m25p16", "jedec,spi-nor";
+			spi-max-frequency = <40000000>;
+			sandbox,filename = "spi.bin";
+		};
+	};
 
 Supported chips are W25Q16 (2MB), W25Q32 (4MB) and W25Q128 (16MB). Once
 U-Boot it started you can use 'sf' commands as normal. For example:
 
-$ ./b/sandbox/u-boot --spi_sf 0:0:W25Q128:b/chromeos_peach/out/image.bin \
-	-c "sf probe; sf test 0 100000; sf read 0 1000 1000; \
-		sf erase 1000 1000; sf write 0 1000 1000"
-
-
-U-Boot 2013.10-00237-gd4e0fdb (Nov 07 2013 - 20:08:15)
-
-DRAM:  128 MiB
-Using default environment
-
-In:    serial
-Out:   serial
-Err:   serial
-SF: Detected W25Q128BV with page size 256 Bytes, erase size 4 KiB, total 16 MiB
-SPI flash test:
-0 erase: 1 ticks, 1024000 KiB/s 8192.000 Mbps
-1 check: 2 ticks, 512000 KiB/s 4096.000 Mbps
-2 write: 6 ticks, 170666 KiB/s 1365.328 Mbps
-3 read: 0 ticks, 1048576000 KiB/s -201326.-592 Mbps
-Test passed
-0 erase: 1 ticks, 1024000 KiB/s 8192.000 Mbps
-1 check: 2 ticks, 512000 KiB/s 4096.000 Mbps
-2 write: 6 ticks, 170666 KiB/s 1365.328 Mbps
-3 read: 0 ticks, 1048576000 KiB/s -201326.-592 Mbps
-SF: 4096 bytes @ 0x1000 Read: OK
-SF: 4096 bytes @ 0x1000 Erased: OK
-SF: 4096 bytes @ 0x1000 Written: OK
-
+$ dd if=/dev/zero of=spi.bin bs=1M count=2
+$ u-boot -T
 
 Since the SPI bus is fully implemented as well as the SPI flash connected to
 it, you can also use low-level SPI commands to access the flash. For example
 this reads the device ID from the emulated chip:
 
 => sspi 0 32 9f
-FFEF4018
+SF: Detected m25p16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB
+FF202015
 
 
 Simon Glass
diff --git a/doc/arch/sandbox.rst b/doc/arch/sandbox.rst
index 6a1c6fc..360f224 100644
--- a/doc/arch/sandbox.rst
+++ b/doc/arch/sandbox.rst
@@ -316,19 +316,29 @@
 
 Sandbox supports SPI and SPI flash emulation.
 
-This is controlled by the spi_sf argument, the format of which is::
+The device can be enabled via a device tree, for example::
 
-   bus:cs:device:file
+    spi@0 {
+            #address-cells = <1>;
+            #size-cells = <0>;
+            reg = <0 1>;
+            compatible = "sandbox,spi";
+            cs-gpios = <0>, <&gpio_a 0>;
+            spi.bin@0 {
+                    reg = <0>;
+                    compatible = "spansion,m25p16", "jedec,spi-nor";
+                    spi-max-frequency = <40000000>;
+                    sandbox,filename = "spi.bin";
+            };
+    };
 
-   bus    - SPI bus number
-   cs     - SPI chip select number
-   device - SPI device emulation name
-   file   - File on disk containing the data
+The file must be created in advance::
 
-For example::
+   $ dd if=/dev/zero of=spi.bin bs=1M count=2
+   $ u-boot -T
 
-   dd if=/dev/zero of=spi.bin bs=1M count=4
-   ./u-boot --spi_sf 0:0:M25P16:spi.bin
+Here, you can use "-T" or "-D" option to specify test.dtb or u-boot.dtb,
+respectively, or "-d <file>" for your own dtb.
 
 With this setup you can issue SPI flash commands as normal::
 
@@ -346,22 +356,6 @@
 This is issuing a READ_ID command and getting back 20 (ST Micro) part
 0x2015 (the M25P16).
 
-Drivers are connected to a particular bus/cs using sandbox's state
-structure (see the 'spi' member). A set of operations must be provided
-for each driver.
-
-
-Configuration settings for the curious are:
-
-CONFIG_SANDBOX_SPI_MAX_BUS:
-  The maximum number of SPI buses supported by the driver (default 1).
-
-CONFIG_SANDBOX_SPI_MAX_CS:
-  The maximum number of chip selects supported by the driver (default 10).
-
-CONFIG_SPI_IDLE_VAL:
-  The idle value on the SPI bus
-
 
 Block Device Emulation
 ----------------------
diff --git a/drivers/core/read.c b/drivers/core/read.c
index 3d421f7..047089c 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -4,12 +4,12 @@
  * Written by Simon Glass <sjg@chromium.org>
  */
 
-#include <asm/types.h>
-#include <asm/io.h>
 #include <common.h>
 #include <dm.h>
-#include <mapmem.h>
 #include <dm/of_access.h>
+#include <mapmem.h>
+#include <asm/types.h>
+#include <asm/io.h>
 
 int dev_read_u32(const struct udevice *dev, const char *propname, u32 *outp)
 {
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index 42ee7d5..3616e21 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -18,6 +18,12 @@
 #include <dm/device_compat.h>
 #include <linux/err.h>
 
+/*
+ * This assigned unique hex value is constant and is derived from the two ASCII
+ * letters 'DW' followed by a 16-bit unsigned number
+ */
+#define DW_I2C_COMP_TYPE	0x44570140
+
 #ifdef CONFIG_SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED
 static int  dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
 {
@@ -199,18 +205,24 @@
 	return 0;
 }
 
-static int calc_bus_speed(struct dw_i2c *priv, int speed, ulong bus_clk,
-			  struct dw_i2c_speed_config *config)
+/**
+ * calc_bus_speed() - Calculate the config to use for a particular i2c speed
+ *
+ * @priv: Private information for the driver (NULL if not using driver model)
+ * @i2c_base: Registers for the I2C controller
+ * @speed: Required i2c speed in Hz
+ * @bus_clk: Input clock to the I2C controller in Hz (e.g. IC_CLK)
+ * @config: Returns the config to use for this speed
+ * @return 0 if OK, -ve on error
+ */
+static int calc_bus_speed(struct dw_i2c *priv, struct i2c_regs *regs, int speed,
+			  ulong bus_clk, struct dw_i2c_speed_config *config)
 {
 	const struct dw_scl_sda_cfg *scl_sda_cfg = NULL;
-	struct i2c_regs *regs = priv->regs;
 	enum i2c_speed_mode i2c_spd;
-	u32 comp_param1;
 	int spk_cnt;
 	int ret;
 
-	comp_param1 = readl(&regs->comp_param1);
-
 	if (priv)
 		scl_sda_cfg = priv->scl_sda_cfg;
 	/* Allow high speed if there is no config, or the config allows it */
@@ -225,6 +237,9 @@
 
 	/* Check is high speed possible and fall back to fast mode if not */
 	if (i2c_spd == IC_SPEED_MODE_HIGH) {
+		u32 comp_param1;
+
+		comp_param1 = readl(&regs->comp_param1);
 		if ((comp_param1 & DW_IC_COMP_PARAM_1_SPEED_MODE_MASK)
 				!= DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH)
 			i2c_spd = IC_SPEED_MODE_FAST;
@@ -260,11 +275,14 @@
 	return 0;
 }
 
-/*
- * _dw_i2c_set_bus_speed - Set the i2c speed
- * @speed:	required i2c speed
+/**
+ * _dw_i2c_set_bus_speed() - Set the i2c speed
  *
- * Set the i2c speed.
+ * @priv: Private information for the driver (NULL if not using driver model)
+ * @i2c_base: Registers for the I2C controller
+ * @speed: Required i2c speed in Hz
+ * @bus_clk: Input clock to the I2C controller in Hz (e.g. IC_CLK)
+ * @return 0 if OK, -ve on error
  */
 static int _dw_i2c_set_bus_speed(struct dw_i2c *priv, struct i2c_regs *i2c_base,
 				 unsigned int speed, unsigned int bus_clk)
@@ -274,7 +292,7 @@
 	unsigned int ena;
 	int ret;
 
-	ret = calc_bus_speed(priv, speed, bus_clk, &config);
+	ret = calc_bus_speed(priv, i2c_base, speed, bus_clk, &config);
 	if (ret)
 		return ret;
 
@@ -754,6 +772,17 @@
 int designware_i2c_probe(struct udevice *bus)
 {
 	struct dw_i2c *priv = dev_get_priv(bus);
+	uint comp_type;
+
+	comp_type = readl(&priv->regs->comp_type);
+	if (comp_type != DW_I2C_COMP_TYPE) {
+		log_err("I2C bus %s has unknown type %#x\n", bus->name,
+			comp_type);
+		return -ENXIO;
+	}
+
+	log_info("I2C bus %s version %#x\n", bus->name,
+		 readl(&priv->regs->comp_version));
 
 	return __dw_i2c_init(priv->regs, 0, 0);
 }
diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index 8166df7..8bc69e8 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -516,7 +516,7 @@
 	udelay(delay);
 
 	/*  Toggle SCL until slave release SDA */
-	while (scl_count-- >= 0) {
+	for (; scl_count; --scl_count) {
 		i2c_gpio_set_pin(scl_pin, 1);
 		udelay(delay);
 		i2c_gpio_set_pin(scl_pin, 0);
diff --git a/drivers/misc/i2c_eeprom.c b/drivers/misc/i2c_eeprom.c
index ed23a62..45c34d3 100644
--- a/drivers/misc/i2c_eeprom.c
+++ b/drivers/misc/i2c_eeprom.c
@@ -18,6 +18,7 @@
 	u32 pagesize; /* page size in bytes */
 	u32 addr_offset_mask; /* bits in addr used for offset overflow */
 	u32 offset_len; /* size in bytes of offset */
+	u32 start_offset; /* valid start offset inside memory, by default 0 */
 };
 
 int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, int size)
@@ -148,7 +149,11 @@
 	i2c_set_chip_addr_offset_mask(dev, data->addr_offset_mask);
 
 	/* Verify that the chip is functional */
-	ret = i2c_eeprom_read(dev, 0, &test_byte, 1);
+	/*
+	 * Not all eeproms start from offset 0. Valid offset is available
+	 * in the platform data struct.
+	 */
+	ret = i2c_eeprom_read(dev, data->start_offset, &test_byte, 1);
 	if (ret)
 		return -ENODEV;
 
@@ -216,6 +221,7 @@
 	.pagesize = 16,
 	.addr_offset_mask = 0,
 	.offset_len = 1,
+	.start_offset = 0x80,
 };
 
 static const struct i2c_eeprom_drv_data atmel24c32_data = {
diff --git a/drivers/usb/eth/r8152.c b/drivers/usb/eth/r8152.c
index d9908ec..f201a17 100644
--- a/drivers/usb/eth/r8152.c
+++ b/drivers/usb/eth/r8152.c
@@ -1354,9 +1354,8 @@
 	struct usb_interface *iface;
 	struct usb_interface_descriptor *iface_desc;
 	int ep_in_found = 0, ep_out_found = 0;
-	int i;
-
 	struct r8152 *tp;
+	int i;
 
 	/* let's examine the device now */
 	iface = &dev->config.if_desc[ifnum];
@@ -1399,10 +1398,13 @@
 		if ((iface->ep_desc[i].bmAttributes &
 		     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
 			u8 ep_addr = iface->ep_desc[i].bEndpointAddress;
-			if ((ep_addr & USB_DIR_IN) && !ep_in_found) {
-				ss->ep_in = ep_addr &
-					USB_ENDPOINT_NUMBER_MASK;
-				ep_in_found = 1;
+
+			if (ep_addr & USB_DIR_IN) {
+				if (!ep_in_found) {
+					ss->ep_in = ep_addr &
+						USB_ENDPOINT_NUMBER_MASK;
+					ep_in_found = 1;
+				}
 			} else {
 				if (!ep_out_found) {
 					ss->ep_out = ep_addr &
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index 24f8ad7..5f84c7b 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -447,8 +447,8 @@
 		ret = regulator_set_enable(priv->vbus_supply,
 					   (type == USB_INIT_DEVICE) ?
 					   false : true);
-		if (ret) {
-			puts("Error enabling VBUS supply\n");
+		if (ret && ret != -ENOSYS) {
+			printf("Error enabling VBUS supply (ret=%i)\n", ret);
 			return ret;
 		}
 	}
@@ -614,8 +614,8 @@
 		ret = regulator_set_enable(priv->vbus_supply,
 					   (type == USB_INIT_DEVICE) ?
 					   false : true);
-		if (ret) {
-			puts("Error enabling VBUS supply\n");
+		if (ret && ret != -ENOSYS) {
+			printf("Error enabling VBUS supply (ret=%i)\n", ret);
 			return ret;
 		}
 	}
diff --git a/tools/patman/README b/tools/patman/README
index 02d5829..52b2cf7 100644
--- a/tools/patman/README
+++ b/tools/patman/README
@@ -247,14 +247,37 @@
 	to update the log there and then, knowing that the script will
 	do the rest.
 
+Commit-changes: n
+- This line will not appear in the cover-letter changelog
+<blank line>
+	This tag is like Series-changes, except changes in this changelog will
+	only appear in the changelog of the commit this tag is in. This is
+	useful when you want to add notes which may not make sense in the cover
+	letter. For example, you can have short changes such as "New" or
+	"Lint".
+
+Cover-changes: n
+- This line will only appear in the cover letter
+<blank line>
+	This tag is like Series-changes, except changes in this changelog will
+	only appear in the cover-letter changelog. This is useful to summarize
+	changes made with Commit-changes, or to add additional context to
+	changes.
+
 Patch-cc: Their Name <email>
 	This copies a single patch to another email address. Note that the
 	Cc: used by git send-email is ignored by patman, but will be
 	interpreted by git send-email if you use it.
 
 Series-process-log: sort, uniq
-	This tells patman to sort and/or uniq the change logs. It is
-	assumed that each change log entry is only a single line long.
+	This tells patman to sort and/or uniq the change logs. Changes may be
+	multiple lines long, as long as each subsequent line of a change begins
+	with a whitespace character. For example,
+
+- This change
+  continues onto the next line
+- But this change is separate
+
 	Use 'sort' to sort the entries, and 'uniq' to include only
 	unique entries. If omitted, no change log processing is done.
 	Separate each tag with a comma.
@@ -474,6 +497,33 @@
 not later when you can't remember which patch you changed. You can always
 go back and change or remove logs from commits.
 
+7. Some mailing lists have size limits and when we add binary contents to
+our patches it's easy to exceed the size limits. Use "--no-binary" to
+generate patches without any binary contents. You are supposed to include
+a link to a git repository in your "Commit-notes", "Series-notes" or
+"Cover-letter" for maintainers to fetch the original commit.
+
+8. Patches will have no changelog entries for revisions where they did not
+change. For clarity, if there are no changes for this patch in the most
+recent revision of the series, a note will be added. For example, a patch
+with the following tags in the commit
+
+    Series-version: 5
+    Series-changes: 2
+    - Some change
+
+    Series-changes: 4
+    - Another change
+
+would have a changelog of
+
+    (no changes since v4)
+
+    Changes in v4:
+    - Another change
+
+    Changes in v2:
+    - Some change
 
 Other thoughts
 ==============
diff --git a/tools/patman/func_test.py b/tools/patman/func_test.py
index b7e2825..dc30078 100644
--- a/tools/patman/func_test.py
+++ b/tools/patman/func_test.py
@@ -82,19 +82,33 @@
             Series-prefix: RFC
             Series-cc: Stefan Brüns <stefan.bruens@rwth-aachen.de>
             Cover-letter-cc: Lord Mëlchett <clergy@palace.gov>
-            Series-version: 2
+            Series-version: 3
+            Patch-cc: fred
+            Series-process-log: sort, uniq
             Series-changes: 4
             - Some changes
+            - Multi
+              line
+              change
+
+            Commit-changes: 2
+            - Changes only for this commit
+
+            Cover-changes: 4
+            - Some notes for the cover letter
 
             Cover-letter:
             test: A test patch series
             This is a test of how the cover
-            leter
+            letter
             works
             END
 
         and this in the first commit:
 
+            Commit-changes: 2
+            - second revision change
+
             Series-notes:
             some notes
             about some things
@@ -202,7 +216,7 @@
 
         expected = '''
 This is a test of how the cover
-leter
+letter
 works
 
 some notes
@@ -210,7 +224,11 @@
 from the first commit
 
 Changes in v4:
+- Multi
+  line
+  change
 - Some changes
+- Some notes for the cover letter
 
 Simon Glass (2):
   pci: Correct cast for sandbox
@@ -237,8 +255,34 @@
             subject = [line for line in lines if line.startswith('Subject')]
             self.assertEqual('Subject: [RFC %d/%d]' % (i + 1, count),
                              subject[0][:18])
+
+            # Check that we got our commit notes
+            start = 0
+            expected = ''
+
             if i == 0:
-                # Check that we got our commit notes
-                self.assertEqual('---', lines[17])
-                self.assertEqual('Some notes about', lines[18])
-                self.assertEqual('the first commit', lines[19])
+                start = 17
+                expected = '''---
+Some notes about
+the first commit
+
+(no changes since v2)
+
+Changes in v2:
+- second revision change'''
+            elif i == 1:
+                start = 17
+                expected = '''---
+
+Changes in v4:
+- Multi
+  line
+  change
+- Some changes
+
+Changes in v2:
+- Changes only for this commit'''
+
+            if expected:
+                expected = expected.splitlines()
+                self.assertEqual(expected, lines[start:(start+len(expected))])
diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py
index 770a051..72fc95d 100644
--- a/tools/patman/gitutil.py
+++ b/tools/patman/gitutil.py
@@ -254,7 +254,7 @@
     if result.return_code != 0:
         raise OSError('git fetch: %s' % result.stderr)
 
-def CreatePatches(start, count, series):
+def CreatePatches(start, count, ignore_binary, series):
     """Create a series of patches from the top of the current branch.
 
     The patch files are written to the current directory using
@@ -270,6 +270,8 @@
     if series.get('version'):
         version = '%s ' % series['version']
     cmd = ['git', 'format-patch', '-M', '--signoff']
+    if ignore_binary:
+        cmd.append('--no-binary')
     if series.get('cover'):
         cmd.append('--cover-letter')
     prefix = series.GetPatchPrefix()
diff --git a/tools/patman/main.py b/tools/patman/main.py
index f3d9c0c..0974c84 100755
--- a/tools/patman/main.py
+++ b/tools/patman/main.py
@@ -36,11 +36,11 @@
 parser.add_option('-i', '--ignore-errors', action='store_true',
        dest='ignore_errors', default=False,
        help='Send patches email even if patch errors are found')
+parser.add_option('-l', '--limit-cc', dest='limit', type='int',
+       default=None, help='Limit the cc list to LIMIT entries [default: %default]')
 parser.add_option('-m', '--no-maintainers', action='store_false',
        dest='add_maintainers', default=True,
        help="Don't cc the file maintainers automatically")
-parser.add_option('-l', '--limit-cc', dest='limit', type='int',
-       default=None, help='Limit the cc list to LIMIT entries [default: %default]')
 parser.add_option('-n', '--dry-run', action='store_true', dest='dry_run',
        default=False, help="Do a dry run (create but don't email patches)")
 parser.add_option('-p', '--project', default=project.DetectProject(),
@@ -52,21 +52,24 @@
        default=0, help='Commit to start creating patches from (0 = HEAD)')
 parser.add_option('-t', '--ignore-bad-tags', action='store_true',
                   default=False, help='Ignore bad tags / aliases')
-parser.add_option('--test', action='store_true', dest='test',
-                  default=False, help='run tests')
 parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
        default=False, help='Verbose output of errors and warnings')
+parser.add_option('-T', '--thread', action='store_true', dest='thread',
+                  default=False, help='Create patches as a single thread')
 parser.add_option('--cc-cmd', dest='cc_cmd', type='string', action='store',
        default=None, help='Output cc list for patch file (used by git)')
+parser.add_option('--no-binary', action='store_true', dest='ignore_binary',
+                  default=False,
+                  help="Do not output contents of changes in binary files")
 parser.add_option('--no-check', action='store_false', dest='check_patch',
                   default=True,
                   help="Don't check for patch compliance")
 parser.add_option('--no-tags', action='store_false', dest='process_tags',
-                  default=True, help="Don't process subject tags as aliaes")
+                  default=True, help="Don't process subject tags as aliases")
 parser.add_option('--smtp-server', type='str',
                   help="Specify the SMTP server to 'git send-email'")
-parser.add_option('-T', '--thread', action='store_true', dest='thread',
-                  default=False, help='Create patches as a single thread')
+parser.add_option('--test', action='store_true', dest='test',
+                  default=False, help='run tests')
 
 parser.usage += """
 
@@ -144,7 +147,7 @@
     if options.count:
         series = patchstream.GetMetaData(options.start, options.count)
         cover_fname, args = gitutil.CreatePatches(options.start, options.count,
-                series)
+                options.ignore_binary, series)
 
     # Fix up the patch files to our liking, and insert the cover letter
     patchstream.FixPatches(series, args)
diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py
index 4052975..4fe465e 100644
--- a/tools/patman/patchstream.py
+++ b/tools/patman/patchstream.py
@@ -24,11 +24,8 @@
 # Signoffs
 re_signoff = re.compile('^Signed-off-by: *(.*)')
 
-# The start of the cover letter
-re_cover = re.compile('^Cover-letter:')
-
-# A cover letter Cc
-re_cover_cc = re.compile('^Cover-letter-cc: *(.*)')
+# Cover letter tag
+re_cover = re.compile('^Cover-([a-z-]*): *(.*)')
 
 # Patch series tag
 re_series_tag = re.compile('^Series-([a-z-]*): *(.*)')
@@ -48,6 +45,9 @@
 # We detect these since checkpatch doesn't always do it
 re_space_before_tab = re.compile('^[+].* \t')
 
+# Match indented lines for changes
+re_leading_whitespace = re.compile('^\s')
+
 # States we can be in - can we use range() and still have comments?
 STATE_MSG_HEADER = 0        # Still in the message header
 STATE_PATCH_SUBJECT = 1     # In patch subject (first line of log for a commit)
@@ -65,7 +65,7 @@
     def __init__(self, series, name=None, is_log=False):
         self.skip_blank = False          # True to skip a single blank line
         self.found_test = False          # Found a TEST= line
-        self.lines_after_test = 0        # MNumber of lines found after TEST=
+        self.lines_after_test = 0        # Number of lines found after TEST=
         self.warn = []                   # List of warnings we have collected
         self.linenum = 1                 # Output line number we are up to
         self.in_section = None           # Name of start...END section we are in
@@ -73,7 +73,9 @@
         self.section = []                # The current section...END section
         self.series = series             # Info about the patch series
         self.is_log = is_log             # True if indent like git log
-        self.in_change = 0               # Non-zero if we are in a change list
+        self.in_change = None            # Name of the change list we are in
+        self.change_version = 0          # Non-zero if we are in a change list
+        self.change_lines = []           # Lines of the current change
         self.blank_count = 0             # Number of blank lines stored up
         self.state = STATE_MSG_HEADER    # What state are we in?
         self.signoff = []                # Contents of signoff line
@@ -124,6 +126,36 @@
             self.skip_blank = True
             self.section = []
 
+    def ParseVersion(self, value, line):
+        """Parse a version from a *-changes tag
+
+        Args:
+            value: Tag value (part after 'xxx-changes: '
+            line: Source line containing tag
+
+        Returns:
+            The version as an integer
+        """
+        try:
+            return int(value)
+        except ValueError as str:
+            raise ValueError("%s: Cannot decode version info '%s'" %
+                (self.commit.hash, line))
+
+    def FinalizeChange(self):
+        """Finalize a (multi-line) change and add it to the series or commit"""
+        if not self.change_lines:
+            return
+        change = '\n'.join(self.change_lines)
+
+        if self.in_change == 'Series':
+            self.series.AddChange(self.change_version, self.commit, change)
+        elif self.in_change == 'Cover':
+            self.series.AddChange(self.change_version, None, change)
+        elif self.in_change == 'Commit':
+            self.commit.AddChange(self.change_version, change)
+        self.change_lines = []
+
     def ProcessLine(self, line):
         """Process a single line of a patch file or commit log
 
@@ -163,8 +195,8 @@
         change_id_match = re_change_id.match(line)
         commit_tag_match = re_commit_tag.match(line)
         cover_match = re_cover.match(line)
-        cover_cc_match = re_cover_cc.match(line)
         signoff_match = re_signoff.match(line)
+        leading_whitespace_match = re_leading_whitespace.match(line)
         tag_match = None
         if self.state == STATE_PATCH_HEADER:
             tag_match = re_tag.match(line)
@@ -183,8 +215,7 @@
 
         # If a tag is detected, or a new commit starts
         if series_tag_match or commit_tag_match or change_id_match or \
-           cover_match or cover_cc_match or signoff_match or \
-           self.state == STATE_MSG_HEADER:
+           cover_match or signoff_match or self.state == STATE_MSG_HEADER:
             # but we are already in a section, this means 'END' is missing
             # for that section, fix it up.
             if self.in_section:
@@ -205,8 +236,10 @@
             # but we are already in a change list, that means a blank line
             # is missing, fix it up.
             if self.in_change:
-                self.warn.append("Missing 'blank line' in section 'Series-changes'")
-                self.in_change = 0
+                self.warn.append("Missing 'blank line' in section '%s-changes'" % self.in_change)
+                self.FinalizeChange()
+                self.in_change = None
+                self.change_version = 0
 
         # If we are in a section, keep collecting lines until we see END
         if self.in_section:
@@ -242,26 +275,35 @@
         elif self.skip_blank and is_blank:
             self.skip_blank = False
 
-        # Detect the start of a cover letter section
+        # Detect Cover-xxx tags
         elif cover_match:
-            self.in_section = 'cover'
-            self.skip_blank = False
-
-        elif cover_cc_match:
-            value = cover_cc_match.group(1)
-            self.AddToSeries(line, 'cover-cc', value)
+            name = cover_match.group(1)
+            value = cover_match.group(2)
+            if name == 'letter':
+                self.in_section = 'cover'
+                self.skip_blank = False
+            elif name == 'letter-cc':
+                self.AddToSeries(line, 'cover-cc', value)
+            elif name == 'changes':
+                self.in_change = 'Cover'
+                self.change_version = self.ParseVersion(value, line)
 
         # If we are in a change list, key collected lines until a blank one
         elif self.in_change:
             if is_blank:
                 # Blank line ends this change list
-                self.in_change = 0
+                self.FinalizeChange()
+                self.in_change = None
+                self.change_version = 0
             elif line == '---':
-                self.in_change = 0
+                self.FinalizeChange()
+                self.in_change = None
+                self.change_version = 0
                 out = self.ProcessLine(line)
-            else:
-                if self.is_log:
-                    self.series.AddChange(self.in_change, self.commit, line)
+            elif self.is_log:
+                if not leading_whitespace_match:
+                    self.FinalizeChange()
+                self.change_lines.append(line)
             self.skip_blank = False
 
         # Detect Series-xxx tags
@@ -270,12 +312,8 @@
             value = series_tag_match.group(2)
             if name == 'changes':
                 # value is the version number: e.g. 1, or 2
-                try:
-                    value = int(value)
-                except ValueError as str:
-                    raise ValueError("%s: Cannot decode version info '%s'" %
-                        (self.commit.hash, line))
-                self.in_change = int(value)
+                self.in_change = 'Series'
+                self.change_version = self.ParseVersion(value, line)
             else:
                 self.AddToSeries(line, name, value)
                 self.skip_blank = True
@@ -297,6 +335,9 @@
             if name == 'notes':
                 self.AddToCommit(line, name, value)
                 self.skip_blank = True
+            elif name == 'changes':
+                self.in_change = 'Commit'
+                self.change_version = self.ParseVersion(value, line)
 
         # Detect the start of a new commit
         elif commit_match:
@@ -340,7 +381,7 @@
             elif line == '---':
                 self.state = STATE_DIFFS
 
-                # Output the tags (signeoff first), then change list
+                # Output the tags (signoff first), then change list
                 out = []
                 log = self.series.MakeChangeLog(self.commit)
                 out += [line]
@@ -355,6 +396,7 @@
 
     def Finalize(self):
         """Close out processing of this patch stream"""
+        self.FinalizeChange()
         self.CloseCommit()
         if self.lines_after_test:
             self.warn.append('Found %d lines after TEST=' %
diff --git a/tools/patman/series.py b/tools/patman/series.py
index e5e28ce..ca7ca55 100644
--- a/tools/patman/series.py
+++ b/tools/patman/series.py
@@ -2,6 +2,9 @@
 # Copyright (c) 2011 The Chromium OS Authors.
 #
 
+from __future__ import print_function
+
+import collections
 import itertools
 import os
 
@@ -144,38 +147,65 @@
             Changes in v4:
             - Jog the dial back closer to the widget
 
-            Changes in v3: None
             Changes in v2:
             - Fix the widget
             - Jog the dial
 
-            etc.
+            If there are no new changes in a patch, a note will be added
+
+            (no changes since v2)
+
+            Changes in v2:
+            - Fix the widget
+            - Jog the dial
         """
+        # Collect changes from the series and this commit
+        changes = collections.defaultdict(list)
+        for version, changelist in self.changes.items():
+            changes[version] += changelist
+        if commit:
+            for version, changelist in commit.changes.items():
+                changes[version] += [[commit, text] for text in changelist]
+
+        versions = sorted(changes, reverse=True)
+        newest_version = 1
+        if 'version' in self:
+            newest_version = max(newest_version, int(self.version))
+        if versions:
+            newest_version = max(newest_version, versions[0])
+
         final = []
         process_it = self.get('process_log', '').split(',')
         process_it = [item.strip() for item in process_it]
         need_blank = False
-        for change in sorted(self.changes, reverse=True):
+        for version in versions:
             out = []
-            for this_commit, text in self.changes[change]:
+            for this_commit, text in changes[version]:
                 if commit and this_commit != commit:
                     continue
                 if 'uniq' not in process_it or text not in out:
                     out.append(text)
-            line = 'Changes in v%d:' % change
-            have_changes = len(out) > 0
             if 'sort' in process_it:
                 out = sorted(out)
+            have_changes = len(out) > 0
+            line = 'Changes in v%d:' % version
             if have_changes:
                 out.insert(0, line)
-            else:
-                out = [line + ' None']
-            if need_blank:
-                out.insert(0, '')
+                if version < newest_version and len(final) == 0:
+                    out.insert(0, '')
+                    out.insert(0, '(no changes since v%d)' % version)
+                    newest_version = 0
+                # Only add a new line if we output something
+                if need_blank:
+                    out.insert(0, '')
+                    need_blank = False
             final += out
-            need_blank = have_changes
-        if self.changes:
+            need_blank = need_blank or have_changes
+
+        if len(final) > 0:
             final.append('')
+        elif newest_version != 1:
+            final = ['(no changes since v1)', '']
         return final
 
     def DoChecks(self):
diff --git a/tools/patman/test/0001-pci-Correct-cast-for-sandbox.patch b/tools/patman/test/0001-pci-Correct-cast-for-sandbox.patch
index 7191176..038943c 100644
--- a/tools/patman/test/0001-pci-Correct-cast-for-sandbox.patch
+++ b/tools/patman/test/0001-pci-Correct-cast-for-sandbox.patch
@@ -15,6 +15,9 @@
 Fix it with a cast.
 
 Signed-off-by: Simon Glass <sjg@chromium.org>
+Commit-changes: 2
+- Changes only for this commit
+
 Series-notes:
 some notes
 about some things
diff --git a/tools/patman/test/0002-fdt-Correct-cast-for-sandbox-in-fdtdec_setup_mem_siz.patch b/tools/patman/test/0002-fdt-Correct-cast-for-sandbox-in-fdtdec_setup_mem_siz.patch
index 702c030..56278a6 100644
--- a/tools/patman/test/0002-fdt-Correct-cast-for-sandbox-in-fdtdec_setup_mem_siz.patch
+++ b/tools/patman/test/0002-fdt-Correct-cast-for-sandbox-in-fdtdec_setup_mem_siz.patch
@@ -21,13 +21,23 @@
 Cover-letter-cc: Lord Mëlchett <clergy@palace.gov>
 Series-version: 3
 Patch-cc: fred
+Series-process-log: sort, uniq
 Series-changes: 4
 - Some changes
+- Multi
+  line
+  change
+
+Commit-changes: 2
+- Changes only for this commit
+
+Cover-changes: 4
+- Some notes for the cover letter
 
 Cover-letter:
 test: A test patch series
 This is a test of how the cover
-leter
+letter
 works
 END
 ---
diff --git a/tools/patman/test/test01.txt b/tools/patman/test/test01.txt
index 478ea93..b238a8b 100644
--- a/tools/patman/test/test01.txt
+++ b/tools/patman/test/test01.txt
@@ -13,6 +13,9 @@
     Fix it with a cast.
     
     Signed-off-by: Simon Glass <sjg@chromium.org>
+    Commit-changes: 2
+    - second revision change
+
     Series-notes:
     some notes
     about some things
@@ -45,12 +48,22 @@
     Cover-letter-cc: Lord Mëlchett <clergy@palace.gov>
     Series-version: 3
     Patch-cc: fred
+    Series-process-log: sort, uniq
     Series-changes: 4
     - Some changes
+    - Multi
+      line
+      change
+
+    Commit-changes: 2
+    - Changes only for this commit
+
+    Cover-changes: 4
+    - Some notes for the cover letter
     
     Cover-letter:
     test: A test patch series
     This is a test of how the cover
-    leter
+    letter
     works
     END