Merge "ipq807x: Device tree support in u-boot for HK08"
diff --git a/common/usb_hub.c b/common/usb_hub.c
index e1de813..0eb8f15 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -55,11 +55,31 @@
 	return;
 }
 
+static inline bool usb_hub_is_superspeed(struct usb_device *hdev)
+{
+	return hdev->descriptor.bDeviceProtocol == 3;
+}
+
+#ifdef CONFIG_DM_USB
+bool usb_hub_is_root_hub(struct udevice *hub)
+{
+	if (device_get_uclass_id(hub->parent) != UCLASS_USB_HUB)
+		return true;
+
+	return false;
+}
+#endif
+
 static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
 {
+	unsigned short dtype = USB_DT_HUB;
+
+	if (usb_hub_is_superspeed(dev))
+		dtype = USB_DT_SS_HUB;
+
 	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 		USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
-		USB_DT_HUB << 8, 0, data, size, USB_CNTL_TIMEOUT);
+		dtype << 8, 0, data, size, USB_CNTL_TIMEOUT);
 }
 
 static int usb_clear_port_feature(struct usb_device *dev, int port, int feature)
@@ -371,17 +391,19 @@
 			&descriptor->wHubCharacteristics)),
 			&hub->desc.wHubCharacteristics);
 	/* set the bitmap */
-	bitmap = (unsigned char *)&hub->desc.DeviceRemovable[0];
+	bitmap = (unsigned char *)&hub->desc.u.hs.DeviceRemovable[0];
 	/* devices not removable by default */
 	memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8);
-	bitmap = (unsigned char *)&hub->desc.PortPowerCtrlMask[0];
+	bitmap = (unsigned char *)&hub->desc.u.hs.PortPowerCtrlMask[0];
 	memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8); /* PowerMask = 1B */
 
 	for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++)
-		hub->desc.DeviceRemovable[i] = descriptor->DeviceRemovable[i];
+		hub->desc.u.hs.DeviceRemovable[i] =
+			descriptor->u.hs.DeviceRemovable[i];
 
 	for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++)
-		hub->desc.PortPowerCtrlMask[i] = descriptor->PortPowerCtrlMask[i];
+		hub->desc.u.hs.PortPowerCtrlMask[i] =
+			descriptor->u.hs.PortPowerCtrlMask[i];
 
 	dev->maxchild = descriptor->bNbrPorts;
 	debug("%d ports detected\n", dev->maxchild);
@@ -425,7 +447,7 @@
 
 	for (i = 0; i < dev->maxchild; i++)
 		debug("port %d is%s removable\n", i + 1,
-		      hub->desc.DeviceRemovable[(i + 1) / 8] & \
+		      hub->desc.u.hs.DeviceRemovable[(i + 1) / 8] & \
 		      (1 << ((i + 1) % 8)) ? " not" : "");
 
 	if (sizeof(struct usb_hub_status) > USB_BUFSIZ) {
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index e2c3c86..34ab736 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1515,6 +1515,9 @@
 	if (((mmc->cid[0] & MMC_MID_MASK) == MMC_MID_SANDISK) &&
 		(strncmp(mmc->block_dev.product, "SEM08", 5) == 0))
 		mmc->quirks |= MMC_QUIRK_SECURE_TRIM;
+	if (((mmc->cid[0] & MMC_MID_MASK) == MMC_MID_TOSHIBA) &&
+		(strncmp(mmc->block_dev.product, "004GE", 5) == 0))
+		mmc->quirks |= MMC_QUIRK_SECURE_TRIM;
 
 	return 0;
 }
diff --git a/drivers/mtd/nand/qpic_nand.c b/drivers/mtd/nand/qpic_nand.c
index c71525a..bb9f9dc 100644
--- a/drivers/mtd/nand/qpic_nand.c
+++ b/drivers/mtd/nand/qpic_nand.c
@@ -1538,13 +1538,20 @@
  * length.
  */
 static u_long qpic_get_read_page_count(struct mtd_info *mtd,
-                      struct mtd_oob_ops *ops)
+				       struct mtd_oob_ops *ops, loff_t to)
 {
 	struct qpic_nand_dev *dev = MTD_QPIC_NAND_DEV(mtd);
 	struct nand_chip *chip = MTD_NAND_CHIP(mtd);
+	uint32_t start_page, end_page;
 
 	if (ops->datbuf != NULL) {
-		return (ops->len + mtd->writesize - 1) >> chip->page_shift;
+		/*
+		 * Determine start page (can be non page aligned) and end page
+		 * and calculate number of pages.
+		 */
+		start_page = to >> chip->page_shift;
+		end_page = (to + ops->len - 1) >> chip->page_shift;
+		return end_page - start_page + 1;
 	} else {
 	if (dev->oob_per_page == 0)
 		return 0;
@@ -1579,7 +1586,7 @@
  * data, return an internal buffer, to hold the data temporarily.
  */
 static uint8_t *qpic_nand_read_datbuf(struct mtd_info *mtd,
-				     struct mtd_oob_ops *ops)
+				     struct mtd_oob_ops *ops, uint32_t col)
 {
 	size_t read_datlen;
 	struct qpic_nand_dev *dev = MTD_QPIC_NAND_DEV(mtd);
@@ -1588,7 +1595,7 @@
 		return NULL;
 
 	read_datlen = ops->len - ops->retlen;
-	if (read_datlen < mtd->writesize)
+	if (read_datlen < mtd->writesize || col)
 		return dev->pad_dat;
 
 	return ops->datbuf + ops->retlen;
@@ -1620,7 +1627,9 @@
  * Copy the in-band data from the internal buffer, to the user buffer,
  * if the internal buffer was used for the read.
  */
-static void qpic_nand_read_datcopy(struct mtd_info *mtd, struct mtd_oob_ops *ops)
+static void
+qpic_nand_read_datcopy(struct mtd_info *mtd,
+		       struct mtd_oob_ops *ops, uint32_t col)
 {
 	size_t datlen;
 	size_t read_datlen;
@@ -1630,10 +1639,13 @@
 		return;
 
 	read_datlen = ops->len - ops->retlen;
-	datlen = (read_datlen < mtd->writesize ? read_datlen : mtd->writesize);
 
-	if (read_datlen < mtd->writesize)
-		memcpy(ops->datbuf + ops->retlen, dev->pad_dat, datlen);
+	if (col == 0 && read_datlen >= mtd->writesize) {
+		datlen = mtd->writesize;
+	} else {
+		datlen = min(read_datlen, mtd->writesize - col);
+		memcpy(ops->datbuf + ops->retlen, dev->pad_dat + col, datlen);
+	}
 
 	ops->retlen += datlen;
 }
@@ -1998,6 +2010,7 @@
 	struct nand_chip *chip = MTD_NAND_CHIP(mtd);
 	uint32_t start_page;
 	uint32_t num_pages;
+	uint32_t col;
 	enum nand_cfg_value cfg_mode;
 	unsigned int max_bitflips = 0;
 	unsigned int ecc_failures = mtd->ecc_stats.failed;
@@ -2010,9 +2023,6 @@
 	if (ops->datbuf && (to + ops->len) > mtd->size)
 		return -EINVAL;
 
-	if (to & (mtd->writesize - 1))
-		return -EINVAL;
-
 	if (ops->ooboffs != 0)
 		return -EINVAL;
 
@@ -2025,14 +2035,20 @@
 	}
 
 	start_page = ((to >> chip->page_shift));
-	num_pages = qpic_get_read_page_count(mtd, ops);
+	num_pages = qpic_get_read_page_count(mtd, ops, to);
 
 	for (i = 0; i < num_pages; i++) {
 		struct mtd_oob_ops page_ops;
+
+		/*
+		 * If start address is non page alinged then determine the
+		 * column offset
+		 */
+		col = i == 0 ? to & (mtd->writesize - 1) : 0;
 		page_ops.mode = ops->mode;
 		page_ops.len = mtd->writesize;
 		page_ops.ooblen = dev->oob_per_page;
-		page_ops.datbuf = qpic_nand_read_datbuf(mtd, ops);
+		page_ops.datbuf = qpic_nand_read_datbuf(mtd, ops, col);
 		page_ops.oobbuf = qpic_nand_read_oobbuf(mtd, ops);
 		page_ops.retlen = 0;
 		page_ops.oobretlen = 0;
@@ -2046,7 +2062,7 @@
 		}
 
 		max_bitflips = max_t(unsigned int, max_bitflips, ret);
-		qpic_nand_read_datcopy(mtd, ops);
+		qpic_nand_read_datcopy(mtd, ops, col);
 		qpic_nand_read_oobcopy(mtd, ops);
 	}
 
diff --git a/drivers/usb/emul/sandbox_hub.c b/drivers/usb/emul/sandbox_hub.c
index 624fbde..a86aa7a 100644
--- a/drivers/usb/emul/sandbox_hub.c
+++ b/drivers/usb/emul/sandbox_hub.c
@@ -96,7 +96,12 @@
 								1 << 7),
 	.bPwrOn2PwrGood		= 2,
 	.bHubContrCurrent	= 5,
-	.DeviceRemovable	= {0, 0xff}, /* all ports removeable */
+	{
+		{
+			/* all ports removeable */
+			.DeviceRemovable	= {0, 0xff}
+		}
+	}
 #if SANDBOX_NUM_PORTS > 8
 #error "This code sets up an incorrect mask"
 #endif
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index c664b16..ba12808 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -52,8 +52,8 @@
 		0,		/* wHubCharacteristics */
 		10,		/* bPwrOn2PwrGood */
 		0,		/* bHubCntrCurrent */
-		{},		/* Device removable */
-		{}		/* at most 7 ports! XXX */
+		{		/* Device removable */
+		}		/* at most 7 ports! XXX */
 	},
 	{
 		0x12,		/* bLength */
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index d599117..3a0c79d 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -50,8 +50,8 @@
 		cpu_to_le16(0x8), /* wHubCharacteristics */
 		10,		/* bPwrOn2PwrGood */
 		0,		/* bHubCntrCurrent */
-		{},		/* Device removable */
-		{}		/* at most 7 ports! XXX */
+		{		/* Device removable */
+		}		/* at most 7 ports! XXX */
 	},
 	{
 		0x12,		/* bLength */
@@ -727,6 +727,7 @@
 	case USB_REQ_GET_DESCRIPTOR | ((USB_DIR_IN | USB_RT_HUB) << 8):
 		switch (le16_to_cpu(req->value) >> 8) {
 		case USB_DT_HUB:
+		case USB_DT_SS_HUB:
 			debug("USB_DT_HUB config\n");
 			srcptr = &descriptor.hub;
 			srclen = 0x8;
@@ -1111,26 +1112,6 @@
 #endif /* CONFIG_DM_USB */
 
 #ifdef CONFIG_DM_USB
-/*
-static struct usb_device *get_usb_device(struct udevice *dev)
-{
-	struct usb_device *udev;
-
-	if (device_get_uclass_id(dev) == UCLASS_USB)
-		udev = dev_get_uclass_priv(dev);
-	else
-		udev = dev_get_parent_priv(dev);
-
-	return udev;
-}
-*/
-static bool is_root_hub(struct udevice *dev)
-{
-	if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB)
-		return true;
-
-	return false;
-}
 
 static int xhci_submit_control_msg(struct udevice *dev, struct usb_device *udev,
 				   unsigned long pipe, void *buffer, int length,
@@ -1145,10 +1126,10 @@
 	hub = udev->dev;
 	if (device_get_uclass_id(hub) == UCLASS_USB_HUB) {
 		/* Figure out our port number on the root hub */
-		if (is_root_hub(hub)) {
+		if (usb_hub_is_root_hub(hub)) {
 			root_portnr = udev->portnr;
 		} else {
-			while (!is_root_hub(hub->parent))
+			while (!usb_hub_is_root_hub(hub->parent))
 				hub = hub->parent;
 			uhop = dev_get_parent_priv(hub);
 			root_portnr = uhop->portnr;
diff --git a/include/mmc.h b/include/mmc.h
index 68bd128..ee18ae3 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -301,6 +301,7 @@
 
 #define MMC_MID_MASK (0xFF << 24)
 #define MMC_MID_SANDISK (0x45 << 24)
+#define MMC_MID_TOSHIBA (0x11 << 24)
 
 /*
  * Quirks
diff --git a/include/usb.h b/include/usb.h
index 0b410b6..f2bd76e 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -546,10 +546,20 @@
 	unsigned short wHubCharacteristics;
 	unsigned char  bPwrOn2PwrGood;
 	unsigned char  bHubContrCurrent;
-	unsigned char  DeviceRemovable[(USB_MAXCHILDREN+1+7)/8];
-	unsigned char  PortPowerCtrlMask[(USB_MAXCHILDREN+1+7)/8];
-	/* DeviceRemovable and PortPwrCtrlMask want to be variable-length
-	   bitmaps that hold max 255 entries. (bit0 is ignored) */
+	/* 2.0 and 3.0 hubs differ here */
+	union {
+		struct {
+			/* add 1 bit for hub status change; round to bytes */
+			__u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8];
+			__u8 PortPowerCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
+		} __attribute__ ((packed)) hs;
+
+		struct {
+			__u8 bHubHdrDecLat;
+			__le16 wHubDelay;
+			__le16 DeviceRemovable;
+		} __attribute__ ((packed)) ss;
+	} u;
 } __attribute__ ((packed));
 
 
@@ -762,6 +772,14 @@
 		     struct usb_device *parent);
 
 /**
+ * usb_hub_is_root_hub() - Test whether a hub device is root hub or not
+ *
+ * @hub:	USB hub device to test
+ * @return:	true if the hub device is root hub, false otherwise.
+ */
+bool usb_hub_is_root_hub(struct udevice *hub);
+
+/**
  * usb_hub_scan() - Scan a hub and find its devices
  *
  * @hub:	Hub device to scan
diff --git a/include/usb_defs.h b/include/usb_defs.h
index 8214ba9..608a0ca 100644
--- a/include/usb_defs.h
+++ b/include/usb_defs.h
@@ -93,6 +93,7 @@
 #define USB_DT_REPORT       (USB_TYPE_CLASS | 0x02)
 #define USB_DT_PHYSICAL     (USB_TYPE_CLASS | 0x03)
 #define USB_DT_HUB          (USB_TYPE_CLASS | 0x09)
+#define USB_DT_SS_HUB       (USB_TYPE_CLASS | 0x0a)
 
 /* Descriptor sizes per descriptor type */
 #define USB_DT_DEVICE_SIZE      18