diff options
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r-- | drivers/usb/dwc3/dwc3-am62.c | 12 | ||||
-rw-r--r-- | drivers/usb/dwc3/dwc3-exynos.c | 9 | ||||
-rw-r--r-- | drivers/usb/dwc3/dwc3-pci.c | 10 | ||||
-rw-r--r-- | drivers/usb/dwc3/dwc3-st.c | 2 | ||||
-rw-r--r-- | drivers/usb/dwc3/dwc3-xilinx.c | 4 | ||||
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 75 |
6 files changed, 90 insertions, 22 deletions
diff --git a/drivers/usb/dwc3/dwc3-am62.c b/drivers/usb/dwc3/dwc3-am62.c index c158364bc03e..9db8f3ca493d 100644 --- a/drivers/usb/dwc3/dwc3-am62.c +++ b/drivers/usb/dwc3/dwc3-am62.c @@ -153,11 +153,11 @@ static int phy_syscon_pll_refclk(struct dwc3_am62 *am62) { struct device *dev = am62->dev; struct device_node *node = dev->of_node; - struct of_phandle_args args; struct regmap *syscon; int ret; - syscon = syscon_regmap_lookup_by_phandle(node, "ti,syscon-phy-pll-refclk"); + syscon = syscon_regmap_lookup_by_phandle_args(node, "ti,syscon-phy-pll-refclk", + 1, &am62->offset); if (IS_ERR(syscon)) { dev_err(dev, "unable to get ti,syscon-phy-pll-refclk regmap\n"); return PTR_ERR(syscon); @@ -165,14 +165,6 @@ static int phy_syscon_pll_refclk(struct dwc3_am62 *am62) am62->syscon = syscon; - ret = of_parse_phandle_with_fixed_args(node, "ti,syscon-phy-pll-refclk", 1, - 0, &args); - if (ret) - return ret; - - of_node_put(args.np); - am62->offset = args.args[0]; - /* Core voltage. PHY_CORE_VOLTAGE bit Recommended to be 0 always */ ret = regmap_update_bits(am62->syscon, am62->offset, PHY_CORE_VOLTAGE_MASK, 0); if (ret) { diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index f5d963fae9e0..de686b9e6404 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -163,6 +163,12 @@ static const struct dwc3_exynos_driverdata exynos7_drvdata = { .suspend_clk_idx = 1, }; +static const struct dwc3_exynos_driverdata exynos7870_drvdata = { + .clk_names = { "bus_early", "ref", "ctrl" }, + .num_clks = 3, + .suspend_clk_idx = -1, +}; + static const struct dwc3_exynos_driverdata exynos850_drvdata = { .clk_names = { "bus_early", "ref" }, .num_clks = 2, @@ -186,6 +192,9 @@ static const struct of_device_id exynos_dwc3_match[] = { .compatible = "samsung,exynos7-dwusb3", .data = &exynos7_drvdata, }, { + .compatible = "samsung,exynos7870-dwusb3", + .data = &exynos7870_drvdata, + }, { .compatible = "samsung,exynos850-dwusb3", .data = &exynos850_drvdata, }, { diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 052852f80146..54a4ee2b90b7 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -148,11 +148,21 @@ static const struct property_entry dwc3_pci_intel_byt_properties[] = { {} }; +/* + * Intel Merrifield SoC uses these endpoints for tracing and they cannot + * be re-allocated if being used because the side band flow control signals + * are hard wired to certain endpoints: + * - 1 High BW Bulk IN (IN#1) (RTIT) + * - 1 1KB BW Bulk IN (IN#8) + 1 1KB BW Bulk OUT (Run Control) (OUT#8) + */ +static const u8 dwc3_pci_mrfld_reserved_endpoints[] = { 3, 16, 17 }; + static const struct property_entry dwc3_pci_mrfld_properties[] = { PROPERTY_ENTRY_STRING("dr_mode", "otg"), PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"), PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"), PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), + PROPERTY_ENTRY_U8_ARRAY("snps,reserved-endpoints", dwc3_pci_mrfld_reserved_endpoints), PROPERTY_ENTRY_BOOL("snps,usb2-gadget-lpm-disable"), PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), {} diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c index ef7c43008946..5d513decaacd 100644 --- a/drivers/usb/dwc3/dwc3-st.c +++ b/drivers/usb/dwc3/dwc3-st.c @@ -225,7 +225,7 @@ static int st_dwc3_probe(struct platform_device *pdev) dwc3_data->syscfg_reg_off = res->start; - dev_vdbg(dev, "glue-logic addr 0x%pK, syscfg-reg offset 0x%x\n", + dev_vdbg(dev, "glue-logic addr 0x%p, syscfg-reg offset 0x%x\n", dwc3_data->glue_base, dwc3_data->syscfg_reg_off); struct device_node *child __free(device_node) = of_get_compatible_child(node, diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c index a33a42ba0249..4ca7f6240d07 100644 --- a/drivers/usb/dwc3/dwc3-xilinx.c +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -207,15 +207,13 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data) skip_usb3_phy: /* ulpi reset via gpio-modepin or gpio-framework driver */ - reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(reset_gpio)) { return dev_err_probe(dev, PTR_ERR(reset_gpio), "Failed to request reset GPIO\n"); } if (reset_gpio) { - /* Toggle ulpi to reset the phy. */ - gpiod_set_value_cansleep(reset_gpio, 1); usleep_range(5000, 10000); gpiod_set_value_cansleep(reset_gpio, 0); usleep_range(5000, 10000); diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 89a4dc8ebf94..8c30d86cc4e3 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -547,6 +547,7 @@ static int dwc3_gadget_set_xfer_resource(struct dwc3_ep *dep) int dwc3_gadget_start_config(struct dwc3 *dwc, unsigned int resource_index) { struct dwc3_gadget_ep_cmd_params params; + struct dwc3_ep *dep; u32 cmd; int i; int ret; @@ -563,8 +564,13 @@ int dwc3_gadget_start_config(struct dwc3 *dwc, unsigned int resource_index) return ret; /* Reset resource allocation flags */ - for (i = resource_index; i < dwc->num_eps && dwc->eps[i]; i++) - dwc->eps[i]->flags &= ~DWC3_EP_RESOURCE_ALLOCATED; + for (i = resource_index; i < dwc->num_eps; i++) { + dep = dwc->eps[i]; + if (!dep) + continue; + + dep->flags &= ~DWC3_EP_RESOURCE_ALLOCATED; + } return 0; } @@ -751,9 +757,11 @@ void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc) dwc->last_fifo_depth = fifo_depth; /* Clear existing TXFIFO for all IN eps except ep0 */ - for (num = 3; num < min_t(int, dwc->num_eps, DWC3_ENDPOINTS_NUM); - num += 2) { + for (num = 3; num < min_t(int, dwc->num_eps, DWC3_ENDPOINTS_NUM); num += 2) { dep = dwc->eps[num]; + if (!dep) + continue; + /* Don't change TXFRAMNUM on usb31 version */ size = DWC3_IP_IS(DWC3) ? 0 : dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1)) & @@ -1971,12 +1979,12 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) return -ESHUTDOWN; } - if (WARN(req->dep != dep, "request %pK belongs to '%s'\n", + if (WARN(req->dep != dep, "request %p belongs to '%s'\n", &req->request, req->dep->name)) return -EINVAL; if (WARN(req->status < DWC3_REQUEST_STATUS_COMPLETED, - "%s: request %pK already in flight\n", + "%s: request %p already in flight\n", dep->name, &req->request)) return -EINVAL; @@ -2165,7 +2173,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, } } - dev_err(dwc->dev, "request %pK was not queued to %s\n", + dev_err(dwc->dev, "request %p was not queued to %s\n", request, ep->name); ret = -EINVAL; out: @@ -3429,14 +3437,53 @@ static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum) return 0; } +static int dwc3_gadget_get_reserved_endpoints(struct dwc3 *dwc, const char *propname, + u8 *eps, u8 num) +{ + u8 count; + int ret; + + if (!device_property_present(dwc->dev, propname)) + return 0; + + ret = device_property_count_u8(dwc->dev, propname); + if (ret < 0) + return ret; + count = ret; + + ret = device_property_read_u8_array(dwc->dev, propname, eps, min(num, count)); + if (ret) + return ret; + + return count; +} + static int dwc3_gadget_init_endpoints(struct dwc3 *dwc, u8 total) { + const char *propname = "snps,reserved-endpoints"; u8 epnum; + u8 reserved_eps[DWC3_ENDPOINTS_NUM]; + u8 count; + u8 num; + int ret; INIT_LIST_HEAD(&dwc->gadget->ep_list); + ret = dwc3_gadget_get_reserved_endpoints(dwc, propname, + reserved_eps, ARRAY_SIZE(reserved_eps)); + if (ret < 0) { + dev_err(dwc->dev, "failed to read %s\n", propname); + return ret; + } + count = ret; + for (epnum = 0; epnum < total; epnum++) { - int ret; + for (num = 0; num < count; num++) { + if (epnum == reserved_eps[num]) + break; + } + if (num < count) + continue; ret = dwc3_gadget_init_endpoint(dwc, epnum); if (ret) @@ -3703,6 +3750,8 @@ out: for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) { dep = dwc->eps[i]; + if (!dep) + continue; if (!(dep->flags & DWC3_EP_ENABLED)) continue; @@ -3852,6 +3901,10 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, u8 epnum = event->endpoint_number; dep = dwc->eps[epnum]; + if (!dep) { + dev_warn(dwc->dev, "spurious event, endpoint %u is not allocated\n", epnum); + return; + } if (!(dep->flags & DWC3_EP_ENABLED)) { if ((epnum > 1) && !(dep->flags & DWC3_EP_TRANSFER_STARTED)) @@ -4564,6 +4617,12 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt) if (!count) return IRQ_NONE; + if (count > evt->length) { + dev_err_ratelimited(dwc->dev, "invalid count(%u) > evt->length(%u)\n", + count, evt->length); + return IRQ_NONE; + } + evt->count = count; evt->flags |= DWC3_EVENT_PENDING; |