summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/dwc3/core.c26
-rw-r--r--drivers/usb/dwc3/dwc3-generic.c105
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c4
-rw-r--r--drivers/usb/gadget/Kconfig15
-rw-r--r--drivers/usb/gadget/f_acm.c9
-rw-r--r--drivers/usb/gadget/f_mass_storage.c102
-rw-r--r--drivers/usb/gadget/storage_common.c12
-rw-r--r--drivers/usb/host/ehci-msm.c22
8 files changed, 230 insertions, 65 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 4b4fcd8a22e..96e850b7170 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -983,18 +983,32 @@ void dwc3_uboot_exit(int index)
}
}
+MODULE_ALIAS("platform:dwc3");
+MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
+
+#if !CONFIG_IS_ENABLED(DM_USB_GADGET)
+__weak int dwc3_uboot_interrupt_status(struct udevice *dev)
+{
+ return 1;
+}
+
/**
- * dwc3_uboot_handle_interrupt - handle dwc3 core interrupt
+ * dm_usb_gadget_handle_interrupts - handle dwc3 core interrupt
* @dev: device of this controller
*
* Invokes dwc3 gadget interrupts.
*
* Generally called from board file.
*/
-void dwc3_uboot_handle_interrupt(struct udevice *dev)
+int dm_usb_gadget_handle_interrupts(struct udevice *dev)
{
struct dwc3 *dwc = NULL;
+ if (!dwc3_uboot_interrupt_status(dev))
+ return 0;
+
list_for_each_entry(dwc, &dwc3_list, list) {
if (dwc->dev != dev)
continue;
@@ -1002,12 +1016,10 @@ void dwc3_uboot_handle_interrupt(struct udevice *dev)
dwc3_gadget_uboot_handle_interrupt(dwc);
break;
}
-}
-MODULE_ALIAS("platform:dwc3");
-MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
+ return 0;
+}
+#endif
#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB)
int dwc3_setup_phy(struct udevice *dev, struct phy_bulk *phys)
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 6fb2de8a5ac..7a00529a2a8 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -21,6 +21,7 @@
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <malloc.h>
+#include <power/regulator.h>
#include <usb.h>
#include "core.h"
#include "gadget.h"
@@ -47,6 +48,7 @@ struct dwc3_generic_priv {
struct dwc3_generic_host_priv {
struct xhci_ctrl xhci_ctrl;
struct dwc3_generic_priv gen_priv;
+ struct udevice *vbus_supply;
};
static int dwc3_generic_probe(struct udevice *dev,
@@ -240,11 +242,24 @@ static int dwc3_generic_host_probe(struct udevice *dev)
if (rc)
return rc;
+ rc = device_get_supply_regulator(dev, "vbus-supply", &priv->vbus_supply);
+ if (rc)
+ debug("%s: No vbus regulator found: %d\n", dev->name, rc);
+
+ /* Only returns an error if regulator is valid and failed to enable due to a driver issue */
+ rc = regulator_set_enable_if_allowed(priv->vbus_supply, true);
+ if (rc)
+ return rc;
+
hccr = (struct xhci_hccr *)priv->gen_priv.base;
hcor = (struct xhci_hcor *)(priv->gen_priv.base +
HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
- return xhci_register(dev, hccr, hcor);
+ rc = xhci_register(dev, hccr, hcor);
+ if (rc)
+ regulator_set_enable_if_allowed(priv->vbus_supply, false);
+
+ return rc;
}
static int dwc3_generic_host_remove(struct udevice *dev)
@@ -252,9 +267,12 @@ static int dwc3_generic_host_remove(struct udevice *dev)
struct dwc3_generic_host_priv *priv = dev_get_priv(dev);
int rc;
- rc = xhci_deregister(dev);
+ /* This function always returns 0 */
+ xhci_deregister(dev);
+
+ rc = regulator_set_enable_if_allowed(priv->vbus_supply, false);
if (rc)
- return rc;
+ debug("%s: Failed to disable vbus regulator: %d\n", dev->name, rc);
return dwc3_generic_remove(dev, &priv->gen_priv);
}
@@ -407,6 +425,77 @@ struct dwc3_glue_ops ti_ops = {
.glue_configure = dwc3_ti_glue_configure,
};
+/* USB QSCRATCH Hardware registers */
+#define QSCRATCH_GENERAL_CFG 0x08
+#define PIPE_UTMI_CLK_SEL BIT(0)
+#define PIPE3_PHYSTATUS_SW BIT(3)
+#define PIPE_UTMI_CLK_DIS BIT(8)
+
+#define QSCRATCH_HS_PHY_CTRL 0x10
+#define UTMI_OTG_VBUS_VALID BIT(20)
+#define SW_SESSVLD_SEL BIT(28)
+
+#define QSCRATCH_SS_PHY_CTRL 0x30
+#define LANE0_PWR_PRESENT BIT(24)
+
+#define PWR_EVNT_IRQ_STAT_REG 0x58
+#define PWR_EVNT_LPM_IN_L2_MASK BIT(4)
+#define PWR_EVNT_LPM_OUT_L2_MASK BIT(5)
+
+#define SDM845_QSCRATCH_BASE_OFFSET 0xf8800
+#define SDM845_QSCRATCH_SIZE 0x400
+#define SDM845_DWC3_CORE_SIZE 0xcd00
+
+static void dwc3_qcom_vbus_override_enable(void __iomem *qscratch_base, bool enable)
+{
+ if (enable) {
+ setbits_le32(qscratch_base + QSCRATCH_SS_PHY_CTRL,
+ LANE0_PWR_PRESENT);
+ setbits_le32(qscratch_base + QSCRATCH_HS_PHY_CTRL,
+ UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
+ } else {
+ clrbits_le32(qscratch_base + QSCRATCH_SS_PHY_CTRL,
+ LANE0_PWR_PRESENT);
+ clrbits_le32(qscratch_base + QSCRATCH_HS_PHY_CTRL,
+ UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
+ }
+}
+
+/* For controllers running without superspeed PHYs */
+static void dwc3_qcom_select_utmi_clk(void __iomem *qscratch_base)
+{
+ /* Configure dwc3 to use UTMI clock as PIPE clock not present */
+ setbits_le32(qscratch_base + QSCRATCH_GENERAL_CFG,
+ PIPE_UTMI_CLK_DIS);
+
+ setbits_le32(qscratch_base + QSCRATCH_GENERAL_CFG,
+ PIPE_UTMI_CLK_SEL | PIPE3_PHYSTATUS_SW);
+
+ clrbits_le32(qscratch_base + QSCRATCH_GENERAL_CFG,
+ PIPE_UTMI_CLK_DIS);
+}
+
+static void dwc3_qcom_glue_configure(struct udevice *dev, int index,
+ enum usb_dr_mode mode)
+{
+ struct dwc3_glue_data *glue = dev_get_plat(dev);
+ void __iomem *qscratch_base = map_physmem(glue->regs, 0x400, MAP_NOCACHE);
+ if (IS_ERR_OR_NULL(qscratch_base)) {
+ log_err("%s: Invalid qscratch base address\n", dev->name);
+ return;
+ }
+
+ if (dev_read_bool(dev, "qcom,select-utmi-as-pipe-clk"))
+ dwc3_qcom_select_utmi_clk(qscratch_base);
+
+ if (mode != USB_DR_MODE_HOST)
+ dwc3_qcom_vbus_override_enable(qscratch_base, true);
+}
+
+struct dwc3_glue_ops qcom_ops = {
+ .glue_configure = dwc3_qcom_glue_configure,
+};
+
static int dwc3_rk_glue_get_ctrl_dev(struct udevice *dev, ofnode *node)
{
*node = dev_ofnode(dev);
@@ -494,6 +583,14 @@ static int dwc3_glue_reset_init(struct udevice *dev,
else if (ret)
return ret;
+ if (device_is_compatible(dev, "qcom,dwc3")) {
+ reset_assert_bulk(&glue->resets);
+ /* We should wait at least 6 sleep clock cycles, that's
+ * (6 / 32764) * 1000000 ~= 200us. But some platforms
+ * have slower sleep clocks so we'll play it safe.
+ */
+ udelay(500);
+ }
ret = reset_deassert_bulk(&glue->resets);
if (ret) {
reset_release_bulk(&glue->resets);
@@ -611,7 +708,7 @@ static const struct udevice_id dwc3_glue_ids[] = {
{ .compatible = "rockchip,rk3399-dwc3" },
{ .compatible = "rockchip,rk3568-dwc3", .data = (ulong)&rk_ops },
{ .compatible = "rockchip,rk3588-dwc3", .data = (ulong)&rk_ops },
- { .compatible = "qcom,dwc3" },
+ { .compatible = "qcom,dwc3", .data = (ulong)&qcom_ops },
{ .compatible = "fsl,imx8mp-dwc3", .data = (ulong)&imx8mp_ops },
{ .compatible = "fsl,imx8mq-dwc3" },
{ .compatible = "intel,tangier-dwc3" },
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 4fadb4a3e20..53c4d4826b4 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -428,7 +428,7 @@ void dwc3_omap_uboot_exit(int index)
}
/**
- * dwc3_omap_uboot_interrupt_status - check the status of interrupt
+ * dwc3_uboot_interrupt_status - check the status of interrupt
* @dev: device of this controller
*
* Checks the status of interrupts and returns true if an interrupt
@@ -436,7 +436,7 @@ void dwc3_omap_uboot_exit(int index)
*
* Generally called from board file.
*/
-int dwc3_omap_uboot_interrupt_status(struct udevice *dev)
+int dwc3_uboot_interrupt_status(struct udevice *dev)
{
struct dwc3_omap *omap = NULL;
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index c72a8047635..4621a6fd5e6 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -70,12 +70,21 @@ config USB_GADGET_PRODUCT_NUM
hex "Product ID of the USB device"
default 0x701a if ARCH_TEGRA
default 0x1010 if ARCH_SUNXI
- default 0x310a if ROCKCHIP_RK3036
+ default 0x110a if ROCKCHIP_RV1108
+ default 0x110b if ROCKCHIP_RV1126
default 0x300a if ROCKCHIP_RK3066
+ default 0x301a if ROCKCHIP_RK3036
+ default 0x310b if ROCKCHIP_RK3188
default 0x310c if ROCKCHIP_RK3128
- default 0x320a if ROCKCHIP_RK3229 || ROCKCHIP_RK3288
- default 0x330a if ROCKCHIP_RK3328
+ default 0x320a if ROCKCHIP_RK3288
+ default 0x320b if ROCKCHIP_RK322X
+ default 0x320c if ROCKCHIP_RK3328
+ default 0x330a if ROCKCHIP_RK3368
default 0x330c if ROCKCHIP_RK3399
+ default 0x330d if ROCKCHIP_PX30
+ default 0x330e if ROCKCHIP_RK3308
+ default 0x350a if ROCKCHIP_RK3568
+ default 0x350b if ROCKCHIP_RK3588
default 0x0
help
Product ID of the USB device emulated, reported to the host device.
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index de42e0189e8..ba216128ab2 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -623,12 +623,21 @@ static void acm_stdio_puts(struct stdio_dev *dev, const char *str)
static int acm_stdio_start(struct stdio_dev *dev)
{
+ struct udevice *udc;
int ret;
if (dev->priv) { /* function already exist */
return 0;
}
+ ret = udc_device_get_by_index(0, &udc);
+ if (ret) {
+ pr_err("USB init failed: %d\n", ret);
+ return ret;
+ }
+
+ g_dnl_clear_detach();
+
ret = g_dnl_register("usb_serial_acm");
if (ret)
return ret;
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index c725aed3f62..ef90c7ec7fb 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -240,6 +240,7 @@
/* #define DUMP_MSGS */
#include <config.h>
+#include <div64.h>
#include <hexdump.h>
#include <log.h>
#include <malloc.h>
@@ -724,12 +725,13 @@ static int do_read(struct fsg_common *common)
curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
return -EINVAL;
}
- file_offset = ((loff_t) lba) << 9;
+ file_offset = ((loff_t)lba) << curlun->blkbits;
/* Carry out the file reads */
amount_left = common->data_size_from_cmnd;
- if (unlikely(amount_left == 0))
+ if (unlikely(amount_left == 0)) {
return -EIO; /* No default reply */
+ }
for (;;) {
@@ -768,13 +770,13 @@ static int do_read(struct fsg_common *common)
/* Perform the read */
rc = ums[common->lun].read_sector(&ums[common->lun],
- file_offset / SECTOR_SIZE,
- amount / SECTOR_SIZE,
+ lldiv(file_offset, curlun->blksize),
+ lldiv(amount, curlun->blksize),
(char __user *)bh->buf);
if (!rc)
return -EIO;
- nread = rc * SECTOR_SIZE;
+ nread = rc * curlun->blksize;
VLDBG(curlun, "file read %u @ %llu -> %d\n", amount,
(unsigned long long) file_offset,
@@ -787,7 +789,7 @@ static int do_read(struct fsg_common *common)
} else if (nread < amount) {
LDBG(curlun, "partial file read: %d/%u\n",
(int) nread, amount);
- nread -= (nread & 511); /* Round down to a block */
+ nread -= (nread & (curlun->blksize - 1)); /* Round down to a block */
}
file_offset += nread;
amount_left -= nread;
@@ -861,7 +863,7 @@ static int do_write(struct fsg_common *common)
/* Carry out the file writes */
get_some_more = 1;
- file_offset = usb_offset = ((loff_t) lba) << 9;
+ file_offset = usb_offset = ((loff_t)lba) << curlun->blkbits;
amount_left_to_req = common->data_size_from_cmnd;
amount_left_to_write = common->data_size_from_cmnd;
@@ -893,7 +895,7 @@ static int do_write(struct fsg_common *common)
curlun->info_valid = 1;
continue;
}
- amount -= (amount & 511);
+ amount -= (amount & (curlun->blksize - 1));
if (amount == 0) {
/* Why were we were asked to transfer a
@@ -942,12 +944,12 @@ static int do_write(struct fsg_common *common)
/* Perform the write */
rc = ums[common->lun].write_sector(&ums[common->lun],
- file_offset / SECTOR_SIZE,
- amount / SECTOR_SIZE,
+ lldiv(file_offset, curlun->blksize),
+ lldiv(amount, curlun->blksize),
(char __user *)bh->buf);
if (!rc)
return -EIO;
- nwritten = rc * SECTOR_SIZE;
+ nwritten = rc * curlun->blksize;
VLDBG(curlun, "file write %u @ %llu -> %d\n", amount,
(unsigned long long) file_offset,
@@ -960,7 +962,7 @@ static int do_write(struct fsg_common *common)
} else if (nwritten < amount) {
LDBG(curlun, "partial file write: %d/%u\n",
(int) nwritten, amount);
- nwritten -= (nwritten & 511);
+ nwritten -= (nwritten & (curlun->blksize - 1));
/* Round down to a block */
}
file_offset += nwritten;
@@ -1034,8 +1036,8 @@ static int do_verify(struct fsg_common *common)
return -EIO; /* No default reply */
/* Prepare to carry out the file verify */
- amount_left = verification_length << 9;
- file_offset = ((loff_t) lba) << 9;
+ amount_left = verification_length << curlun->blkbits;
+ file_offset = ((loff_t) lba) << curlun->blkbits;
/* Write out all the dirty buffers before invalidating them */
@@ -1058,12 +1060,12 @@ static int do_verify(struct fsg_common *common)
/* Perform the read */
rc = ums[common->lun].read_sector(&ums[common->lun],
- file_offset / SECTOR_SIZE,
- amount / SECTOR_SIZE,
+ lldiv(file_offset, curlun->blksize),
+ lldiv(amount, curlun->blksize),
(char __user *)bh->buf);
if (!rc)
return -EIO;
- nread = rc * SECTOR_SIZE;
+ nread = rc * curlun->blksize;
VLDBG(curlun, "file read %u @ %llu -> %d\n", amount,
(unsigned long long) file_offset,
@@ -1075,7 +1077,7 @@ static int do_verify(struct fsg_common *common)
} else if (nread < amount) {
LDBG(curlun, "partial file verify: %d/%u\n",
(int) nread, amount);
- nread -= (nread & 511); /* Round down to a sector */
+ nread -= (nread & (curlun->blksize - 1)); /* Round down to a sector */
}
if (nread == 0) {
curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
@@ -1183,7 +1185,7 @@ static int do_read_capacity(struct fsg_common *common, struct fsg_buffhd *bh)
put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
/* Max logical block */
- put_unaligned_be32(512, &buf[4]); /* Block length */
+ put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */
return 8;
}
@@ -1370,7 +1372,7 @@ static int do_read_format_capacities(struct fsg_common *common,
put_unaligned_be32(curlun->num_sectors, &buf[0]);
/* Number of blocks */
- put_unaligned_be32(512, &buf[4]); /* Block length */
+ put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */
buf[4] = 0x02; /* Current capacity */
return 12;
}
@@ -1781,6 +1783,16 @@ static int check_command(struct fsg_common *common, int cmnd_size,
return 0;
}
+/* wrapper of check_command for data size in blocks handling */
+static int check_command_size_in_blocks(struct fsg_common *common,
+ int cmnd_size, enum data_direction data_dir,
+ unsigned int mask, int needs_medium, const char *name)
+{
+ common->data_size_from_cmnd <<= common->luns[common->lun].blkbits;
+ return check_command(common, cmnd_size, data_dir,
+ mask, needs_medium, name);
+}
+
static int do_scsi_command(struct fsg_common *common)
{
@@ -1865,30 +1877,30 @@ static int do_scsi_command(struct fsg_common *common)
case SC_READ_6:
i = common->cmnd[4];
- common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
- reply = check_command(common, 6, DATA_DIR_TO_HOST,
- (7<<1) | (1<<4), 1,
- "READ(6)");
+ common->data_size_from_cmnd = (i == 0 ? 256 : i);
+ reply = check_command_size_in_blocks(common, 6, DATA_DIR_TO_HOST,
+ (7<<1) | (1<<4), 1,
+ "READ(6)");
if (reply == 0)
reply = do_read(common);
break;
case SC_READ_10:
common->data_size_from_cmnd =
- get_unaligned_be16(&common->cmnd[7]) << 9;
- reply = check_command(common, 10, DATA_DIR_TO_HOST,
- (1<<1) | (0xf<<2) | (3<<7), 1,
- "READ(10)");
+ get_unaligned_be16(&common->cmnd[7]);
+ reply = check_command_size_in_blocks(common, 10, DATA_DIR_TO_HOST,
+ (1<<1) | (0xf<<2) | (3<<7), 1,
+ "READ(10)");
if (reply == 0)
reply = do_read(common);
break;
case SC_READ_12:
common->data_size_from_cmnd =
- get_unaligned_be32(&common->cmnd[6]) << 9;
- reply = check_command(common, 12, DATA_DIR_TO_HOST,
- (1<<1) | (0xf<<2) | (0xf<<6), 1,
- "READ(12)");
+ get_unaligned_be32(&common->cmnd[6]);
+ reply = check_command_size_in_blocks(common, 12, DATA_DIR_TO_HOST,
+ (1<<1) | (0xf<<2) | (0xf<<6), 1,
+ "READ(12)");
if (reply == 0)
reply = do_read(common);
break;
@@ -1983,30 +1995,30 @@ static int do_scsi_command(struct fsg_common *common)
case SC_WRITE_6:
i = common->cmnd[4];
- common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
- reply = check_command(common, 6, DATA_DIR_FROM_HOST,
- (7<<1) | (1<<4), 1,
- "WRITE(6)");
+ common->data_size_from_cmnd = (i == 0 ? 256 : i);
+ reply = check_command_size_in_blocks(common, 6, DATA_DIR_FROM_HOST,
+ (7<<1) | (1<<4), 1,
+ "WRITE(6)");
if (reply == 0)
reply = do_write(common);
break;
case SC_WRITE_10:
common->data_size_from_cmnd =
- get_unaligned_be16(&common->cmnd[7]) << 9;
- reply = check_command(common, 10, DATA_DIR_FROM_HOST,
- (1<<1) | (0xf<<2) | (3<<7), 1,
- "WRITE(10)");
+ get_unaligned_be16(&common->cmnd[7]);
+ reply = check_command_size_in_blocks(common, 10, DATA_DIR_FROM_HOST,
+ (1<<1) | (0xf<<2) | (3<<7), 1,
+ "WRITE(10)");
if (reply == 0)
reply = do_write(common);
break;
case SC_WRITE_12:
common->data_size_from_cmnd =
- get_unaligned_be32(&common->cmnd[6]) << 9;
- reply = check_command(common, 12, DATA_DIR_FROM_HOST,
- (1<<1) | (0xf<<2) | (0xf<<6), 1,
- "WRITE(12)");
+ get_unaligned_be32(&common->cmnd[6]);
+ reply = check_command_size_in_blocks(common, 12, DATA_DIR_FROM_HOST,
+ (1<<1) | (0xf<<2) | (0xf<<6), 1,
+ "WRITE(12)");
if (reply == 0)
reply = do_write(common);
break;
@@ -2497,7 +2509,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
for (i = 0; i < nluns; i++) {
common->luns[i].removable = 1;
- rc = fsg_lun_open(&common->luns[i], ums[i].num_sectors, "");
+ rc = fsg_lun_open(&common->luns[i], ums[i].num_sectors, ums->block_dev.blksz, "");
if (rc)
goto error_luns;
}
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index 5674e8fe494..97dc6b6f729 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -269,6 +269,7 @@ struct device_attribute { int i; };
#define ETOOSMALL 525
#include <log.h>
+#include <linux/log2.h>
#include <usb_mass_storage.h>
#include <dm/device_compat.h>
@@ -290,6 +291,8 @@ struct fsg_lun {
u32 sense_data;
u32 sense_data_info;
u32 unit_attention_data;
+ unsigned int blkbits;
+ unsigned int blksize; /* logical block size of bound block device */
struct device dev;
};
@@ -566,7 +569,7 @@ static struct usb_gadget_strings fsg_stringtab = {
*/
static int fsg_lun_open(struct fsg_lun *curlun, unsigned int num_sectors,
- const char *filename)
+ unsigned int sector_size, const char *filename)
{
int ro;
@@ -574,9 +577,12 @@ static int fsg_lun_open(struct fsg_lun *curlun, unsigned int num_sectors,
ro = curlun->initially_ro;
curlun->ro = ro;
- curlun->file_length = num_sectors << 9;
+ curlun->file_length = num_sectors * sector_size;
curlun->num_sectors = num_sectors;
- debug("open backing file: %s\n", filename);
+ curlun->blksize = sector_size;
+ curlun->blkbits = order_base_2(sector_size >> 9) + 9;
+ debug("blksize: %u\n", sector_size);
+ debug("open backing file: '%s'\n", filename);
return 0;
}
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index dd0d153500c..98fe7bc3bcb 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -9,6 +9,7 @@
#include <common.h>
#include <dm.h>
+#include <dm/lists.h>
#include <errno.h>
#include <usb.h>
#include <usb/ehci-ci.h>
@@ -119,6 +120,24 @@ static int ehci_usb_of_to_plat(struct udevice *dev)
return 0;
}
+static int ehci_usb_of_bind(struct udevice *dev)
+{
+ ofnode ulpi_node = ofnode_first_subnode(dev_ofnode(dev));
+ ofnode phy_node;
+
+ if (!ofnode_valid(ulpi_node))
+ return 0;
+
+ phy_node = ofnode_first_subnode(ulpi_node);
+ if (!ofnode_valid(phy_node)) {
+ printf("%s: ulpi subnode with no phy\n", __func__);
+ return -ENOENT;
+ }
+
+ return device_bind_driver_to_node(dev, "msm8916_usbphy", "msm8916_usbphy",
+ phy_node, NULL);
+}
+
#if defined(CONFIG_CI_UDC)
/* Little quirk that MSM needs with Chipidea controller
* Must reinit phy after reset
@@ -132,7 +151,7 @@ void ci_init_after_reset(struct ehci_ctrl *ctrl)
#endif
static const struct udevice_id ehci_usb_ids[] = {
- { .compatible = "qcom,ehci-host", },
+ { .compatible = "qcom,ci-hdrc", },
{ }
};
@@ -141,6 +160,7 @@ U_BOOT_DRIVER(usb_ehci) = {
.id = UCLASS_USB,
.of_match = ehci_usb_ids,
.of_to_plat = ehci_usb_of_to_plat,
+ .bind = ehci_usb_of_bind,
.probe = ehci_usb_probe,
.remove = ehci_usb_remove,
.ops = &ehci_usb_ops,