Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'usb-5.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg KH:
"Here are some small USB fixes for 5.13-rc2. They consist of a number
of resolutions for reported issues:

- typec fixes for found problems

- xhci fixes and quirk additions

- dwc3 driver fixes

- minor fixes found by Coverity

- cdc-wdm fixes for reported problems

All of these have been in linux-next for a few days with no reported
issues"

* tag 'usb-5.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (28 commits)
usb: core: hub: fix race condition about TRSMRCY of resume
usb: typec: tcpm: Fix SINK_DISCOVERY current limit for Rp-default
xhci: Add reset resume quirk for AMD xhci controller.
usb: xhci: Increase timeout for HC halt
xhci: Do not use GFP_KERNEL in (potentially) atomic context
xhci: Fix giving back cancelled URBs even if halted endpoint can't reset
xhci-pci: Allow host runtime PM as default for Intel Alder Lake xHCI
usb: musb: Fix an error message
usb: typec: tcpm: Fix wrong handling for Not_Supported in VDM AMS
usb: typec: tcpm: Send DISCOVER_IDENTITY from dedicated work
usb: typec: ucsi: Retrieve all the PDOs instead of just the first 4
usb: fotg210-hcd: Fix an error message
docs: usb: function: Modify path name
usb: dwc3: omap: improve extcon initialization
usb: typec: ucsi: Put fwnode in any case during ->probe()
usb: typec: tcpm: Fix wrong handling in GET_SINK_CAP
usb: dwc2: Remove obsolete MODULE_ constants from platform.c
usb: dwc3: imx8mp: fix error return code in dwc3_imx8mp_probe()
usb: dwc3: imx8mp: detect dwc3 core node via compatible string
usb: dwc3: gadget: Return success always for kick transfer in ep queue
...

+221 -76
+9 -6
Documentation/driver-api/usb/usb.rst
··· 109 109 USB-Standard Types 110 110 ================== 111 111 112 - In ``drivers/usb/common/common.c`` and ``drivers/usb/common/debug.c`` you 113 - will find the USB data types defined in chapter 9 of the USB specification. 114 - These data types are used throughout USB, and in APIs including this host 115 - side API, gadget APIs, usb character devices and debugfs interfaces. 112 + In ``include/uapi/linux/usb/ch9.h`` you will find the USB data types defined 113 + in chapter 9 of the USB specification. These data types are used throughout 114 + USB, and in APIs including this host side API, gadget APIs, usb character 115 + devices and debugfs interfaces. That file is itself included by 116 + ``include/linux/usb/ch9.h``, which also contains declarations of a few 117 + utility routines for manipulating these data types; the implementations 118 + are in ``drivers/usb/common/common.c``. 116 119 117 120 .. kernel-doc:: drivers/usb/common/common.c 118 121 :export: 119 122 120 - .. kernel-doc:: drivers/usb/common/debug.c 121 - :export: 123 + In addition, some functions useful for creating debugging output are 124 + defined in ``drivers/usb/common/debug.c``. 122 125 123 126 Host-Side Data Types and Macros 124 127 ===============================
+1 -1
Documentation/usb/gadget_configfs.rst
··· 140 140 Each function provides its specific set of attributes, with either read-only 141 141 or read-write access. Where applicable they need to be written to as 142 142 appropriate. 143 - Please refer to Documentation/ABI/*/configfs-usb-gadget* for more information. 143 + Please refer to Documentation/ABI/testing/configfs-usb-gadget for more information. 144 144 145 145 4. Associating the functions with their configurations 146 146 ------------------------------------------------------
+22 -8
drivers/usb/class/cdc-wdm.c
··· 321 321 322 322 } 323 323 324 - static void kill_urbs(struct wdm_device *desc) 324 + static void poison_urbs(struct wdm_device *desc) 325 325 { 326 326 /* the order here is essential */ 327 - usb_kill_urb(desc->command); 328 - usb_kill_urb(desc->validity); 329 - usb_kill_urb(desc->response); 327 + usb_poison_urb(desc->command); 328 + usb_poison_urb(desc->validity); 329 + usb_poison_urb(desc->response); 330 + } 331 + 332 + static void unpoison_urbs(struct wdm_device *desc) 333 + { 334 + /* 335 + * the order here is not essential 336 + * it is symmetrical just to be nice 337 + */ 338 + usb_unpoison_urb(desc->response); 339 + usb_unpoison_urb(desc->validity); 340 + usb_unpoison_urb(desc->command); 330 341 } 331 342 332 343 static void free_urbs(struct wdm_device *desc) ··· 752 741 if (!desc->count) { 753 742 if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { 754 743 dev_dbg(&desc->intf->dev, "wdm_release: cleanup\n"); 755 - kill_urbs(desc); 744 + poison_urbs(desc); 756 745 spin_lock_irq(&desc->iuspin); 757 746 desc->resp_count = 0; 758 747 spin_unlock_irq(&desc->iuspin); 759 748 desc->manage_power(desc->intf, 0); 749 + unpoison_urbs(desc); 760 750 } else { 761 751 /* must avoid dev_printk here as desc->intf is invalid */ 762 752 pr_debug(KBUILD_MODNAME " %s: device gone - cleaning up\n", __func__); ··· 1049 1037 wake_up_all(&desc->wait); 1050 1038 mutex_lock(&desc->rlock); 1051 1039 mutex_lock(&desc->wlock); 1040 + poison_urbs(desc); 1052 1041 cancel_work_sync(&desc->rxwork); 1053 1042 cancel_work_sync(&desc->service_outs_intr); 1054 - kill_urbs(desc); 1055 1043 mutex_unlock(&desc->wlock); 1056 1044 mutex_unlock(&desc->rlock); 1057 1045 ··· 1092 1080 set_bit(WDM_SUSPENDING, &desc->flags); 1093 1081 spin_unlock_irq(&desc->iuspin); 1094 1082 /* callback submits work - order is essential */ 1095 - kill_urbs(desc); 1083 + poison_urbs(desc); 1096 1084 cancel_work_sync(&desc->rxwork); 1097 1085 cancel_work_sync(&desc->service_outs_intr); 1086 + unpoison_urbs(desc); 1098 1087 } 1099 1088 if (!PMSG_IS_AUTO(message)) { 1100 1089 mutex_unlock(&desc->wlock); ··· 1153 1140 wake_up_all(&desc->wait); 1154 1141 mutex_lock(&desc->rlock); 1155 1142 mutex_lock(&desc->wlock); 1156 - kill_urbs(desc); 1143 + poison_urbs(desc); 1157 1144 cancel_work_sync(&desc->rxwork); 1158 1145 cancel_work_sync(&desc->service_outs_intr); 1159 1146 return 0; ··· 1164 1151 struct wdm_device *desc = wdm_find_device(intf); 1165 1152 int rv; 1166 1153 1154 + unpoison_urbs(desc); 1167 1155 clear_bit(WDM_OVERFLOW, &desc->flags); 1168 1156 clear_bit(WDM_RESETTING, &desc->flags); 1169 1157 rv = recover_from_urb_loss(desc);
+3 -3
drivers/usb/core/hub.c
··· 3642 3642 * sequence. 3643 3643 */ 3644 3644 status = hub_port_status(hub, port1, &portstatus, &portchange); 3645 - 3646 - /* TRSMRCY = 10 msec */ 3647 - msleep(10); 3648 3645 } 3649 3646 3650 3647 SuspendCleared: ··· 3656 3659 usb_clear_port_feature(hub->hdev, port1, 3657 3660 USB_PORT_FEAT_C_SUSPEND); 3658 3661 } 3662 + 3663 + /* TRSMRCY = 10 msec */ 3664 + msleep(10); 3659 3665 } 3660 3666 3661 3667 if (udev->persist_enabled)
+2
drivers/usb/dwc2/core.h
··· 113 113 * @debugfs: File entry for debugfs file for this endpoint. 114 114 * @dir_in: Set to true if this endpoint is of the IN direction, which 115 115 * means that it is sending data to the Host. 116 + * @map_dir: Set to the value of dir_in when the DMA buffer is mapped. 116 117 * @index: The index for the endpoint registers. 117 118 * @mc: Multi Count - number of transactions per microframe 118 119 * @interval: Interval for periodic endpoints, in frames or microframes. ··· 163 162 unsigned short fifo_index; 164 163 165 164 unsigned char dir_in; 165 + unsigned char map_dir; 166 166 unsigned char index; 167 167 unsigned char mc; 168 168 u16 interval;
+2 -1
drivers/usb/dwc2/gadget.c
··· 422 422 { 423 423 struct usb_request *req = &hs_req->req; 424 424 425 - usb_gadget_unmap_request(&hsotg->gadget, req, hs_ep->dir_in); 425 + usb_gadget_unmap_request(&hsotg->gadget, req, hs_ep->map_dir); 426 426 } 427 427 428 428 /* ··· 1242 1242 { 1243 1243 int ret; 1244 1244 1245 + hs_ep->map_dir = hs_ep->dir_in; 1245 1246 ret = usb_gadget_map_request(&hsotg->gadget, req, hs_ep->dir_in); 1246 1247 if (ret) 1247 1248 goto dma_error;
-4
drivers/usb/dwc2/platform.c
··· 776 776 }; 777 777 778 778 module_platform_driver(dwc2_platform_driver); 779 - 780 - MODULE_DESCRIPTION("DESIGNWARE HS OTG Platform Glue"); 781 - MODULE_AUTHOR("Matthijs Kooijman <matthijs@stdin.nl>"); 782 - MODULE_LICENSE("Dual BSD/GPL");
+4 -3
drivers/usb/dwc3/core.h
··· 57 57 #define DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE 3 58 58 #define DWC3_DEVICE_EVENT_WAKEUP 4 59 59 #define DWC3_DEVICE_EVENT_HIBER_REQ 5 60 - #define DWC3_DEVICE_EVENT_EOPF 6 60 + #define DWC3_DEVICE_EVENT_SUSPEND 6 61 61 #define DWC3_DEVICE_EVENT_SOF 7 62 62 #define DWC3_DEVICE_EVENT_ERRATIC_ERROR 9 63 63 #define DWC3_DEVICE_EVENT_CMD_CMPL 10 ··· 460 460 #define DWC3_DEVTEN_CMDCMPLTEN BIT(10) 461 461 #define DWC3_DEVTEN_ERRTICERREN BIT(9) 462 462 #define DWC3_DEVTEN_SOFEN BIT(7) 463 - #define DWC3_DEVTEN_EOPFEN BIT(6) 463 + #define DWC3_DEVTEN_U3L2L1SUSPEN BIT(6) 464 464 #define DWC3_DEVTEN_HIBERNATIONREQEVTEN BIT(5) 465 465 #define DWC3_DEVTEN_WKUPEVTEN BIT(4) 466 466 #define DWC3_DEVTEN_ULSTCNGEN BIT(3) ··· 850 850 * @hwparams6: GHWPARAMS6 851 851 * @hwparams7: GHWPARAMS7 852 852 * @hwparams8: GHWPARAMS8 853 + * @hwparams9: GHWPARAMS9 853 854 */ 854 855 struct dwc3_hwparams { 855 856 u32 hwparams0; ··· 1375 1374 * 3 - ULStChng 1376 1375 * 4 - WkUpEvt 1377 1376 * 5 - Reserved 1378 - * 6 - EOPF 1377 + * 6 - Suspend (EOPF on revisions 2.10a and prior) 1379 1378 * 7 - SOF 1380 1379 * 8 - Reserved 1381 1380 * 9 - ErrticErr
+4 -4
drivers/usb/dwc3/debug.h
··· 221 221 snprintf(str, size, "WakeUp [%s]", 222 222 dwc3_gadget_link_string(state)); 223 223 break; 224 - case DWC3_DEVICE_EVENT_EOPF: 225 - snprintf(str, size, "End-Of-Frame [%s]", 224 + case DWC3_DEVICE_EVENT_SUSPEND: 225 + snprintf(str, size, "Suspend [%s]", 226 226 dwc3_gadget_link_string(state)); 227 227 break; 228 228 case DWC3_DEVICE_EVENT_SOF: ··· 353 353 return "Wake-Up"; 354 354 case DWC3_DEVICE_EVENT_HIBER_REQ: 355 355 return "Hibernation"; 356 - case DWC3_DEVICE_EVENT_EOPF: 357 - return "End of Periodic Frame"; 356 + case DWC3_DEVICE_EVENT_SUSPEND: 357 + return "Suspend"; 358 358 case DWC3_DEVICE_EVENT_SOF: 359 359 return "Start of Frame"; 360 360 case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
+2 -1
drivers/usb/dwc3/dwc3-imx8mp.c
··· 165 165 if (err < 0) 166 166 goto disable_rpm; 167 167 168 - dwc3_np = of_get_child_by_name(node, "dwc3"); 168 + dwc3_np = of_get_compatible_child(node, "snps,dwc3"); 169 169 if (!dwc3_np) { 170 + err = -ENODEV; 170 171 dev_err(dev, "failed to find dwc3 core child\n"); 171 172 goto disable_rpm; 172 173 }
+5
drivers/usb/dwc3/dwc3-omap.c
··· 437 437 438 438 if (extcon_get_state(edev, EXTCON_USB) == true) 439 439 dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID); 440 + else 441 + dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF); 442 + 440 443 if (extcon_get_state(edev, EXTCON_USB_HOST) == true) 441 444 dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND); 445 + else 446 + dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT); 442 447 443 448 omap->edev = edev; 444 449 }
+1
drivers/usb/dwc3/dwc3-pci.c
··· 123 123 PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"), 124 124 PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"), 125 125 PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), 126 + PROPERTY_ENTRY_BOOL("snps,usb2-gadget-lpm-disable"), 126 127 PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), 127 128 {} 128 129 };
+10 -3
drivers/usb/dwc3/gadget.c
··· 1684 1684 } 1685 1685 } 1686 1686 1687 - return __dwc3_gadget_kick_transfer(dep); 1687 + __dwc3_gadget_kick_transfer(dep); 1688 + 1689 + return 0; 1688 1690 } 1689 1691 1690 1692 static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, ··· 2324 2322 2325 2323 if (DWC3_VER_IS_PRIOR(DWC3, 250A)) 2326 2324 reg |= DWC3_DEVTEN_ULSTCNGEN; 2325 + 2326 + /* On 2.30a and above this bit enables U3/L2-L1 Suspend Events */ 2327 + if (!DWC3_VER_IS_PRIOR(DWC3, 230A)) 2328 + reg |= DWC3_DEVTEN_U3L2L1SUSPEN; 2327 2329 2328 2330 dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); 2329 2331 } ··· 3746 3740 case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: 3747 3741 dwc3_gadget_linksts_change_interrupt(dwc, event->event_info); 3748 3742 break; 3749 - case DWC3_DEVICE_EVENT_EOPF: 3743 + case DWC3_DEVICE_EVENT_SUSPEND: 3750 3744 /* It changed to be suspend event for version 2.30a and above */ 3751 3745 if (!DWC3_VER_IS_PRIOR(DWC3, 230A)) { 3752 3746 /* ··· 4064 4058 4065 4059 void dwc3_gadget_exit(struct dwc3 *dwc) 4066 4060 { 4067 - usb_del_gadget_udc(dwc->gadget); 4061 + usb_del_gadget(dwc->gadget); 4068 4062 dwc3_gadget_free_endpoints(dwc); 4063 + usb_put_gadget(dwc->gadget); 4069 4064 dma_free_coherent(dwc->sysdev, DWC3_BOUNCE_SIZE, dwc->bounce, 4070 4065 dwc->bounce_addr); 4071 4066 kfree(dwc->setup_buf);
+2 -2
drivers/usb/host/fotg210-hcd.c
··· 5568 5568 struct usb_hcd *hcd; 5569 5569 struct resource *res; 5570 5570 int irq; 5571 - int retval = -ENODEV; 5571 + int retval; 5572 5572 struct fotg210_hcd *fotg210; 5573 5573 5574 5574 if (usb_disabled()) ··· 5588 5588 hcd = usb_create_hcd(&fotg210_fotg210_hc_driver, dev, 5589 5589 dev_name(dev)); 5590 5590 if (!hcd) { 5591 - dev_err(dev, "failed to create hcd with err %d\n", retval); 5591 + dev_err(dev, "failed to create hcd\n"); 5592 5592 retval = -ENOMEM; 5593 5593 goto fail_create_hcd; 5594 5594 }
+3 -2
drivers/usb/host/xhci-ext-caps.h
··· 7 7 * Author: Sarah Sharp 8 8 * Some code borrowed from the Linux EHCI driver. 9 9 */ 10 - /* Up to 16 ms to halt an HC */ 11 - #define XHCI_MAX_HALT_USEC (16*1000) 10 + 11 + /* HC should halt within 16 ms, but use 32 ms as some hosts take longer */ 12 + #define XHCI_MAX_HALT_USEC (32 * 1000) 12 13 /* HC not running - set to 1 when run/stop bit is cleared. */ 13 14 #define XHCI_STS_HALT (1<<0) 14 15
+6 -2
drivers/usb/host/xhci-pci.c
··· 57 57 #define PCI_DEVICE_ID_INTEL_CML_XHCI 0xa3af 58 58 #define PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI 0x9a13 59 59 #define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138 60 + #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI 0x461e 60 61 61 62 #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 62 63 #define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba ··· 167 166 (pdev->device == 0x15e0 || pdev->device == 0x15e1)) 168 167 xhci->quirks |= XHCI_SNPS_BROKEN_SUSPEND; 169 168 170 - if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x15e5) 169 + if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x15e5) { 171 170 xhci->quirks |= XHCI_DISABLE_SPARSE; 171 + xhci->quirks |= XHCI_RESET_ON_RESUME; 172 + } 172 173 173 174 if (pdev->vendor == PCI_VENDOR_ID_AMD) 174 175 xhci->quirks |= XHCI_TRUST_TX_LENGTH; ··· 246 243 pdev->device == PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_XHCI || 247 244 pdev->device == PCI_DEVICE_ID_INTEL_ICE_LAKE_XHCI || 248 245 pdev->device == PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI || 249 - pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI)) 246 + pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI || 247 + pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI)) 250 248 xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; 251 249 252 250 if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
+11 -5
drivers/usb/host/xhci-ring.c
··· 862 862 return ret; 863 863 } 864 864 865 - static void xhci_handle_halted_endpoint(struct xhci_hcd *xhci, 865 + static int xhci_handle_halted_endpoint(struct xhci_hcd *xhci, 866 866 struct xhci_virt_ep *ep, unsigned int stream_id, 867 867 struct xhci_td *td, 868 868 enum xhci_ep_reset_type reset_type) ··· 875 875 * Device will be reset soon to recover the link so don't do anything 876 876 */ 877 877 if (ep->vdev->flags & VDEV_PORT_ERROR) 878 - return; 878 + return -ENODEV; 879 879 880 880 /* add td to cancelled list and let reset ep handler take care of it */ 881 881 if (reset_type == EP_HARD_RESET) { ··· 888 888 889 889 if (ep->ep_state & EP_HALTED) { 890 890 xhci_dbg(xhci, "Reset ep command already pending\n"); 891 - return; 891 + return 0; 892 892 } 893 893 894 894 err = xhci_reset_halted_ep(xhci, slot_id, ep->ep_index, reset_type); 895 895 if (err) 896 - return; 896 + return err; 897 897 898 898 ep->ep_state |= EP_HALTED; 899 899 900 900 xhci_ring_cmd_db(xhci); 901 + 902 + return 0; 901 903 } 902 904 903 905 /* ··· 1016 1014 struct xhci_td *td = NULL; 1017 1015 enum xhci_ep_reset_type reset_type; 1018 1016 struct xhci_command *command; 1017 + int err; 1019 1018 1020 1019 if (unlikely(TRB_TO_SUSPEND_PORT(le32_to_cpu(trb->generic.field[3])))) { 1021 1020 if (!xhci->devs[slot_id]) ··· 1061 1058 td->status = -EPROTO; 1062 1059 } 1063 1060 /* reset ep, reset handler cleans up cancelled tds */ 1064 - xhci_handle_halted_endpoint(xhci, ep, 0, td, reset_type); 1061 + err = xhci_handle_halted_endpoint(xhci, ep, 0, td, 1062 + reset_type); 1063 + if (err) 1064 + break; 1065 1065 xhci_stop_watchdog_timer_in_irq(xhci, ep); 1066 1066 return; 1067 1067 case EP_STATE_RUNNING:
+3 -3
drivers/usb/host/xhci.c
··· 1514 1514 * we need to issue an evaluate context command and wait on it. 1515 1515 */ 1516 1516 static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id, 1517 - unsigned int ep_index, struct urb *urb) 1517 + unsigned int ep_index, struct urb *urb, gfp_t mem_flags) 1518 1518 { 1519 1519 struct xhci_container_ctx *out_ctx; 1520 1520 struct xhci_input_control_ctx *ctrl_ctx; ··· 1545 1545 * changes max packet sizes. 1546 1546 */ 1547 1547 1548 - command = xhci_alloc_command(xhci, true, GFP_KERNEL); 1548 + command = xhci_alloc_command(xhci, true, mem_flags); 1549 1549 if (!command) 1550 1550 return -ENOMEM; 1551 1551 ··· 1639 1639 */ 1640 1640 if (urb->dev->speed == USB_SPEED_FULL) { 1641 1641 ret = xhci_check_maxpacket(xhci, slot_id, 1642 - ep_index, urb); 1642 + ep_index, urb, mem_flags); 1643 1643 if (ret < 0) { 1644 1644 xhci_urb_free_priv(urb_priv); 1645 1645 urb->hcpriv = NULL;
+1 -1
drivers/usb/musb/mediatek.c
··· 518 518 519 519 glue->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); 520 520 if (IS_ERR(glue->xceiv)) { 521 - dev_err(dev, "fail to getting usb-phy %d\n", ret); 522 521 ret = PTR_ERR(glue->xceiv); 522 + dev_err(dev, "fail to getting usb-phy %d\n", ret); 523 523 goto err_unregister_usb_phy; 524 524 } 525 525
+89 -14
drivers/usb/typec/tcpm/tcpm.c
··· 259 259 #define ALTMODE_DISCOVERY_MAX (SVID_DISCOVERY_MAX * MODE_DISCOVERY_MAX) 260 260 261 261 #define GET_SINK_CAP_RETRY_MS 100 262 + #define SEND_DISCOVER_RETRY_MS 100 262 263 263 264 struct pd_mode_data { 264 265 int svid_index; /* current SVID index */ ··· 367 366 struct kthread_work vdm_state_machine; 368 367 struct hrtimer enable_frs_timer; 369 368 struct kthread_work enable_frs; 369 + struct hrtimer send_discover_timer; 370 + struct kthread_work send_discover_work; 370 371 bool state_machine_running; 371 372 bool vdm_sm_running; 372 373 ··· 1181 1178 } 1182 1179 } 1183 1180 1181 + static void mod_send_discover_delayed_work(struct tcpm_port *port, unsigned int delay_ms) 1182 + { 1183 + if (delay_ms) { 1184 + hrtimer_start(&port->send_discover_timer, ms_to_ktime(delay_ms), HRTIMER_MODE_REL); 1185 + } else { 1186 + hrtimer_cancel(&port->send_discover_timer); 1187 + kthread_queue_work(port->wq, &port->send_discover_work); 1188 + } 1189 + } 1190 + 1184 1191 static void tcpm_set_state(struct tcpm_port *port, enum tcpm_state state, 1185 1192 unsigned int delay_ms) 1186 1193 { ··· 1868 1855 res = tcpm_ams_start(port, DISCOVER_IDENTITY); 1869 1856 if (res == 0) 1870 1857 port->send_discover = false; 1858 + else if (res == -EAGAIN) 1859 + mod_send_discover_delayed_work(port, 1860 + SEND_DISCOVER_RETRY_MS); 1871 1861 break; 1872 1862 case CMD_DISCOVER_SVID: 1873 1863 res = tcpm_ams_start(port, DISCOVER_SVIDS); ··· 1896 1880 } 1897 1881 1898 1882 if (res < 0) { 1899 - port->vdm_sm_running = false; 1883 + port->vdm_state = VDM_STATE_ERR_BUSY; 1900 1884 return; 1901 1885 } 1902 1886 } ··· 1912 1896 port->vdo_data[0] = port->vdo_retry; 1913 1897 port->vdo_count = 1; 1914 1898 port->vdm_state = VDM_STATE_READY; 1899 + tcpm_ams_finish(port); 1915 1900 break; 1916 1901 case VDM_STATE_BUSY: 1917 1902 port->vdm_state = VDM_STATE_ERR_TMOUT; ··· 1978 1961 port->vdm_state != VDM_STATE_BUSY && 1979 1962 port->vdm_state != VDM_STATE_SEND_MESSAGE); 1980 1963 1981 - if (port->vdm_state == VDM_STATE_ERR_TMOUT) 1964 + if (port->vdm_state < VDM_STATE_READY) 1982 1965 port->vdm_sm_running = false; 1983 1966 1984 1967 mutex_unlock(&port->lock); ··· 2407 2390 port->nr_sink_caps = cnt; 2408 2391 port->sink_cap_done = true; 2409 2392 if (port->ams == GET_SINK_CAPABILITIES) 2410 - tcpm_pd_handle_state(port, ready_state(port), NONE_AMS, 0); 2393 + tcpm_set_state(port, ready_state(port), 0); 2411 2394 /* Unexpected Sink Capabilities */ 2412 2395 else 2413 2396 tcpm_pd_handle_msg(port, ··· 2569 2552 port->sink_cap_done = true; 2570 2553 tcpm_set_state(port, ready_state(port), 0); 2571 2554 break; 2555 + case SRC_READY: 2556 + case SNK_READY: 2557 + if (port->vdm_state > VDM_STATE_READY) { 2558 + port->vdm_state = VDM_STATE_DONE; 2559 + if (tcpm_vdm_ams(port)) 2560 + tcpm_ams_finish(port); 2561 + mod_vdm_delayed_work(port, 0); 2562 + break; 2563 + } 2564 + fallthrough; 2572 2565 default: 2573 2566 tcpm_pd_handle_state(port, 2574 2567 port->pwr_role == TYPEC_SOURCE ? ··· 3709 3682 return SNK_UNATTACHED; 3710 3683 } 3711 3684 3712 - static void tcpm_check_send_discover(struct tcpm_port *port) 3713 - { 3714 - if ((port->data_role == TYPEC_HOST || port->negotiated_rev > PD_REV20) && 3715 - port->send_discover && port->pd_capable) 3716 - tcpm_send_vdm(port, USB_SID_PD, CMD_DISCOVER_IDENT, NULL, 0); 3717 - port->send_discover = false; 3718 - } 3719 - 3720 3685 static void tcpm_swap_complete(struct tcpm_port *port, int result) 3721 3686 { 3722 3687 if (port->swap_pending) { ··· 3945 3926 break; 3946 3927 } 3947 3928 3948 - tcpm_check_send_discover(port); 3929 + /* 3930 + * 6.4.4.3.1 Discover Identity 3931 + * "The Discover Identity Command Shall only be sent to SOP when there is an 3932 + * Explicit Contract." 3933 + * For now, this driver only supports SOP for DISCOVER_IDENTITY, thus using 3934 + * port->explicit_contract to decide whether to send the command. 3935 + */ 3936 + if (port->explicit_contract) 3937 + mod_send_discover_delayed_work(port, 0); 3938 + else 3939 + port->send_discover = false; 3940 + 3949 3941 /* 3950 3942 * 6.3.5 3951 3943 * Sending ping messages is not necessary if ··· 4085 4055 if (port->vbus_present) { 4086 4056 u32 current_lim = tcpm_get_current_limit(port); 4087 4057 4088 - if (port->slow_charger_loop || (current_lim > PD_P_SNK_STDBY_MW / 5)) 4058 + if (port->slow_charger_loop && (current_lim > PD_P_SNK_STDBY_MW / 5)) 4089 4059 current_lim = PD_P_SNK_STDBY_MW / 5; 4090 4060 tcpm_set_current_limit(port, current_lim, 5000); 4091 4061 tcpm_set_charge(port, true); ··· 4224 4194 break; 4225 4195 } 4226 4196 4227 - tcpm_check_send_discover(port); 4197 + /* 4198 + * 6.4.4.3.1 Discover Identity 4199 + * "The Discover Identity Command Shall only be sent to SOP when there is an 4200 + * Explicit Contract." 4201 + * For now, this driver only supports SOP for DISCOVER_IDENTITY, thus using 4202 + * port->explicit_contract. 4203 + */ 4204 + if (port->explicit_contract) 4205 + mod_send_discover_delayed_work(port, 0); 4206 + else 4207 + port->send_discover = false; 4208 + 4228 4209 power_supply_changed(port->psy); 4229 4210 break; 4230 4211 ··· 5329 5288 mutex_unlock(&port->lock); 5330 5289 } 5331 5290 5291 + static void tcpm_send_discover_work(struct kthread_work *work) 5292 + { 5293 + struct tcpm_port *port = container_of(work, struct tcpm_port, send_discover_work); 5294 + 5295 + mutex_lock(&port->lock); 5296 + /* No need to send DISCOVER_IDENTITY anymore */ 5297 + if (!port->send_discover) 5298 + goto unlock; 5299 + 5300 + /* Retry if the port is not idle */ 5301 + if ((port->state != SRC_READY && port->state != SNK_READY) || port->vdm_sm_running) { 5302 + mod_send_discover_delayed_work(port, SEND_DISCOVER_RETRY_MS); 5303 + goto unlock; 5304 + } 5305 + 5306 + /* Only send the Message if the port is host for PD rev2.0 */ 5307 + if (port->data_role == TYPEC_HOST || port->negotiated_rev > PD_REV20) 5308 + tcpm_send_vdm(port, USB_SID_PD, CMD_DISCOVER_IDENT, NULL, 0); 5309 + 5310 + unlock: 5311 + mutex_unlock(&port->lock); 5312 + } 5313 + 5332 5314 static int tcpm_dr_set(struct typec_port *p, enum typec_data_role data) 5333 5315 { 5334 5316 struct tcpm_port *port = typec_get_drvdata(p); ··· 6157 6093 return HRTIMER_NORESTART; 6158 6094 } 6159 6095 6096 + static enum hrtimer_restart send_discover_timer_handler(struct hrtimer *timer) 6097 + { 6098 + struct tcpm_port *port = container_of(timer, struct tcpm_port, send_discover_timer); 6099 + 6100 + kthread_queue_work(port->wq, &port->send_discover_work); 6101 + return HRTIMER_NORESTART; 6102 + } 6103 + 6160 6104 struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) 6161 6105 { 6162 6106 struct tcpm_port *port; ··· 6195 6123 kthread_init_work(&port->vdm_state_machine, vdm_state_machine_work); 6196 6124 kthread_init_work(&port->event_work, tcpm_pd_event_handler); 6197 6125 kthread_init_work(&port->enable_frs, tcpm_enable_frs_work); 6126 + kthread_init_work(&port->send_discover_work, tcpm_send_discover_work); 6198 6127 hrtimer_init(&port->state_machine_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 6199 6128 port->state_machine_timer.function = state_machine_timer_handler; 6200 6129 hrtimer_init(&port->vdm_state_machine_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 6201 6130 port->vdm_state_machine_timer.function = vdm_state_machine_timer_handler; 6202 6131 hrtimer_init(&port->enable_frs_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 6203 6132 port->enable_frs_timer.function = enable_frs_timer_handler; 6133 + hrtimer_init(&port->send_discover_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 6134 + port->send_discover_timer.function = send_discover_timer_handler; 6204 6135 6205 6136 spin_lock_init(&port->pd_event_lock); 6206 6137
+37 -11
drivers/usb/typec/ucsi/ucsi.c
··· 495 495 } 496 496 } 497 497 498 - static void ucsi_get_pdos(struct ucsi_connector *con, int is_partner) 498 + static int ucsi_get_pdos(struct ucsi_connector *con, int is_partner, 499 + u32 *pdos, int offset, int num_pdos) 499 500 { 500 501 struct ucsi *ucsi = con->ucsi; 501 502 u64 command; ··· 504 503 505 504 command = UCSI_COMMAND(UCSI_GET_PDOS) | UCSI_CONNECTOR_NUMBER(con->num); 506 505 command |= UCSI_GET_PDOS_PARTNER_PDO(is_partner); 507 - command |= UCSI_GET_PDOS_NUM_PDOS(UCSI_MAX_PDOS - 1); 506 + command |= UCSI_GET_PDOS_PDO_OFFSET(offset); 507 + command |= UCSI_GET_PDOS_NUM_PDOS(num_pdos - 1); 508 508 command |= UCSI_GET_PDOS_SRC_PDOS; 509 - ret = ucsi_send_command(ucsi, command, con->src_pdos, 510 - sizeof(con->src_pdos)); 511 - if (ret < 0) { 509 + ret = ucsi_send_command(ucsi, command, pdos + offset, 510 + num_pdos * sizeof(u32)); 511 + if (ret < 0) 512 512 dev_err(ucsi->dev, "UCSI_GET_PDOS failed (%d)\n", ret); 513 - return; 514 - } 515 - con->num_pdos = ret / sizeof(u32); /* number of bytes to 32-bit PDOs */ 516 - if (ret == 0) 513 + if (ret == 0 && offset == 0) 517 514 dev_warn(ucsi->dev, "UCSI_GET_PDOS returned 0 bytes\n"); 515 + 516 + return ret; 517 + } 518 + 519 + static void ucsi_get_src_pdos(struct ucsi_connector *con, int is_partner) 520 + { 521 + int ret; 522 + 523 + /* UCSI max payload means only getting at most 4 PDOs at a time */ 524 + ret = ucsi_get_pdos(con, 1, con->src_pdos, 0, UCSI_MAX_PDOS); 525 + if (ret < 0) 526 + return; 527 + 528 + con->num_pdos = ret / sizeof(u32); /* number of bytes to 32-bit PDOs */ 529 + if (con->num_pdos < UCSI_MAX_PDOS) 530 + return; 531 + 532 + /* get the remaining PDOs, if any */ 533 + ret = ucsi_get_pdos(con, 1, con->src_pdos, UCSI_MAX_PDOS, 534 + PDO_MAX_OBJECTS - UCSI_MAX_PDOS); 535 + if (ret < 0) 536 + return; 537 + 538 + con->num_pdos += ret / sizeof(u32); 518 539 } 519 540 520 541 static void ucsi_pwr_opmode_change(struct ucsi_connector *con) ··· 545 522 case UCSI_CONSTAT_PWR_OPMODE_PD: 546 523 con->rdo = con->status.request_data_obj; 547 524 typec_set_pwr_opmode(con->port, TYPEC_PWR_MODE_PD); 548 - ucsi_get_pdos(con, 1); 525 + ucsi_get_src_pdos(con, 1); 549 526 break; 550 527 case UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5: 551 528 con->rdo = 0; ··· 1022 999 .pr_set = ucsi_pr_swap 1023 1000 }; 1024 1001 1002 + /* Caller must call fwnode_handle_put() after use */ 1025 1003 static struct fwnode_handle *ucsi_find_fwnode(struct ucsi_connector *con) 1026 1004 { 1027 1005 struct fwnode_handle *fwnode; ··· 1057 1033 command |= UCSI_CONNECTOR_NUMBER(con->num); 1058 1034 ret = ucsi_send_command(ucsi, command, &con->cap, sizeof(con->cap)); 1059 1035 if (ret < 0) 1060 - goto out; 1036 + goto out_unlock; 1061 1037 1062 1038 if (con->cap.op_mode & UCSI_CONCAP_OPMODE_DRP) 1063 1039 cap->data = TYPEC_PORT_DRD; ··· 1175 1151 trace_ucsi_register_port(con->num, &con->status); 1176 1152 1177 1153 out: 1154 + fwnode_handle_put(cap->fwnode); 1155 + out_unlock: 1178 1156 mutex_unlock(&con->lock); 1179 1157 return ret; 1180 1158 }
+4 -2
drivers/usb/typec/ucsi/ucsi.h
··· 8 8 #include <linux/power_supply.h> 9 9 #include <linux/types.h> 10 10 #include <linux/usb/typec.h> 11 + #include <linux/usb/pd.h> 11 12 #include <linux/usb/role.h> 12 13 13 14 /* -------------------------------------------------------------------------- */ ··· 135 134 136 135 /* GET_PDOS command bits */ 137 136 #define UCSI_GET_PDOS_PARTNER_PDO(_r_) ((u64)(_r_) << 23) 137 + #define UCSI_GET_PDOS_PDO_OFFSET(_r_) ((u64)(_r_) << 24) 138 138 #define UCSI_GET_PDOS_NUM_PDOS(_r_) ((u64)(_r_) << 32) 139 + #define UCSI_MAX_PDOS (4) 139 140 #define UCSI_GET_PDOS_SRC_PDOS ((u64)1 << 34) 140 141 141 142 /* -------------------------------------------------------------------------- */ ··· 305 302 306 303 #define UCSI_MAX_SVID 5 307 304 #define UCSI_MAX_ALTMODES (UCSI_MAX_SVID * 6) 308 - #define UCSI_MAX_PDOS (4) 309 305 310 306 #define UCSI_TYPEC_VSAFE5V 5000 311 307 #define UCSI_TYPEC_1_5_CURRENT 1500 ··· 332 330 struct power_supply *psy; 333 331 struct power_supply_desc psy_desc; 334 332 u32 rdo; 335 - u32 src_pdos[UCSI_MAX_PDOS]; 333 + u32 src_pdos[PDO_MAX_OBJECTS]; 336 334 int num_pdos; 337 335 338 336 struct usb_role_switch *usb_role_sw;