Merge tag 'usb-6.8-rc6' 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 6.8-rc6 to resolve some reported
problems. These include:

- regression fixes with typec tpcm code as reported by many

- cdnsp and cdns3 driver fixes

- usb role setting code bugfixes

- build fix for uhci driver

- ncm gadget driver bugfix

- MAINTAINERS entry update

All of these have been in linux-next all week with no reported issues
and there is at least one fix in here that is in Thorsten's regression
list that is being tracked"

* tag 'usb-6.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
usb: typec: tpcm: Fix issues with power being removed during reset
MAINTAINERS: Drop myself as maintainer of TYPEC port controller drivers
usb: gadget: ncm: Avoid dropping datagrams of properly parsed NTBs
Revert "usb: typec: tcpm: reset counter when enter into unattached state after try role"
usb: gadget: omap_udc: fix USB gadget regression on Palm TE
usb: dwc3: gadget: Don't disconnect if not started
usb: cdns3: fix memory double free when handle zero packet
usb: cdns3: fixed memory use after free at cdns3_gadget_ep_disable()
usb: roles: don't get/set_role() when usb_role_switch is unregistered
usb: roles: fix NULL pointer issue when put module's reference
usb: cdnsp: fixed issue with incorrect detecting CDNSP family controllers
usb: cdnsp: blocked some cdns3 specific code
usb: uhci-grlib: Explicitly include linux/platform_device.h

Changed files
+75 -26
drivers
usb
cdns3
dwc3
gadget
function
udc
host
roles
typec
tcpm
+1 -2
MAINTAINERS
··· 22880 22880 F: drivers/usb/typec/mux/pi3usb30532.c 22881 22881 22882 22882 USB TYPEC PORT CONTROLLER DRIVERS 22883 - M: Guenter Roeck <linux@roeck-us.net> 22884 22883 L: linux-usb@vger.kernel.org 22885 - S: Maintained 22884 + S: Orphan 22886 22885 F: drivers/usb/typec/tcpm/ 22887 22886 22888 22887 USB UHCI DRIVER
+6 -2
drivers/usb/cdns3/cdns3-gadget.c
··· 828 828 return; 829 829 } 830 830 831 - if (request->complete) { 831 + /* 832 + * zlp request is appended by driver, needn't call usb_gadget_giveback_request() to notify 833 + * gadget composite driver. 834 + */ 835 + if (request->complete && request->buf != priv_dev->zlp_buf) { 832 836 spin_unlock(&priv_dev->lock); 833 837 usb_gadget_giveback_request(&priv_ep->endpoint, 834 838 request); ··· 2544 2540 2545 2541 while (!list_empty(&priv_ep->wa2_descmiss_req_list)) { 2546 2542 priv_req = cdns3_next_priv_request(&priv_ep->wa2_descmiss_req_list); 2543 + list_del_init(&priv_req->list); 2547 2544 2548 2545 kfree(priv_req->request.buf); 2549 2546 cdns3_gadget_ep_free_request(&priv_ep->endpoint, 2550 2547 &priv_req->request); 2551 - list_del_init(&priv_req->list); 2552 2548 --priv_ep->wa2_counter; 2553 2549 } 2554 2550
-1
drivers/usb/cdns3/core.c
··· 395 395 return ret; 396 396 } 397 397 398 - 399 398 /** 400 399 * cdns_wakeup_irq - interrupt handler for wakeup events 401 400 * @irq: irq number for cdns3/cdnsp core device
+9 -4
drivers/usb/cdns3/drd.c
··· 156 156 */ 157 157 static void cdns_otg_disable_irq(struct cdns *cdns) 158 158 { 159 - writel(0, &cdns->otg_irq_regs->ien); 159 + if (cdns->version) 160 + writel(0, &cdns->otg_irq_regs->ien); 160 161 } 161 162 162 163 /** ··· 423 422 424 423 cdns->otg_regs = (void __iomem *)&cdns->otg_v1_regs->cmd; 425 424 426 - if (readl(&cdns->otg_cdnsp_regs->did) == OTG_CDNSP_DID) { 425 + state = readl(&cdns->otg_cdnsp_regs->did); 426 + 427 + if (OTG_CDNSP_CHECK_DID(state)) { 427 428 cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem *) 428 429 &cdns->otg_cdnsp_regs->ien; 429 430 cdns->version = CDNSP_CONTROLLER_V2; 430 - } else { 431 + } else if (OTG_CDNS3_CHECK_DID(state)) { 431 432 cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem *) 432 433 &cdns->otg_v1_regs->ien; 433 434 writel(1, &cdns->otg_v1_regs->simulate); 434 435 cdns->version = CDNS3_CONTROLLER_V1; 436 + } else { 437 + dev_err(cdns->dev, "not supporte DID=0x%08x\n", state); 438 + return -EINVAL; 435 439 } 436 440 437 441 dev_dbg(cdns->dev, "DRD version v1 (ID: %08x, rev: %08x)\n", ··· 488 482 489 483 return 0; 490 484 } 491 - 492 485 493 486 /* Indicate the cdns3 core was power lost before */ 494 487 bool cdns_power_is_lost(struct cdns *cdns)
+5 -1
drivers/usb/cdns3/drd.h
··· 79 79 __le32 susp_timing_ctrl; 80 80 }; 81 81 82 - #define OTG_CDNSP_DID 0x0004034E 82 + /* CDNSP driver supports 0x000403xx Cadence USB controller family. */ 83 + #define OTG_CDNSP_CHECK_DID(did) (((did) & GENMASK(31, 8)) == 0x00040300) 84 + 85 + /* CDNS3 driver supports 0x000402xx Cadence USB controller family. */ 86 + #define OTG_CDNS3_CHECK_DID(did) (((did) & GENMASK(31, 8)) == 0x00040200) 83 87 84 88 /* 85 89 * Common registers interface for both CDNS3 and CDNSP version of DRD.
+14 -2
drivers/usb/cdns3/host.c
··· 18 18 #include "../host/xhci.h" 19 19 #include "../host/xhci-plat.h" 20 20 21 + /* 22 + * The XECP_PORT_CAP_REG and XECP_AUX_CTRL_REG1 exist only 23 + * in Cadence USB3 dual-role controller, so it can't be used 24 + * with Cadence CDNSP dual-role controller. 25 + */ 21 26 #define XECP_PORT_CAP_REG 0x8000 22 27 #define XECP_AUX_CTRL_REG1 0x8120 23 28 ··· 62 57 .resume_quirk = xhci_cdns3_resume_quirk, 63 58 }; 64 59 60 + static const struct xhci_plat_priv xhci_plat_cdnsp_xhci; 61 + 65 62 static int __cdns_host_init(struct cdns *cdns) 66 63 { 67 64 struct platform_device *xhci; ··· 88 81 goto err1; 89 82 } 90 83 91 - cdns->xhci_plat_data = kmemdup(&xhci_plat_cdns3_xhci, 92 - sizeof(struct xhci_plat_priv), GFP_KERNEL); 84 + if (cdns->version < CDNSP_CONTROLLER_V2) 85 + cdns->xhci_plat_data = kmemdup(&xhci_plat_cdns3_xhci, 86 + sizeof(struct xhci_plat_priv), GFP_KERNEL); 87 + else 88 + cdns->xhci_plat_data = kmemdup(&xhci_plat_cdnsp_xhci, 89 + sizeof(struct xhci_plat_priv), GFP_KERNEL); 90 + 93 91 if (!cdns->xhci_plat_data) { 94 92 ret = -ENOMEM; 95 93 goto err1;
+5
drivers/usb/dwc3/gadget.c
··· 2650 2650 int ret; 2651 2651 2652 2652 spin_lock_irqsave(&dwc->lock, flags); 2653 + if (!dwc->pullups_connected) { 2654 + spin_unlock_irqrestore(&dwc->lock, flags); 2655 + return 0; 2656 + } 2657 + 2653 2658 dwc->connected = false; 2654 2659 2655 2660 /*
+9 -1
drivers/usb/gadget/function/f_ncm.c
··· 1338 1338 "Parsed NTB with %d frames\n", dgram_counter); 1339 1339 1340 1340 to_process -= block_len; 1341 - if (to_process != 0) { 1341 + 1342 + /* 1343 + * Windows NCM driver avoids USB ZLPs by adding a 1-byte 1344 + * zero pad as needed. 1345 + */ 1346 + if (to_process == 1 && 1347 + (*(unsigned char *)(ntb_ptr + block_len) == 0x00)) { 1348 + to_process--; 1349 + } else if (to_process > 0) { 1342 1350 ntb_ptr = (unsigned char *)(ntb_ptr + block_len); 1343 1351 goto parse_ntb; 1344 1352 }
+2 -1
drivers/usb/gadget/udc/omap_udc.c
··· 2036 2036 2037 2037 static inline int machine_without_vbus_sense(void) 2038 2038 { 2039 - return machine_is_omap_osk() || machine_is_sx1(); 2039 + return machine_is_omap_osk() || machine_is_omap_palmte() || 2040 + machine_is_sx1(); 2040 2041 } 2041 2042 2042 2043 static int omap_udc_start(struct usb_gadget *g,
+1
drivers/usb/host/uhci-grlib.c
··· 22 22 #include <linux/of_irq.h> 23 23 #include <linux/of_address.h> 24 24 #include <linux/of_platform.h> 25 + #include <linux/platform_device.h> 25 26 26 27 static int uhci_grlib_init(struct usb_hcd *hcd) 27 28 {
+21 -8
drivers/usb/roles/class.c
··· 21 21 struct usb_role_switch { 22 22 struct device dev; 23 23 struct mutex lock; /* device lock*/ 24 + struct module *module; /* the module this device depends on */ 24 25 enum usb_role role; 26 + bool registered; 25 27 26 28 /* From descriptor */ 27 29 struct device *usb2_port; ··· 50 48 if (IS_ERR_OR_NULL(sw)) 51 49 return 0; 52 50 51 + if (!sw->registered) 52 + return -EOPNOTSUPP; 53 + 53 54 mutex_lock(&sw->lock); 54 55 55 56 ret = sw->set(sw, role); ··· 78 73 { 79 74 enum usb_role role; 80 75 81 - if (IS_ERR_OR_NULL(sw)) 76 + if (IS_ERR_OR_NULL(sw) || !sw->registered) 82 77 return USB_ROLE_NONE; 83 78 84 79 mutex_lock(&sw->lock); ··· 140 135 usb_role_switch_match); 141 136 142 137 if (!IS_ERR_OR_NULL(sw)) 143 - WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); 138 + WARN_ON(!try_module_get(sw->module)); 144 139 145 140 return sw; 146 141 } ··· 162 157 sw = fwnode_connection_find_match(fwnode, "usb-role-switch", 163 158 NULL, usb_role_switch_match); 164 159 if (!IS_ERR_OR_NULL(sw)) 165 - WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); 160 + WARN_ON(!try_module_get(sw->module)); 166 161 167 162 return sw; 168 163 } ··· 177 172 void usb_role_switch_put(struct usb_role_switch *sw) 178 173 { 179 174 if (!IS_ERR_OR_NULL(sw)) { 180 - module_put(sw->dev.parent->driver->owner); 175 + module_put(sw->module); 181 176 put_device(&sw->dev); 182 177 } 183 178 } ··· 194 189 usb_role_switch_find_by_fwnode(const struct fwnode_handle *fwnode) 195 190 { 196 191 struct device *dev; 192 + struct usb_role_switch *sw = NULL; 197 193 198 194 if (!fwnode) 199 195 return NULL; 200 196 201 197 dev = class_find_device_by_fwnode(&role_class, fwnode); 202 - if (dev) 203 - WARN_ON(!try_module_get(dev->parent->driver->owner)); 198 + if (dev) { 199 + sw = to_role_switch(dev); 200 + WARN_ON(!try_module_get(sw->module)); 201 + } 204 202 205 - return dev ? to_role_switch(dev) : NULL; 203 + return sw; 206 204 } 207 205 EXPORT_SYMBOL_GPL(usb_role_switch_find_by_fwnode); 208 206 ··· 346 338 sw->set = desc->set; 347 339 sw->get = desc->get; 348 340 341 + sw->module = parent->driver->owner; 349 342 sw->dev.parent = parent; 350 343 sw->dev.fwnode = desc->fwnode; 351 344 sw->dev.class = &role_class; ··· 360 351 put_device(&sw->dev); 361 352 return ERR_PTR(ret); 362 353 } 354 + 355 + sw->registered = true; 363 356 364 357 /* TODO: Symlinks for the host port and the device controller. */ 365 358 ··· 377 366 */ 378 367 void usb_role_switch_unregister(struct usb_role_switch *sw) 379 368 { 380 - if (!IS_ERR_OR_NULL(sw)) 369 + if (!IS_ERR_OR_NULL(sw)) { 370 + sw->registered = false; 381 371 device_unregister(&sw->dev); 372 + } 382 373 } 383 374 EXPORT_SYMBOL_GPL(usb_role_switch_unregister); 384 375
+2 -4
drivers/usb/typec/tcpm/tcpm.c
··· 3743 3743 if (tcpm_port_is_disconnected(port)) 3744 3744 port->hard_reset_count = 0; 3745 3745 3746 - port->try_src_count = 0; 3747 - port->try_snk_count = 0; 3748 - 3749 3746 if (!port->attached) 3750 3747 return; 3751 3748 ··· 4873 4876 break; 4874 4877 case PORT_RESET: 4875 4878 tcpm_reset_port(port); 4876 - tcpm_set_cc(port, TYPEC_CC_OPEN); 4879 + tcpm_set_cc(port, tcpm_default_state(port) == SNK_UNATTACHED ? 4880 + TYPEC_CC_RD : tcpm_rp_cc(port)); 4877 4881 tcpm_set_state(port, PORT_RESET_WAIT_OFF, 4878 4882 PD_T_ERROR_RECOVERY); 4879 4883 break;