Merge tag 'usb-6.19-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 and new device ids for 6.19-rc6

  Included in here are:

   - new usb-serial device ids

   - dwc3-apple driver fixes to get things working properly on that
     hardware platform

   - ohci/uhci platfrom driver module soft-deps with ehci to remove a
     runtime warning that sometimes shows up on some platforms.

   - quirk for broken devices that can not handle reading the BOS
     descriptor from them without going crazy.

   - usb-serial driver fixes

   - xhci driver fixes

   - usb gadget driver fixes

  All of these except for the last xhci fix has been in linux-next for a
  while. The xhci fix has been reported by others to solve the issue for
  them, so should be ok"

* tag 'usb-6.19-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  xhci: sideband: don't dereference freed ring when removing sideband endpoint
  usb: gadget: uvc: retry vb2_reqbufs() with vb_vmalloc_memops if use_sg fail
  usb: gadget: uvc: return error from uvcg_queue_init()
  usb: gadget: uvc: fix interval_duration calculation
  usb: gadget: uvc: fix req_payload_size calculation
  usb: dwc3: apple: Ignore USB role switches to the active role
  usb: host: xhci-tegra: Use platform_get_irq_optional() for wake IRQs
  USB: OHCI/UHCI: Add soft dependencies on ehci_platform
  usb: dwc3: apple: Set USB2 PHY mode before dwc3 init
  USB: serial: f81232: fix incomplete serial port generation
  USB: serial: ftdi_sio: add support for PICAXE AXE027 cable
  USB: serial: option: add Telit LE910 MBIM composition
  usb: core: add USB_QUIRK_NO_BOS for devices that hang on BOS descriptor
  dt-bindings: usb: qcom,dwc3: Correct MSM8994 interrupts
  dt-bindings: usb: qcom,dwc3: Correct IPQ5018 interrupts
  tcpm: allow looking for role_sw device in the main node
  usb: dwc3: Check for USB4 IP_NAME
This commit is contained in:
Linus Torvalds
2026-01-18 12:09:13 -08:00
22 changed files with 166 additions and 67 deletions

View File

@@ -406,7 +406,6 @@ allOf:
compatible:
contains:
enum:
- qcom,ipq5018-dwc3
- qcom,ipq6018-dwc3
- qcom,ipq8074-dwc3
- qcom,msm8953-dwc3
@@ -428,6 +427,7 @@ allOf:
compatible:
contains:
enum:
- qcom,msm8994-dwc3
- qcom,msm8996-dwc3
- qcom,qcs404-dwc3
- qcom,sdm660-dwc3
@@ -451,6 +451,7 @@ allOf:
compatible:
contains:
enum:
- qcom,ipq5018-dwc3
- qcom,ipq5332-dwc3
then:
properties:
@@ -488,7 +489,6 @@ allOf:
enum:
- qcom,ipq4019-dwc3
- qcom,ipq8064-dwc3
- qcom,msm8994-dwc3
- qcom,qcs615-dwc3
- qcom,qcs8300-dwc3
- qcom,qdu1000-dwc3

View File

@@ -420,7 +420,6 @@ allOf:
compatible:
contains:
enum:
- qcom,ipq5018-dwc3
- qcom,ipq6018-dwc3
- qcom,ipq8074-dwc3
- qcom,msm8953-dwc3
@@ -443,6 +442,7 @@ allOf:
compatible:
contains:
enum:
- qcom,msm8994-dwc3
- qcom,msm8996-dwc3
- qcom,qcs404-dwc3
- qcom,sdm660-dwc3
@@ -467,6 +467,7 @@ allOf:
compatible:
contains:
enum:
- qcom,ipq5018-dwc3
- qcom,ipq5332-dwc3
then:
properties:
@@ -509,7 +510,6 @@ allOf:
- qcom,ipq4019-dwc3
- qcom,ipq8064-dwc3
- qcom,kaanapali-dwc3
- qcom,msm8994-dwc3
- qcom,qcs615-dwc3
- qcom,qcs8300-dwc3
- qcom,qdu1000-dwc3

View File

@@ -1040,6 +1040,11 @@ int usb_get_bos_descriptor(struct usb_device *dev)
__u8 cap_type;
int ret;
if (dev->quirks & USB_QUIRK_NO_BOS) {
dev_dbg(ddev, "skipping BOS descriptor\n");
return -ENOMSG;
}
bos = kzalloc(sizeof(*bos), GFP_KERNEL);
if (!bos)
return -ENOMEM;

View File

@@ -450,6 +450,9 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x0c45, 0x7056), .driver_info =
USB_QUIRK_IGNORE_REMOTE_WAKEUP },
/* Elgato 4K X - BOS descriptor fetch hangs at SuperSpeed Plus */
{ USB_DEVICE(0x0fd9, 0x009b), .driver_info = USB_QUIRK_NO_BOS },
/* Sony Xperia XZ1 Compact (lilac) smartphone in fastboot mode */
{ USB_DEVICE(0x0fce, 0x0dde), .driver_info = USB_QUIRK_NO_LPM },

View File

@@ -993,6 +993,8 @@ static bool dwc3_core_is_valid(struct dwc3 *dwc)
reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
dwc->ip = DWC3_GSNPS_ID(reg);
if (dwc->ip == DWC4_IP)
dwc->ip = DWC32_IP;
/* This should read as U3 followed by revision number */
if (DWC3_IP_IS(DWC3)) {

View File

@@ -1265,6 +1265,7 @@ struct dwc3 {
#define DWC3_IP 0x5533
#define DWC31_IP 0x3331
#define DWC32_IP 0x3332
#define DWC4_IP 0x3430
u32 revision;

View File

@@ -218,25 +218,31 @@ static int dwc3_apple_core_init(struct dwc3_apple *appledwc)
return ret;
}
static void dwc3_apple_phy_set_mode(struct dwc3_apple *appledwc, enum phy_mode mode)
{
lockdep_assert_held(&appledwc->lock);
/*
* This platform requires SUSPHY to be enabled here already in order to properly configure
* the PHY and switch dwc3's PIPE interface to USB3 PHY.
*/
dwc3_enable_susphy(&appledwc->dwc, true);
phy_set_mode(appledwc->dwc.usb2_generic_phy[0], mode);
phy_set_mode(appledwc->dwc.usb3_generic_phy[0], mode);
}
static int dwc3_apple_init(struct dwc3_apple *appledwc, enum dwc3_apple_state state)
{
int ret, ret_reset;
lockdep_assert_held(&appledwc->lock);
/*
* The USB2 PHY on this platform must be configured for host or device mode while it is
* still powered off and before dwc3 tries to access it. Otherwise, the new configuration
* will sometimes only take affect after the *next* time dwc3 is brought up which causes
* the connected device to just not work.
* The USB3 PHY must be configured later after dwc3 has already been initialized.
*/
switch (state) {
case DWC3_APPLE_HOST:
phy_set_mode(appledwc->dwc.usb2_generic_phy[0], PHY_MODE_USB_HOST);
break;
case DWC3_APPLE_DEVICE:
phy_set_mode(appledwc->dwc.usb2_generic_phy[0], PHY_MODE_USB_DEVICE);
break;
default:
/* Unreachable unless there's a bug in this driver */
return -EINVAL;
}
ret = reset_control_deassert(appledwc->reset);
if (ret) {
dev_err(appledwc->dev, "Failed to deassert reset, err=%d\n", ret);
@@ -257,7 +263,13 @@ static int dwc3_apple_init(struct dwc3_apple *appledwc, enum dwc3_apple_state st
case DWC3_APPLE_HOST:
appledwc->dwc.dr_mode = USB_DR_MODE_HOST;
dwc3_apple_set_ptrcap(appledwc, DWC3_GCTL_PRTCAP_HOST);
dwc3_apple_phy_set_mode(appledwc, PHY_MODE_USB_HOST);
/*
* This platform requires SUSPHY to be enabled here already in order to properly
* configure the PHY and switch dwc3's PIPE interface to USB3 PHY. The USB2 PHY
* has already been configured to the correct mode earlier.
*/
dwc3_enable_susphy(&appledwc->dwc, true);
phy_set_mode(appledwc->dwc.usb3_generic_phy[0], PHY_MODE_USB_HOST);
ret = dwc3_host_init(&appledwc->dwc);
if (ret) {
dev_err(appledwc->dev, "Failed to initialize host, ret=%d\n", ret);
@@ -268,7 +280,13 @@ static int dwc3_apple_init(struct dwc3_apple *appledwc, enum dwc3_apple_state st
case DWC3_APPLE_DEVICE:
appledwc->dwc.dr_mode = USB_DR_MODE_PERIPHERAL;
dwc3_apple_set_ptrcap(appledwc, DWC3_GCTL_PRTCAP_DEVICE);
dwc3_apple_phy_set_mode(appledwc, PHY_MODE_USB_DEVICE);
/*
* This platform requires SUSPHY to be enabled here already in order to properly
* configure the PHY and switch dwc3's PIPE interface to USB3 PHY. The USB2 PHY
* has already been configured to the correct mode earlier.
*/
dwc3_enable_susphy(&appledwc->dwc, true);
phy_set_mode(appledwc->dwc.usb3_generic_phy[0], PHY_MODE_USB_DEVICE);
ret = dwc3_gadget_init(&appledwc->dwc);
if (ret) {
dev_err(appledwc->dev, "Failed to initialize gadget, ret=%d\n", ret);
@@ -339,6 +357,22 @@ static int dwc3_usb_role_switch_set(struct usb_role_switch *sw, enum usb_role ro
guard(mutex)(&appledwc->lock);
/*
* Skip role switches if appledwc is already in the desired state. The
* USB-C port controller on M2 and M1/M2 Pro/Max/Ultra devices issues
* additional interrupts which results in usb_role_switch_set_role()
* calls with the current role.
* Ignore those calls here to ensure the USB-C port controller and
* appledwc are in a consistent state.
* This matches the behaviour in __dwc3_set_mode().
* Do no handle USB_ROLE_NONE for DWC3_APPLE_NO_CABLE and
* DWC3_APPLE_PROBE_PENDING since that is no-op anyway.
*/
if (appledwc->state == DWC3_APPLE_HOST && role == USB_ROLE_HOST)
return 0;
if (appledwc->state == DWC3_APPLE_DEVICE && role == USB_ROLE_DEVICE)
return 0;
/*
* We need to tear all of dwc3 down and re-initialize it every time a cable is
* connected or disconnected or when the mode changes. See the documentation for enum

View File

@@ -362,6 +362,10 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
return ret;
usb_ep_enable(uvc->video.ep);
uvc->video.max_req_size = uvc->video.ep->maxpacket
* max_t(unsigned int, uvc->video.ep->maxburst, 1)
* (uvc->video.ep->mult);
memset(&v4l2_event, 0, sizeof(v4l2_event));
v4l2_event.type = UVC_EVENT_STREAMON;
v4l2_event_queue(&uvc->vdev, &v4l2_event);

View File

@@ -107,7 +107,7 @@ struct uvc_video {
unsigned int width;
unsigned int height;
unsigned int imagesize;
unsigned int interval;
unsigned int interval; /* in 100ns units */
struct mutex mutex; /* protects frame parameters */
unsigned int uvc_num_requests;
@@ -117,6 +117,7 @@ struct uvc_video {
/* Requests */
bool is_enabled; /* tracks whether video stream is enabled */
unsigned int req_size;
unsigned int max_req_size;
struct list_head ureqs; /* all uvc_requests allocated by uvc_video */
/* USB requests that the video pump thread can encode into */

View File

@@ -86,10 +86,17 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb)
buf->bytesused = 0;
} else {
buf->bytesused = vb2_get_plane_payload(vb, 0);
buf->req_payload_size =
DIV_ROUND_UP(buf->bytesused +
(video->reqs_per_frame * UVCG_REQUEST_HEADER_LEN),
video->reqs_per_frame);
if (video->reqs_per_frame != 0) {
buf->req_payload_size =
DIV_ROUND_UP(buf->bytesused +
(video->reqs_per_frame * UVCG_REQUEST_HEADER_LEN),
video->reqs_per_frame);
if (buf->req_payload_size > video->req_size)
buf->req_payload_size = video->req_size;
} else {
buf->req_payload_size = video->max_req_size;
}
}
return 0;
@@ -175,7 +182,15 @@ int uvcg_alloc_buffers(struct uvc_video_queue *queue,
{
int ret;
retry:
ret = vb2_reqbufs(&queue->queue, rb);
if (ret < 0 && queue->use_sg) {
uvc_trace(UVC_TRACE_IOCTL,
"failed to alloc buffer with sg enabled, try non-sg mode\n");
queue->use_sg = 0;
queue->queue.mem_ops = &vb2_vmalloc_memops;
goto retry;
}
return ret ? ret : rb->count;
}

View File

@@ -499,13 +499,11 @@ uvc_video_prep_requests(struct uvc_video *video)
{
struct uvc_device *uvc = container_of(video, struct uvc_device, video);
struct usb_composite_dev *cdev = uvc->func.config->cdev;
unsigned int interval_duration = video->ep->desc->bInterval * 1250;
unsigned int interval_duration;
unsigned int max_req_size, req_size, header_size;
unsigned int nreq;
max_req_size = video->ep->maxpacket
* max_t(unsigned int, video->ep->maxburst, 1)
* (video->ep->mult);
max_req_size = video->max_req_size;
if (!usb_endpoint_xfer_isoc(video->ep->desc)) {
video->req_size = max_req_size;
@@ -515,8 +513,11 @@ uvc_video_prep_requests(struct uvc_video *video)
return;
}
interval_duration = 2 << (video->ep->desc->bInterval - 1);
if (cdev->gadget->speed < USB_SPEED_HIGH)
interval_duration = video->ep->desc->bInterval * 10000;
interval_duration *= 10000;
else
interval_duration *= 1250;
nreq = DIV_ROUND_UP(video->interval, interval_duration);
@@ -837,7 +838,6 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc)
video->interval = 666666;
/* Initialize the video buffers queue. */
uvcg_queue_init(&video->queue, uvc->v4l2_dev.dev->parent,
return uvcg_queue_init(&video->queue, uvc->v4l2_dev.dev->parent,
V4L2_BUF_TYPE_VIDEO_OUTPUT, &video->mutex);
return 0;
}

View File

@@ -392,3 +392,4 @@ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_AUTHOR("Hauke Mehrtens");
MODULE_AUTHOR("Alan Stern");
MODULE_LICENSE("GPL");
MODULE_SOFTDEP("pre: ehci_platform");

View File

@@ -211,3 +211,4 @@ static struct platform_driver uhci_platform_driver = {
.of_match_table = platform_uhci_ids,
},
};
MODULE_SOFTDEP("pre: ehci_platform");

View File

@@ -210,7 +210,6 @@ xhci_sideband_remove_endpoint(struct xhci_sideband *sb,
return -ENODEV;
__xhci_sideband_remove_endpoint(sb, ep);
xhci_initialize_ring_info(ep->ring);
return 0;
}

View File

@@ -1563,7 +1563,7 @@ static int tegra_xusb_setup_wakeup(struct platform_device *pdev, struct tegra_xu
for (i = 0; i < tegra->soc->max_num_wakes; i++) {
struct irq_data *data;
tegra->wake_irqs[i] = platform_get_irq(pdev, i + WAKE_IRQ_START_INDEX);
tegra->wake_irqs[i] = platform_get_irq_optional(pdev, i + WAKE_IRQ_START_INDEX);
if (tegra->wake_irqs[i] < 0)
break;

View File

@@ -2898,16 +2898,25 @@ int xhci_stop_endpoint_sync(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, int
gfp_t gfp_flags)
{
struct xhci_command *command;
struct xhci_ep_ctx *ep_ctx;
unsigned long flags;
int ret;
int ret = -ENODEV;
command = xhci_alloc_command(xhci, true, gfp_flags);
if (!command)
return -ENOMEM;
spin_lock_irqsave(&xhci->lock, flags);
ret = xhci_queue_stop_endpoint(xhci, command, ep->vdev->slot_id,
ep->ep_index, suspend);
/* make sure endpoint exists and is running before stopping it */
if (ep->ring) {
ep_ctx = xhci_get_ep_ctx(xhci, ep->vdev->out_ctx, ep->ep_index);
if (GET_EP_CTX_STATE(ep_ctx) == EP_STATE_RUNNING)
ret = xhci_queue_stop_endpoint(xhci, command,
ep->vdev->slot_id,
ep->ep_index, suspend);
}
if (ret < 0) {
spin_unlock_irqrestore(&xhci->lock, flags);
goto out;

View File

@@ -70,7 +70,6 @@ MODULE_DEVICE_TABLE(usb, combined_id_table);
#define F81232_REGISTER_REQUEST 0xa0
#define F81232_GET_REGISTER 0xc0
#define F81232_SET_REGISTER 0x40
#define F81534A_ACCESS_REG_RETRY 2
#define SERIAL_BASE_ADDRESS 0x0120
#define RECEIVE_BUFFER_REGISTER (0x00 + SERIAL_BASE_ADDRESS)
@@ -824,36 +823,31 @@ static void f81232_lsr_worker(struct work_struct *work)
static int f81534a_ctrl_set_register(struct usb_interface *intf, u16 reg,
u16 size, void *val)
{
struct usb_device *dev = interface_to_usbdev(intf);
int retry = F81534A_ACCESS_REG_RETRY;
int status;
return usb_control_msg_send(interface_to_usbdev(intf),
0,
F81232_REGISTER_REQUEST,
F81232_SET_REGISTER,
reg,
0,
val,
size,
USB_CTRL_SET_TIMEOUT,
GFP_KERNEL);
}
while (retry--) {
status = usb_control_msg_send(dev,
0,
F81232_REGISTER_REQUEST,
F81232_SET_REGISTER,
reg,
0,
val,
size,
USB_CTRL_SET_TIMEOUT,
GFP_KERNEL);
if (status) {
status = usb_translate_errors(status);
if (status == -EIO)
continue;
}
break;
}
if (status) {
dev_err(&intf->dev, "failed to set register 0x%x: %d\n",
reg, status);
}
return status;
static int f81534a_ctrl_get_register(struct usb_interface *intf, u16 reg,
u16 size, void *val)
{
return usb_control_msg_recv(interface_to_usbdev(intf),
0,
F81232_REGISTER_REQUEST,
F81232_GET_REGISTER,
reg,
0,
val,
size,
USB_CTRL_GET_TIMEOUT,
GFP_KERNEL);
}
static int f81534a_ctrl_enable_all_ports(struct usb_interface *intf, bool en)
@@ -869,6 +863,29 @@ static int f81534a_ctrl_enable_all_ports(struct usb_interface *intf, bool en)
* bit 0~11 : Serial port enable bit.
*/
if (en) {
/*
* The Fintek F81532A/534A/535/536 family relies on the
* F81534A_CTRL_CMD_ENABLE_PORT (116h) register during
* initialization to both determine serial port status and
* control port creation.
*
* If the driver experiences fast load/unload cycles, the
* device state may becomes unstable, resulting in the
* incomplete generation of serial ports.
*
* Performing a dummy read operation on the register prior
* to the initial write command resolves the issue.
*
* This clears the device's stale internal state. Subsequent
* write operations will correctly generate all serial ports.
*/
status = f81534a_ctrl_get_register(intf,
F81534A_CTRL_CMD_ENABLE_PORT,
sizeof(enable),
enable);
if (status)
return status;
enable[0] = 0xff;
enable[1] = 0x8f;
}

View File

@@ -848,6 +848,7 @@ static const struct usb_device_id id_table_combined[] = {
{ USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, LMI_LM3S_DEVEL_BOARD_PID, 1) },
{ USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID, 1) },
{ USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, LMI_LM3S_ICDI_BOARD_PID, 1) },
{ USB_DEVICE(FTDI_VID, FTDI_AXE027_PID) },
{ USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, FTDI_TURTELIZER_PID, 1) },
{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_SCU18) },

View File

@@ -96,6 +96,8 @@
#define LMI_LM3S_EVAL_BOARD_PID 0xbcd9
#define LMI_LM3S_ICDI_BOARD_PID 0xbcda
#define FTDI_AXE027_PID 0xBD90 /* PICAXE AXE027 USB download cable */
#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmbH */
/* OpenDCC (www.opendcc.de) product id */

View File

@@ -1505,6 +1505,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1231, 0xff), /* Telit LE910Cx (RNDIS) */
.driver_info = NCTRL(2) | RSVD(3) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x1250, 0xff, 0x00, 0x00) }, /* Telit LE910Cx (rmnet) */
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1252, 0xff) }, /* Telit LE910Cx (MBIM) */
{ USB_DEVICE(TELIT_VENDOR_ID, 0x1260),
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
{ USB_DEVICE(TELIT_VENDOR_ID, 0x1261),

View File

@@ -7890,7 +7890,7 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
port->partner_desc.identity = &port->partner_ident;
port->role_sw = fwnode_usb_role_switch_get(tcpc->fwnode);
if (!port->role_sw)
if (IS_ERR_OR_NULL(port->role_sw))
port->role_sw = usb_role_switch_get(port->dev);
if (IS_ERR(port->role_sw)) {
err = PTR_ERR(port->role_sw);

View File

@@ -75,4 +75,7 @@
/* short SET_ADDRESS request timeout */
#define USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT BIT(16)
/* skip BOS descriptor request */
#define USB_QUIRK_NO_BOS BIT(17)
#endif /* __LINUX_USB_QUIRKS_H */