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-6.12-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB driver fixes from Greg KH:
"Here are some small USB driver fixes and new device ids for 6.12-rc4:

- xhci driver fixes for a number of reported issues

- new usb-serial driver ids

- dwc3 driver fixes for reported problems.

- usb gadget driver fixes for reported problems

- typec driver fixes

- MAINTAINER file updates

All of these have been in linux-next this week with no reported issues"

* tag 'usb-6.12-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
USB: serial: option: add Telit FN920C04 MBIM compositions
USB: serial: option: add support for Quectel EG916Q-GL
xhci: dbc: honor usb transfer size boundaries.
usb: xhci: Fix handling errors mid TD followed by other errors
xhci: Mitigate failed set dequeue pointer commands
xhci: Fix incorrect stream context type macro
USB: gadget: dummy-hcd: Fix "task hung" problem
usb: gadget: f_uac2: fix return value for UAC2_ATTRIBUTE_STRING store
usb: dwc3: core: Fix system suspend on TI AM62 platforms
xhci: tegra: fix checked USB2 port number
usb: dwc3: Wait for EndXfer completion before restoring GUSB2PHYCFG
usb: typec: qcom-pmic-typec: fix sink status being overwritten with RP_DEF
usb: typec: altmode should keep reference to parent
MAINTAINERS: usb: raw-gadget: add bug tracker link
MAINTAINERS: Add an entry for the LJCA drivers

+151 -58
+11
MAINTAINERS
··· 11604 11604 F: drivers/crypto/intel/keembay/ocs-hcu.c 11605 11605 F: drivers/crypto/intel/keembay/ocs-hcu.h 11606 11606 11607 + INTEL LA JOLLA COVE ADAPTER (LJCA) USB I/O EXPANDER DRIVERS 11608 + M: Wentong Wu <wentong.wu@intel.com> 11609 + M: Sakari Ailus <sakari.ailus@linux.intel.com> 11610 + S: Maintained 11611 + F: drivers/gpio/gpio-ljca.c 11612 + F: drivers/i2c/busses/i2c-ljca.c 11613 + F: drivers/spi/spi-ljca.c 11614 + F: drivers/usb/misc/usb-ljca.c 11615 + F: include/linux/usb/ljca.h 11616 + 11607 11617 INTEL MANAGEMENT ENGINE (mei) 11608 11618 M: Tomas Winkler <tomas.winkler@intel.com> 11609 11619 L: linux-kernel@vger.kernel.org ··· 24088 24078 R: Andrey Konovalov <andreyknvl@gmail.com> 24089 24079 L: linux-usb@vger.kernel.org 24090 24080 S: Maintained 24081 + B: https://github.com/xairy/raw-gadget/issues 24091 24082 F: Documentation/usb/raw-gadget.rst 24092 24083 F: drivers/usb/gadget/legacy/raw_gadget.c 24093 24084 F: include/uapi/linux/usb/raw_gadget.h
+19
drivers/usb/dwc3/core.c
··· 2342 2342 u32 reg; 2343 2343 int i; 2344 2344 2345 + dwc->susphy_state = (dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)) & 2346 + DWC3_GUSB2PHYCFG_SUSPHY) || 2347 + (dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)) & 2348 + DWC3_GUSB3PIPECTL_SUSPHY); 2349 + 2345 2350 switch (dwc->current_dr_role) { 2346 2351 case DWC3_GCTL_PRTCAP_DEVICE: 2347 2352 if (pm_runtime_suspended(dwc->dev)) ··· 2396 2391 default: 2397 2392 /* do nothing */ 2398 2393 break; 2394 + } 2395 + 2396 + if (!PMSG_IS_AUTO(msg)) { 2397 + /* 2398 + * TI AM62 platform requires SUSPHY to be 2399 + * enabled for system suspend to work. 2400 + */ 2401 + if (!dwc->susphy_state) 2402 + dwc3_enable_susphy(dwc, true); 2399 2403 } 2400 2404 2401 2405 return 0; ··· 2472 2458 default: 2473 2459 /* do nothing */ 2474 2460 break; 2461 + } 2462 + 2463 + if (!PMSG_IS_AUTO(msg)) { 2464 + /* restore SUSPHY state to that before system suspend. */ 2465 + dwc3_enable_susphy(dwc, dwc->susphy_state); 2475 2466 } 2476 2467 2477 2468 return 0;
+3
drivers/usb/dwc3/core.h
··· 1150 1150 * @sys_wakeup: set if the device may do system wakeup. 1151 1151 * @wakeup_configured: set if the device is configured for remote wakeup. 1152 1152 * @suspended: set to track suspend event due to U3/L2. 1153 + * @susphy_state: state of DWC3_GUSB2PHYCFG_SUSPHY + DWC3_GUSB3PIPECTL_SUSPHY 1154 + * before PM suspend. 1153 1155 * @imod_interval: set the interrupt moderation interval in 250ns 1154 1156 * increments or 0 to disable. 1155 1157 * @max_cfg_eps: current max number of IN eps used across all USB configs. ··· 1384 1382 unsigned sys_wakeup:1; 1385 1383 unsigned wakeup_configured:1; 1386 1384 unsigned suspended:1; 1385 + unsigned susphy_state:1; 1387 1386 1388 1387 u16 imod_interval; 1389 1388
+6 -4
drivers/usb/dwc3/gadget.c
··· 438 438 dwc3_gadget_ep_get_transfer_index(dep); 439 439 } 440 440 441 + if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER && 442 + !(cmd & DWC3_DEPCMD_CMDIOC)) 443 + mdelay(1); 444 + 441 445 if (saved_config) { 442 446 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); 443 447 reg |= saved_config; ··· 1719 1715 WARN_ON_ONCE(ret); 1720 1716 dep->resource_index = 0; 1721 1717 1722 - if (!interrupt) { 1723 - mdelay(1); 1718 + if (!interrupt) 1724 1719 dep->flags &= ~DWC3_EP_TRANSFER_STARTED; 1725 - } else if (!ret) { 1720 + else if (!ret) 1726 1721 dep->flags |= DWC3_EP_END_TRANSFER_PENDING; 1727 - } 1728 1722 1729 1723 dep->flags &= ~DWC3_EP_DELAY_STOP; 1730 1724 return ret;
+3 -3
drivers/usb/gadget/function/f_uac2.c
··· 2061 2061 const char *page, size_t len) \ 2062 2062 { \ 2063 2063 struct f_uac2_opts *opts = to_f_uac2_opts(item); \ 2064 - int ret = 0; \ 2064 + int ret = len; \ 2065 2065 \ 2066 2066 mutex_lock(&opts->lock); \ 2067 2067 if (opts->refcnt) { \ ··· 2072 2072 if (len && page[len - 1] == '\n') \ 2073 2073 len--; \ 2074 2074 \ 2075 - ret = scnprintf(opts->name, min(sizeof(opts->name), len + 1), \ 2076 - "%s", page); \ 2075 + scnprintf(opts->name, min(sizeof(opts->name), len + 1), \ 2076 + "%s", page); \ 2077 2077 \ 2078 2078 end: \ 2079 2079 mutex_unlock(&opts->lock); \
+15 -5
drivers/usb/gadget/udc/dummy_hcd.c
··· 254 254 u32 stream_en_ep; 255 255 u8 num_stream[30 / 2]; 256 256 257 + unsigned timer_pending:1; 257 258 unsigned active:1; 258 259 unsigned old_active:1; 259 260 unsigned resuming:1; ··· 1304 1303 urb->error_count = 1; /* mark as a new urb */ 1305 1304 1306 1305 /* kick the scheduler, it'll do the rest */ 1307 - if (!hrtimer_active(&dum_hcd->timer)) 1306 + if (!dum_hcd->timer_pending) { 1307 + dum_hcd->timer_pending = 1; 1308 1308 hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), 1309 1309 HRTIMER_MODE_REL_SOFT); 1310 + } 1310 1311 1311 1312 done: 1312 1313 spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); ··· 1327 1324 spin_lock_irqsave(&dum_hcd->dum->lock, flags); 1328 1325 1329 1326 rc = usb_hcd_check_unlink_urb(hcd, urb, status); 1330 - if (!rc && dum_hcd->rh_state != DUMMY_RH_RUNNING && 1331 - !list_empty(&dum_hcd->urbp_list)) 1327 + if (rc == 0 && !dum_hcd->timer_pending) { 1328 + dum_hcd->timer_pending = 1; 1332 1329 hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); 1330 + } 1333 1331 1334 1332 spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); 1335 1333 return rc; ··· 1817 1813 1818 1814 /* look at each urb queued by the host side driver */ 1819 1815 spin_lock_irqsave(&dum->lock, flags); 1816 + dum_hcd->timer_pending = 0; 1820 1817 1821 1818 if (!dum_hcd->udev) { 1822 1819 dev_err(dummy_dev(dum_hcd), ··· 1999 1994 if (list_empty(&dum_hcd->urbp_list)) { 2000 1995 usb_put_dev(dum_hcd->udev); 2001 1996 dum_hcd->udev = NULL; 2002 - } else if (dum_hcd->rh_state == DUMMY_RH_RUNNING) { 1997 + } else if (!dum_hcd->timer_pending && 1998 + dum_hcd->rh_state == DUMMY_RH_RUNNING) { 2003 1999 /* want a 1 msec delay here */ 2000 + dum_hcd->timer_pending = 1; 2004 2001 hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), 2005 2002 HRTIMER_MODE_REL_SOFT); 2006 2003 } ··· 2397 2390 } else { 2398 2391 dum_hcd->rh_state = DUMMY_RH_RUNNING; 2399 2392 set_link_state(dum_hcd); 2400 - if (!list_empty(&dum_hcd->urbp_list)) 2393 + if (!list_empty(&dum_hcd->urbp_list)) { 2394 + dum_hcd->timer_pending = 1; 2401 2395 hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); 2396 + } 2402 2397 hcd->state = HC_STATE_RUNNING; 2403 2398 } 2404 2399 spin_unlock_irq(&dum_hcd->dum->lock); ··· 2531 2522 struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); 2532 2523 2533 2524 hrtimer_cancel(&dum_hcd->timer); 2525 + dum_hcd->timer_pending = 0; 2534 2526 device_remove_file(dummy_dev(dum_hcd), &dev_attr_urbs); 2535 2527 dev_info(dummy_dev(dum_hcd), "stopped\n"); 2536 2528 }
+1
drivers/usb/host/xhci-dbgcap.h
··· 110 110 struct tasklet_struct push; 111 111 112 112 struct list_head write_pool; 113 + unsigned int tx_boundary; 113 114 114 115 bool registered; 115 116 };
+50 -5
drivers/usb/host/xhci-dbgtty.c
··· 24 24 return dbc->priv; 25 25 } 26 26 27 + static unsigned int 28 + dbc_kfifo_to_req(struct dbc_port *port, char *packet) 29 + { 30 + unsigned int len; 31 + 32 + len = kfifo_len(&port->port.xmit_fifo); 33 + 34 + if (len == 0) 35 + return 0; 36 + 37 + len = min(len, DBC_MAX_PACKET); 38 + 39 + if (port->tx_boundary) 40 + len = min(port->tx_boundary, len); 41 + 42 + len = kfifo_out(&port->port.xmit_fifo, packet, len); 43 + 44 + if (port->tx_boundary) 45 + port->tx_boundary -= len; 46 + 47 + return len; 48 + } 49 + 27 50 static int dbc_start_tx(struct dbc_port *port) 28 51 __releases(&port->port_lock) 29 52 __acquires(&port->port_lock) ··· 59 36 60 37 while (!list_empty(pool)) { 61 38 req = list_entry(pool->next, struct dbc_request, list_pool); 62 - len = kfifo_out(&port->port.xmit_fifo, req->buf, DBC_MAX_PACKET); 39 + len = dbc_kfifo_to_req(port, req->buf); 63 40 if (len == 0) 64 41 break; 65 42 do_tty_wake = true; ··· 223 200 { 224 201 struct dbc_port *port = tty->driver_data; 225 202 unsigned long flags; 203 + unsigned int written = 0; 226 204 227 205 spin_lock_irqsave(&port->port_lock, flags); 228 - if (count) 229 - count = kfifo_in(&port->port.xmit_fifo, buf, count); 230 - dbc_start_tx(port); 206 + 207 + /* 208 + * Treat tty write as one usb transfer. Make sure the writes are turned 209 + * into TRB request having the same size boundaries as the tty writes. 210 + * Don't add data to kfifo before previous write is turned into TRBs 211 + */ 212 + if (port->tx_boundary) { 213 + spin_unlock_irqrestore(&port->port_lock, flags); 214 + return 0; 215 + } 216 + 217 + if (count) { 218 + written = kfifo_in(&port->port.xmit_fifo, buf, count); 219 + 220 + if (written == count) 221 + port->tx_boundary = kfifo_len(&port->port.xmit_fifo); 222 + 223 + dbc_start_tx(port); 224 + } 225 + 231 226 spin_unlock_irqrestore(&port->port_lock, flags); 232 227 233 - return count; 228 + return written; 234 229 } 235 230 236 231 static int dbc_tty_put_char(struct tty_struct *tty, u8 ch) ··· 282 241 283 242 spin_lock_irqsave(&port->port_lock, flags); 284 243 room = kfifo_avail(&port->port.xmit_fifo); 244 + 245 + if (port->tx_boundary) 246 + room = 0; 247 + 285 248 spin_unlock_irqrestore(&port->port_lock, flags); 286 249 287 250 return room;
+30 -38
drivers/usb/host/xhci-ring.c
··· 1023 1023 td_to_noop(xhci, ring, cached_td, false); 1024 1024 cached_td->cancel_status = TD_CLEARED; 1025 1025 } 1026 - 1026 + td_to_noop(xhci, ring, td, false); 1027 1027 td->cancel_status = TD_CLEARING_CACHE; 1028 1028 cached_td = td; 1029 1029 break; ··· 2775 2775 return 0; 2776 2776 } 2777 2777 2778 + /* 2779 + * xhci 4.10.2 states isoc endpoints should continue 2780 + * processing the next TD if there was an error mid TD. 2781 + * So host like NEC don't generate an event for the last 2782 + * isoc TRB even if the IOC flag is set. 2783 + * xhci 4.9.1 states that if there are errors in mult-TRB 2784 + * TDs xHC should generate an error for that TRB, and if xHC 2785 + * proceeds to the next TD it should genete an event for 2786 + * any TRB with IOC flag on the way. Other host follow this. 2787 + * 2788 + * We wait for the final IOC event, but if we get an event 2789 + * anywhere outside this TD, just give it back already. 2790 + */ 2791 + td = list_first_entry_or_null(&ep_ring->td_list, struct xhci_td, td_list); 2792 + 2793 + if (td && td->error_mid_td && !trb_in_td(xhci, td, ep_trb_dma, false)) { 2794 + xhci_dbg(xhci, "Missing TD completion event after mid TD error\n"); 2795 + ep_ring->dequeue = td->last_trb; 2796 + ep_ring->deq_seg = td->last_trb_seg; 2797 + inc_deq(xhci, ep_ring); 2798 + xhci_td_cleanup(xhci, td, ep_ring, td->status); 2799 + } 2800 + 2778 2801 if (list_empty(&ep_ring->td_list)) { 2779 2802 /* 2780 2803 * Don't print wanings if ring is empty due to a stopped endpoint generating an ··· 2859 2836 return 0; 2860 2837 } 2861 2838 2862 - /* 2863 - * xhci 4.10.2 states isoc endpoints should continue 2864 - * processing the next TD if there was an error mid TD. 2865 - * So host like NEC don't generate an event for the last 2866 - * isoc TRB even if the IOC flag is set. 2867 - * xhci 4.9.1 states that if there are errors in mult-TRB 2868 - * TDs xHC should generate an error for that TRB, and if xHC 2869 - * proceeds to the next TD it should genete an event for 2870 - * any TRB with IOC flag on the way. Other host follow this. 2871 - * So this event might be for the next TD. 2872 - */ 2873 - if (td->error_mid_td && 2874 - !list_is_last(&td->td_list, &ep_ring->td_list)) { 2875 - struct xhci_td *td_next = list_next_entry(td, td_list); 2839 + /* HC is busted, give up! */ 2840 + xhci_err(xhci, 2841 + "ERROR Transfer event TRB DMA ptr not part of current TD ep_index %d comp_code %u\n", 2842 + ep_index, trb_comp_code); 2843 + trb_in_td(xhci, td, ep_trb_dma, true); 2876 2844 2877 - ep_seg = trb_in_td(xhci, td_next, ep_trb_dma, false); 2878 - if (ep_seg) { 2879 - /* give back previous TD, start handling new */ 2880 - xhci_dbg(xhci, "Missing TD completion event after mid TD error\n"); 2881 - ep_ring->dequeue = td->last_trb; 2882 - ep_ring->deq_seg = td->last_trb_seg; 2883 - inc_deq(xhci, ep_ring); 2884 - xhci_td_cleanup(xhci, td, ep_ring, td->status); 2885 - td = td_next; 2886 - } 2887 - } 2888 - 2889 - if (!ep_seg) { 2890 - /* HC is busted, give up! */ 2891 - xhci_err(xhci, 2892 - "ERROR Transfer event TRB DMA ptr not " 2893 - "part of current TD ep_index %d " 2894 - "comp_code %u\n", ep_index, 2895 - trb_comp_code); 2896 - trb_in_td(xhci, td, ep_trb_dma, true); 2897 - 2898 - return -ESHUTDOWN; 2899 - } 2845 + return -ESHUTDOWN; 2900 2846 } 2901 2847 2902 2848 if (ep->skip) {
+1 -1
drivers/usb/host/xhci-tegra.c
··· 2183 2183 goto out; 2184 2184 } 2185 2185 2186 - for (i = 0; i < tegra->num_usb_phys; i++) { 2186 + for (i = 0; i < xhci->usb2_rhub.num_ports; i++) { 2187 2187 if (!xhci->usb2_rhub.ports[i]) 2188 2188 continue; 2189 2189 portsc = readl(xhci->usb2_rhub.ports[i]->addr);
+1 -1
drivers/usb/host/xhci.h
··· 1001 1001 /* Set TR Dequeue Pointer command TRB fields, 6.4.3.9 */ 1002 1002 #define TRB_TO_STREAM_ID(p) ((((p) & (0xffff << 16)) >> 16)) 1003 1003 #define STREAM_ID_FOR_TRB(p) ((((p)) & 0xffff) << 16) 1004 - #define SCT_FOR_TRB(p) (((p) << 1) & 0x7) 1004 + #define SCT_FOR_TRB(p) (((p) & 0x7) << 1) 1005 1005 1006 1006 /* Link TRB specific fields */ 1007 1007 #define TRB_TC (1<<1)
+8
drivers/usb/serial/option.c
··· 279 279 #define QUECTEL_PRODUCT_EG912Y 0x6001 280 280 #define QUECTEL_PRODUCT_EC200S_CN 0x6002 281 281 #define QUECTEL_PRODUCT_EC200A 0x6005 282 + #define QUECTEL_PRODUCT_EG916Q 0x6007 282 283 #define QUECTEL_PRODUCT_EM061K_LWW 0x6008 283 284 #define QUECTEL_PRODUCT_EM061K_LCN 0x6009 284 285 #define QUECTEL_PRODUCT_EC200T 0x6026 ··· 1271 1270 { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, 1272 1271 { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, 1273 1272 { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG912Y, 0xff, 0, 0) }, 1273 + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG916Q, 0xff, 0x00, 0x00) }, 1274 1274 { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) }, 1275 1275 1276 1276 { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, ··· 1382 1380 .driver_info = NCTRL(0) | RSVD(1) }, 1383 1381 { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a0, 0xff), /* Telit FN20C04 (rmnet) */ 1384 1382 .driver_info = RSVD(0) | NCTRL(3) }, 1383 + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a2, 0xff), /* Telit FN920C04 (MBIM) */ 1384 + .driver_info = NCTRL(4) }, 1385 1385 { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a4, 0xff), /* Telit FN20C04 (rmnet) */ 1386 1386 .driver_info = RSVD(0) | NCTRL(3) }, 1387 + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a7, 0xff), /* Telit FN920C04 (MBIM) */ 1388 + .driver_info = NCTRL(4) }, 1387 1389 { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a9, 0xff), /* Telit FN20C04 (rmnet) */ 1388 1390 .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, 1391 + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10aa, 0xff), /* Telit FN920C04 (MBIM) */ 1392 + .driver_info = NCTRL(3) | RSVD(4) | RSVD(5) }, 1389 1393 { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), 1390 1394 .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, 1391 1395 { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
+3
drivers/usb/typec/class.c
··· 519 519 typec_altmode_put_partner(alt); 520 520 521 521 altmode_id_remove(alt->adev.dev.parent, alt->id); 522 + put_device(alt->adev.dev.parent); 522 523 kfree(alt); 523 524 } 524 525 ··· 568 567 alt->adev.dev.groups = alt->groups; 569 568 alt->adev.dev.type = &typec_altmode_dev_type; 570 569 dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id); 570 + 571 + get_device(alt->adev.dev.parent); 571 572 572 573 /* Link partners and plugs with the ports */ 573 574 if (!is_port)
-1
drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.c
··· 432 432 val = TYPEC_CC_RP_DEF; 433 433 break; 434 434 } 435 - val = TYPEC_CC_RP_DEF; 436 435 } 437 436 438 437 if (misc & CC_ORIENTATION)