aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/chipidea/udc.c20
-rw-r--r--drivers/usb/dwc2/params.c9
-rw-r--r--drivers/usb/dwc2/platform.c9
-rw-r--r--drivers/usb/host/xhci-ring.c15
-rw-r--r--drivers/usb/host/xhci.c25
-rw-r--r--drivers/usb/host/xhci.h9
6 files changed, 72 insertions, 15 deletions
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 829e947cabf5..6a5ee8e6da10 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1622,6 +1622,25 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
1622static int ci_udc_start(struct usb_gadget *gadget, 1622static int ci_udc_start(struct usb_gadget *gadget,
1623 struct usb_gadget_driver *driver); 1623 struct usb_gadget_driver *driver);
1624static int ci_udc_stop(struct usb_gadget *gadget); 1624static int ci_udc_stop(struct usb_gadget *gadget);
1625
1626/* Match ISOC IN from the highest endpoint */
1627static struct usb_ep *ci_udc_match_ep(struct usb_gadget *gadget,
1628 struct usb_endpoint_descriptor *desc,
1629 struct usb_ss_ep_comp_descriptor *comp_desc)
1630{
1631 struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
1632 struct usb_ep *ep;
1633
1634 if (usb_endpoint_xfer_isoc(desc) && usb_endpoint_dir_in(desc)) {
1635 list_for_each_entry_reverse(ep, &ci->gadget.ep_list, ep_list) {
1636 if (ep->caps.dir_in && !ep->claimed)
1637 return ep;
1638 }
1639 }
1640
1641 return NULL;
1642}
1643
1625/** 1644/**
1626 * Device operations part of the API to the USB controller hardware, 1645 * Device operations part of the API to the USB controller hardware,
1627 * which don't involve endpoints (or i/o) 1646 * which don't involve endpoints (or i/o)
@@ -1635,6 +1654,7 @@ static const struct usb_gadget_ops usb_gadget_ops = {
1635 .vbus_draw = ci_udc_vbus_draw, 1654 .vbus_draw = ci_udc_vbus_draw,
1636 .udc_start = ci_udc_start, 1655 .udc_start = ci_udc_start,
1637 .udc_stop = ci_udc_stop, 1656 .udc_stop = ci_udc_stop,
1657 .match_ep = ci_udc_match_ep,
1638}; 1658};
1639 1659
1640static int init_eps(struct ci_hdrc *ci) 1660static int init_eps(struct ci_hdrc *ci)
diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c
index 6900eea57526..5949262ff669 100644
--- a/drivers/usb/dwc2/params.c
+++ b/drivers/usb/dwc2/params.c
@@ -253,6 +253,15 @@ static void dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg)
253 val = (hsotg->hw_params.utmi_phy_data_width == 253 val = (hsotg->hw_params.utmi_phy_data_width ==
254 GHWCFG4_UTMI_PHY_DATA_WIDTH_8) ? 8 : 16; 254 GHWCFG4_UTMI_PHY_DATA_WIDTH_8) ? 8 : 16;
255 255
256 if (hsotg->phy) {
257 /*
258 * If using the generic PHY framework, check if the PHY bus
259 * width is 8-bit and set the phyif appropriately.
260 */
261 if (phy_get_bus_width(hsotg->phy) == 8)
262 val = 8;
263 }
264
256 hsotg->params.phy_utmi_width = val; 265 hsotg->params.phy_utmi_width = val;
257} 266}
258 267
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index d10a7f8daec3..e98d7812da2d 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -271,15 +271,6 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
271 271
272 hsotg->plat = dev_get_platdata(hsotg->dev); 272 hsotg->plat = dev_get_platdata(hsotg->dev);
273 273
274 if (hsotg->phy) {
275 /*
276 * If using the generic PHY framework, check if the PHY bus
277 * width is 8-bit and set the phyif appropriately.
278 */
279 if (phy_get_bus_width(hsotg->phy) == 8)
280 hsotg->params.phy_utmi_width = 8;
281 }
282
283 /* Clock */ 274 /* Clock */
284 hsotg->clk = devm_clk_get_optional(hsotg->dev, "otg"); 275 hsotg->clk = devm_clk_get_optional(hsotg->dev, "otg");
285 if (IS_ERR(hsotg->clk)) { 276 if (IS_ERR(hsotg->clk)) {
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index feffceb31e8a..121782e22c01 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1612,8 +1612,13 @@ static void handle_port_status(struct xhci_hcd *xhci,
1612 usb_hcd_resume_root_hub(hcd); 1612 usb_hcd_resume_root_hub(hcd);
1613 } 1613 }
1614 1614
1615 if (hcd->speed >= HCD_USB3 && (portsc & PORT_PLS_MASK) == XDEV_INACTIVE) 1615 if (hcd->speed >= HCD_USB3 &&
1616 (portsc & PORT_PLS_MASK) == XDEV_INACTIVE) {
1617 slot_id = xhci_find_slot_id_by_port(hcd, xhci, hcd_portnum + 1);
1618 if (slot_id && xhci->devs[slot_id])
1619 xhci->devs[slot_id]->flags |= VDEV_PORT_ERROR;
1616 bus_state->port_remote_wakeup &= ~(1 << hcd_portnum); 1620 bus_state->port_remote_wakeup &= ~(1 << hcd_portnum);
1621 }
1617 1622
1618 if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_RESUME) { 1623 if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_RESUME) {
1619 xhci_dbg(xhci, "port resume event for port %d\n", port_id); 1624 xhci_dbg(xhci, "port resume event for port %d\n", port_id);
@@ -1801,6 +1806,14 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
1801{ 1806{
1802 struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index]; 1807 struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index];
1803 struct xhci_command *command; 1808 struct xhci_command *command;
1809
1810 /*
1811 * Avoid resetting endpoint if link is inactive. Can cause host hang.
1812 * Device will be reset soon to recover the link so don't do anything
1813 */
1814 if (xhci->devs[slot_id]->flags & VDEV_PORT_ERROR)
1815 return;
1816
1804 command = xhci_alloc_command(xhci, false, GFP_ATOMIC); 1817 command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
1805 if (!command) 1818 if (!command)
1806 return; 1819 return;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 20db378a6012..3f79f35d0b19 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1466,6 +1466,10 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
1466 xhci_dbg(xhci, "urb submitted during PCI suspend\n"); 1466 xhci_dbg(xhci, "urb submitted during PCI suspend\n");
1467 return -ESHUTDOWN; 1467 return -ESHUTDOWN;
1468 } 1468 }
1469 if (xhci->devs[slot_id]->flags & VDEV_PORT_ERROR) {
1470 xhci_dbg(xhci, "Can't queue urb, port error, link inactive\n");
1471 return -ENODEV;
1472 }
1469 1473
1470 if (usb_endpoint_xfer_isoc(&urb->ep->desc)) 1474 if (usb_endpoint_xfer_isoc(&urb->ep->desc))
1471 num_tds = urb->number_of_packets; 1475 num_tds = urb->number_of_packets;
@@ -3754,6 +3758,7 @@ static int xhci_discover_or_reset_device(struct usb_hcd *hcd,
3754 } 3758 }
3755 /* If necessary, update the number of active TTs on this root port */ 3759 /* If necessary, update the number of active TTs on this root port */
3756 xhci_update_tt_active_eps(xhci, virt_dev, old_active_eps); 3760 xhci_update_tt_active_eps(xhci, virt_dev, old_active_eps);
3761 virt_dev->flags = 0;
3757 ret = 0; 3762 ret = 0;
3758 3763
3759command_cleanup: 3764command_cleanup:
@@ -5060,16 +5065,26 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
5060 } else { 5065 } else {
5061 /* 5066 /*
5062 * Some 3.1 hosts return sbrn 0x30, use xhci supported protocol 5067 * Some 3.1 hosts return sbrn 0x30, use xhci supported protocol
5063 * minor revision instead of sbrn 5068 * minor revision instead of sbrn. Minor revision is a two digit
5069 * BCD containing minor and sub-minor numbers, only show minor.
5064 */ 5070 */
5065 minor_rev = xhci->usb3_rhub.min_rev; 5071 minor_rev = xhci->usb3_rhub.min_rev / 0x10;
5066 if (minor_rev) { 5072
5073 switch (minor_rev) {
5074 case 2:
5075 hcd->speed = HCD_USB32;
5076 hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;
5077 hcd->self.root_hub->rx_lanes = 2;
5078 hcd->self.root_hub->tx_lanes = 2;
5079 break;
5080 case 1:
5067 hcd->speed = HCD_USB31; 5081 hcd->speed = HCD_USB31;
5068 hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS; 5082 hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;
5083 break;
5069 } 5084 }
5070 xhci_info(xhci, "Host supports USB 3.%x %s SuperSpeed\n", 5085 xhci_info(xhci, "Host supports USB 3.%x %sSuperSpeed\n",
5071 minor_rev, 5086 minor_rev,
5072 minor_rev ? "Enhanced" : ""); 5087 minor_rev ? "Enhanced " : "");
5073 5088
5074 xhci->usb3_rhub.hcd = hcd; 5089 xhci->usb3_rhub.hcd = hcd;
5075 /* xHCI private pointer was set in xhci_pci_probe for the second 5090 /* xHCI private pointer was set in xhci_pci_probe for the second
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 7f8b950d1a73..92e764c54154 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1010,6 +1010,15 @@ struct xhci_virt_device {
1010 u8 real_port; 1010 u8 real_port;
1011 struct xhci_interval_bw_table *bw_table; 1011 struct xhci_interval_bw_table *bw_table;
1012 struct xhci_tt_bw_info *tt_info; 1012 struct xhci_tt_bw_info *tt_info;
1013 /*
1014 * flags for state tracking based on events and issued commands.
1015 * Software can not rely on states from output contexts because of
1016 * latency between events and xHC updating output context values.
1017 * See xhci 1.1 section 4.8.3 for more details
1018 */
1019 unsigned long flags;
1020#define VDEV_PORT_ERROR BIT(0) /* Port error, link inactive */
1021
1013 /* The current max exit latency for the enabled USB3 link states. */ 1022 /* The current max exit latency for the enabled USB3 link states. */
1014 u16 current_mel; 1023 u16 current_mel;
1015 /* Used for the debugfs interfaces. */ 1024 /* Used for the debugfs interfaces. */