Merge branch 'master' of git://git.denx.de/u-boot-spi
diff --git a/Makefile b/Makefile
index f03d116..cbd45a7 100644
--- a/Makefile
+++ b/Makefile
@@ -163,7 +163,7 @@
 include $(TOPDIR)/config.mk
 
 # Targets which don't build the source code
-NON_BUILD_TARGETS = backup clean clobber distclean mkproper tidy unconfig
+NON_BUILD_TARGETS = backup clean clobber distclean mrproper tidy unconfig
 
 # Only do the generic board check when actually building, not configuring
 ifeq ($(filter $(NON_BUILD_TARGETS),$(MAKECMDGOALS)),)
@@ -471,12 +471,10 @@
 $(obj)u-boot.spr:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
 		$(obj)tools/mkimage -A $(ARCH) -T firmware -C none \
 		-a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) -n XLOADER \
-		-d $(obj)spl/u-boot-spl.bin $(obj)spl/u-boot-spl.img
-		tr "\000" "\377" < /dev/zero | dd ibs=1 count=$(CONFIG_SPL_PAD_TO) \
-			of=$(obj)spl/u-boot-spl-pad.img 2>/dev/null
-		dd if=$(obj)spl/u-boot-spl.img of=$(obj)spl/u-boot-spl-pad.img \
-			conv=notrunc 2>/dev/null
-		cat $(obj)spl/u-boot-spl-pad.img $(obj)u-boot.img > $@
+		-d $(obj)spl/u-boot-spl.bin $@
+		$(OBJCOPY) -I binary -O binary \
+			--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff $@
+		cat $(obj)u-boot.img >> $@
 
 ifneq ($(CONFIG_TEGRA),)
 $(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
@@ -499,11 +497,9 @@
 # at the start padded up to the start of the SPL image. And then concat
 # the SPL image to the end.
 $(obj)u-boot-img-spl-at-end.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
-		tr "\000" "\377" < /dev/zero | dd ibs=1 count=$(CONFIG_UBOOT_PAD_TO) \
-			of=$(obj)u-boot-pad.img 2>/dev/null
-		dd if=$(obj)u-boot.img of=$(obj)u-boot-pad.img \
-			conv=notrunc 2>/dev/null
-		cat $(obj)u-boot-pad.img $(obj)spl/u-boot-spl.bin > $@
+		$(OBJCOPY) -I binary -O binary --pad-to=$(CONFIG_UBOOT_PAD_TO) \
+			 --gap-fill=0xff $(obj)u-boot.img $@
+		cat $(obj)spl/u-boot-spl.bin >> $@
 
 ifeq ($(CONFIG_SANDBOX),y)
 GEN_UBOOT = \
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index 1eb92e5..07011e9 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -74,6 +74,11 @@
 	return dfu_buf;
 }
 
+unsigned long dfu_get_buf_size(void)
+{
+	return dfu_buf_size;
+}
+
 unsigned char *dfu_get_buf(void)
 {
 	char *s;
diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
index eeaa7e8..b292826 100644
--- a/drivers/mtd/nand/nand_util.c
+++ b/drivers/mtd/nand/nand_util.c
@@ -315,7 +315,7 @@
 	int page;
 	struct nand_chip *chip = mtd->priv;
 
-	debug("nand_unlock%s: start: %08llx, length: %d!\n",
+	debug("nand_unlock%s: start: %08llx, length: %zd!\n",
 		allexcept ? " (allexcept)" : "", start, length);
 
 	/* select the NAND device */
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index 5e7e6b3..790d5385 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -283,53 +283,55 @@
 	if (bch->ecc_scheme == OMAP_ECC_BCH8_CODE_HW) {
 		wr_mode = BCH_WRAPMODE_1;
 
-	switch (bch->nibbles) {
-	case ECC_BCH4_NIBBLES:
-		unused_length = 3;
-		break;
-	case ECC_BCH8_NIBBLES:
-		unused_length = 2;
-		break;
-	case ECC_BCH16_NIBBLES:
-		unused_length = 0;
-		break;
-	}
-
-	/*
-	 * This is ecc_size_config for ELM mode.
-	 * Here we are using different settings for read and write access and
-	 * also depending on BCH strength.
-	 */
-	switch (mode) {
-	case NAND_ECC_WRITE:
-		/* write access only setup eccsize1 config */
-		val = ((unused_length + bch->nibbles) << 22);
-		break;
+		switch (bch->nibbles) {
+		case ECC_BCH4_NIBBLES:
+			unused_length = 3;
+			break;
+		case ECC_BCH8_NIBBLES:
+			unused_length = 2;
+			break;
+		case ECC_BCH16_NIBBLES:
+			unused_length = 0;
+			break;
+		}
 
-	case NAND_ECC_READ:
-	default:
 		/*
-		 * by default eccsize0 selected for ecc1resultsize
-		 * eccsize0 config.
+		 * This is ecc_size_config for ELM mode.  Here we are using
+		 * different settings for read and write access and also
+		 * depending on BCH strength.
 		 */
-		val  = (bch->nibbles << 12);
-		/* eccsize1 config */
-		val |= (unused_length << 22);
-		break;
-	}
+		switch (mode) {
+		case NAND_ECC_WRITE:
+			/* write access only setup eccsize1 config */
+			val = ((unused_length + bch->nibbles) << 22);
+			break;
+
+		case NAND_ECC_READ:
+		default:
+			/*
+			 * by default eccsize0 selected for ecc1resultsize
+			 * eccsize0 config.
+			 */
+			val  = (bch->nibbles << 12);
+			/* eccsize1 config */
+			val |= (unused_length << 22);
+			break;
+		}
 	} else {
-	/*
-	 * This ecc_size_config setting is for BCH sw library.
-	 *
-	 * Note: we only support BCH8 currently with BCH sw library!
-	 * Should be really easy to adobt to BCH4, however some omap3 have
-	 * flaws with BCH4.
-	 *
-	 * Here we are using wrapping mode 6 both for reading and writing, with:
-	 *  size0 = 0  (no additional protected byte in spare area)
-	 *  size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
-	 */
-	val = (32 << 22) | (0 << 12);
+		/*
+		 * This ecc_size_config setting is for BCH sw library.
+		 *
+		 * Note: we only support BCH8 currently with BCH sw library!
+		 * Should be really easy to adobt to BCH4, however some omap3
+		 * have flaws with BCH4.
+		 *
+		 * Here we are using wrapping mode 6 both for reading and
+		 * writing, with:
+		 *  size0 = 0  (no additional protected byte in spare area)
+		 *  size1 = 32 (skip 32 nibbles = 16 bytes per sector in
+		 *		spare area)
+		 */
+		val = (32 << 22) | (0 << 12);
 	}
 	/* ecc size configuration */
 	writel(val, &gpmc_cfg->ecc_size_config);
@@ -761,7 +763,7 @@
 static int omap_select_ecc_scheme(struct nand_chip *nand,
 	enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {
 	struct nand_bch_priv	*bch		= nand->priv;
-	struct nand_ecclayout	*ecclayout	= nand->ecc.layout;
+	struct nand_ecclayout	*ecclayout	= &omap_ecclayout;
 	int eccsteps = pagesize / SECTOR_BYTES;
 	int i;
 
@@ -774,7 +776,7 @@
 		bch_priv.type		= 0;
 		nand->ecc.mode		= NAND_ECC_SOFT;
 		nand->ecc.layout	= NULL;
-		nand->ecc.size		= pagesize;
+		nand->ecc.size		= 0;
 		bch->ecc_scheme		= OMAP_ECC_HAM1_CODE_SW;
 		break;
 
@@ -789,6 +791,7 @@
 		bch_priv.control	= NULL;
 		bch_priv.type		= 0;
 		/* populate ecc specific fields */
+		memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
 		nand->ecc.mode		= NAND_ECC_HW;
 		nand->ecc.strength	= 1;
 		nand->ecc.size		= SECTOR_BYTES;
@@ -798,8 +801,12 @@
 		nand->ecc.calculate	= omap_calculate_ecc;
 		/* define ecc-layout */
 		ecclayout->eccbytes	= nand->ecc.bytes * eccsteps;
-		for (i = 0; i < ecclayout->eccbytes; i++)
-			ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
+		for (i = 0; i < ecclayout->eccbytes; i++) {
+			if (nand->options & NAND_BUSWIDTH_16)
+				ecclayout->eccpos[i] = i + 2;
+			else
+				ecclayout->eccpos[i] = i + 1;
+		}
 		ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
 		ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
 						BADBLOCK_MARKER_LENGTH;
@@ -823,6 +830,7 @@
 		}
 		bch_priv.type = ECC_BCH8;
 		/* populate ecc specific fields */
+		memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
 		nand->ecc.mode		= NAND_ECC_HW;
 		nand->ecc.strength	= 8;
 		nand->ecc.size		= SECTOR_BYTES;
@@ -865,6 +873,7 @@
 		elm_init();
 		bch_priv.type		= ECC_BCH8;
 		/* populate ecc specific fields */
+		memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
 		nand->ecc.mode		= NAND_ECC_HW;
 		nand->ecc.strength	= 8;
 		nand->ecc.size		= SECTOR_BYTES;
@@ -891,6 +900,11 @@
 		debug("nand: error: ecc scheme not enabled or supported\n");
 		return -EINVAL;
 	}
+
+	/* nand_scan_tail() sets ham1 sw ecc; hw ecc layout is set by driver */
+	if (ecc_scheme != OMAP_ECC_HAM1_CODE_SW)
+		nand->ecc.layout = ecclayout;
+
 	return 0;
 }
 
diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c
index 37d04a1..a045864 100644
--- a/drivers/usb/gadget/f_dfu.c
+++ b/drivers/usb/gadget/f_dfu.c
@@ -40,6 +40,7 @@
 
 	/* Send/received block number is handy for data integrity check */
 	int                             blk_seq_num;
+	unsigned int                    poll_timeout;
 };
 
 typedef int (*dfu_state_fn) (struct f_dfu *,
@@ -128,6 +129,33 @@
 	NULL,
 };
 
+static void dfu_set_poll_timeout(struct dfu_status *dstat, unsigned int ms)
+{
+	/*
+	 * The bwPollTimeout DFU_GETSTATUS request payload provides information
+	 * about minimum time, in milliseconds, that the host should wait before
+	 * sending a subsequent DFU_GETSTATUS request
+	 *
+	 * This permits the device to vary the delay depending on its need to
+	 * erase or program the memory
+	 *
+	 */
+
+	unsigned char *p = (unsigned char *)&ms;
+
+	if (!ms || (ms & ~DFU_POLL_TIMEOUT_MASK)) {
+		dstat->bwPollTimeout[0] = 0;
+		dstat->bwPollTimeout[1] = 0;
+		dstat->bwPollTimeout[2] = 0;
+
+		return;
+	}
+
+	dstat->bwPollTimeout[0] = *p++;
+	dstat->bwPollTimeout[1] = *p++;
+	dstat->bwPollTimeout[2] = *p;
+}
+
 /*-------------------------------------------------------------------------*/
 
 static void dnload_request_complete(struct usb_ep *ep, struct usb_request *req)
@@ -157,11 +185,15 @@
 		break;
 	}
 
+	dfu_set_poll_timeout(dstat, 0);
+
+	if (f_dfu->poll_timeout)
+		if (!(f_dfu->blk_seq_num %
+		      (dfu_get_buf_size() / DFU_USB_BUFSIZ)))
+			dfu_set_poll_timeout(dstat, f_dfu->poll_timeout);
+
 	/* send status response */
 	dstat->bStatus = f_dfu->dfu_status;
-	dstat->bwPollTimeout[0] = 0;
-	dstat->bwPollTimeout[1] = 0;
-	dstat->bwPollTimeout[2] = 0;
 	dstat->bState = f_dfu->dfu_state;
 	dstat->iString = 0;
 }
@@ -723,8 +755,9 @@
 	f_dfu->usb_function.unbind = dfu_unbind;
 	f_dfu->usb_function.set_alt = dfu_set_alt;
 	f_dfu->usb_function.disable = dfu_disable;
-	f_dfu->usb_function.strings = dfu_generic_strings,
-	f_dfu->usb_function.setup = dfu_handle,
+	f_dfu->usb_function.strings = dfu_generic_strings;
+	f_dfu->usb_function.setup = dfu_handle;
+	f_dfu->poll_timeout = DFU_DEFAULT_POLL_TIMEOUT;
 
 	status = usb_add_function(c, &f_dfu->usb_function);
 	if (status)
diff --git a/drivers/usb/gadget/f_dfu.h b/drivers/usb/gadget/f_dfu.h
index cc2c455..0c29954 100644
--- a/drivers/usb/gadget/f_dfu.h
+++ b/drivers/usb/gadget/f_dfu.h
@@ -82,4 +82,6 @@
 	__le16				wTransferSize;
 	__le16				bcdDFUVersion;
 } __packed;
+
+#define DFU_POLL_TIMEOUT_MASK           (0xFFFFFFUL)
 #endif /* __F_DFU_H_ */
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 8bd1eb8..17187ca 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -201,6 +201,9 @@
 	int i, ret = 0;
 	uint32_t cmd, reg;
 
+	if (!ctrl || !ctrl->hcor)
+		return -EINVAL;
+
 	cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
 	cmd &= ~(CMD_PSE | CMD_ASE);
 	ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
@@ -945,7 +948,7 @@
 #endif
 	/* Set the high address word (aka segment) for 64-bit controller */
 	if (ehci_readl(&ehcic[index].hccr->cr_hccparams) & 1)
-		ehci_writel(ehcic[index].hcor->or_ctrldssegment, 0);
+		ehci_writel(&ehcic[index].hcor->or_ctrldssegment, 0);
 
 	qh_list = &ehcic[index].qh_list;
 
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 7a1ffe5..991b199 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -54,9 +54,31 @@
 					bdf += PCI_BDF(0, 0, 1)) {
 				pci_read_config_dword(bdf, PCI_CLASS_REVISION,
 						      &class);
-				if ((class >> 8 == PCI_CLASS_SERIAL_USB_EHCI)
-						&& !index--)
-					return bdf;
+				class >>= 8;
+				/*
+				 * Here be dragons! In case we have multiple
+				 * PCI EHCI controllers, this function will
+				 * be called multiple times as well. This
+				 * function will scan the PCI busses, always
+				 * starting from bus 0, device 0, function 0,
+				 * until it finds an USB controller. The USB
+				 * stack gives us an 'index' of a controller
+				 * that is currently being registered, which
+				 * is a number, starting from 0 and growing
+				 * in ascending order as controllers are added.
+				 * To avoid probing the same controller in tne
+				 * subsequent runs of this function, we will
+				 * skip 'index - 1' detected controllers and
+				 * report the index'th controller.
+				 */
+				if (class != PCI_CLASS_SERIAL_USB_EHCI)
+					continue;
+				if (index) {
+					index--;
+					continue;
+				}
+				/* Return index'th controller. */
+				return bdf;
 			}
 		}
 	}
diff --git a/include/configs/trats.h b/include/configs/trats.h
index 0877142..6cd15c2 100644
--- a/include/configs/trats.h
+++ b/include/configs/trats.h
@@ -99,6 +99,7 @@
 #define CONFIG_THOR_FUNCTION
 
 #define CONFIG_SYS_DFU_DATA_BUF_SIZE SZ_32M
+#define DFU_DEFAULT_POLL_TIMEOUT 300
 #define CONFIG_DFU_FUNCTION
 #define CONFIG_DFU_MMC
 
diff --git a/include/dfu.h b/include/dfu.h
index cc14044..f973426 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -77,6 +77,9 @@
 #ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE
 #define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE
 #endif
+#ifndef DFU_DEFAULT_POLL_TIMEOUT
+#define DFU_DEFAULT_POLL_TIMEOUT 0
+#endif
 
 struct dfu_entity {
 	char			name[DFU_NAME_SIZE];
@@ -131,6 +134,7 @@
 int dfu_init_env_entities(char *interface, int dev);
 unsigned char *dfu_get_buf(void);
 unsigned char *dfu_free_buf(void);
+unsigned long dfu_get_buf_size(void);
 
 int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
 int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num);