USB fixes for 6.11-rc6

Here are some small USB fixes for 6.11-rc6.  Included in here are:
   - dwc3 driver fixes for reported issues
   - MAINTAINER file update, marking a driver as unsupported :(
   - cdnsp driver fixes
   - USB gadget driver fix
   - USB sysfs fix
   - other tiny fixes
   - new device ids for usb serial driver
 
 All of these have been in linux-next this week with no reported issues.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCZtNVTw8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ymqWwCgmITg5Owdigw+ejnkLJ4Q/CHYfRkAoLh7nkcm
 kaX7IqZLgVDr4rvgVcmR
 =azoE
 -----END PGP SIGNATURE-----

Merge tag 'usb-6.11-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.11-rc6.  Included in here are:

   - dwc3 driver fixes for reported issues

   - MAINTAINER file update, marking a driver as unsupported :(

   - cdnsp driver fixes

   - USB gadget driver fix

   - USB sysfs fix

   - other tiny fixes

   - new device ids for usb serial driver

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

* tag 'usb-6.11-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  USB: serial: option: add MeiG Smart SRM825L
  usb: cdnsp: fix for Link TRB with TC
  usb: dwc3: st: add missing depopulate in probe error path
  usb: dwc3: st: fix probed platform device ref count on probe error path
  usb: dwc3: ep0: Don't reset resource alloc flag (including ep0)
  usb: core: sysfs: Unmerge @usb3_hardware_lpm_attr_group in remove_power_attributes()
  usb: typec: fsa4480: Relax CHIP_ID check
  usb: dwc3: xilinx: add missing depopulate in probe error path
  usb: dwc3: omap: add missing depopulate in probe error path
  dt-bindings: usb: microchip,usb2514: Fix reference USB device schema
  usb: gadget: uvc: queue pump work in uvcg_video_enable()
  cdc-acm: Add DISABLE_ECHO quirk for GE HealthCare UI Controller
  usb: cdnsp: fix incorrect index in cdnsp_get_hw_deq function
  usb: dwc3: core: Prevent USB core invalid event buffer address access
  MAINTAINERS: Mark UVC gadget driver as orphan
This commit is contained in:
Linus Torvalds 2024-09-01 07:06:28 +12:00
commit e8784b0aef
14 changed files with 78 additions and 18 deletions

View File

@ -10,7 +10,7 @@ maintainers:
- Fabio Estevam <festevam@gmail.com> - Fabio Estevam <festevam@gmail.com>
allOf: allOf:
- $ref: usb-hcd.yaml# - $ref: usb-device.yaml#
properties: properties:
compatible: compatible:
@ -36,6 +36,13 @@ required:
- compatible - compatible
- reg - reg
patternProperties:
"^.*@[0-9a-f]{1,2}$":
description: The hard wired USB devices
type: object
$ref: /schemas/usb/usb-device.yaml
additionalProperties: true
unevaluatedProperties: false unevaluatedProperties: false
examples: examples:

View File

@ -23848,10 +23848,8 @@ F: drivers/media/usb/uvc/
F: include/uapi/linux/uvcvideo.h F: include/uapi/linux/uvcvideo.h
USB WEBCAM GADGET USB WEBCAM GADGET
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
M: Daniel Scally <dan.scally@ideasonboard.com>
L: linux-usb@vger.kernel.org L: linux-usb@vger.kernel.org
S: Maintained S: Orphan
F: drivers/usb/gadget/function/*uvc* F: drivers/usb/gadget/function/*uvc*
F: drivers/usb/gadget/legacy/webcam.c F: drivers/usb/gadget/legacy/webcam.c
F: include/uapi/linux/usb/g_uvc.h F: include/uapi/linux/usb/g_uvc.h

View File

@ -811,6 +811,7 @@ struct cdnsp_stream_info {
* generate Missed Service Error Event. * generate Missed Service Error Event.
* Set skip flag when receive a Missed Service Error Event and * Set skip flag when receive a Missed Service Error Event and
* process the missed tds on the endpoint ring. * process the missed tds on the endpoint ring.
* @wa1_nop_trb: hold pointer to NOP trb.
*/ */
struct cdnsp_ep { struct cdnsp_ep {
struct usb_ep endpoint; struct usb_ep endpoint;
@ -838,6 +839,8 @@ struct cdnsp_ep {
#define EP_UNCONFIGURED BIT(7) #define EP_UNCONFIGURED BIT(7)
bool skip; bool skip;
union cdnsp_trb *wa1_nop_trb;
}; };
/** /**

View File

@ -402,7 +402,7 @@ static u64 cdnsp_get_hw_deq(struct cdnsp_device *pdev,
struct cdnsp_stream_ctx *st_ctx; struct cdnsp_stream_ctx *st_ctx;
struct cdnsp_ep *pep; struct cdnsp_ep *pep;
pep = &pdev->eps[stream_id]; pep = &pdev->eps[ep_index];
if (pep->ep_state & EP_HAS_STREAMS) { if (pep->ep_state & EP_HAS_STREAMS) {
st_ctx = &pep->stream_info.stream_ctx_array[stream_id]; st_ctx = &pep->stream_info.stream_ctx_array[stream_id];
@ -1904,6 +1904,23 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
if (ret) if (ret)
return ret; return ret;
/*
* workaround 1: STOP EP command on LINK TRB with TC bit set to 1
* causes that internal cycle bit can have incorrect state after
* command complete. In consequence empty transfer ring can be
* incorrectly detected when EP is resumed.
* NOP TRB before LINK TRB avoid such scenario. STOP EP command is
* then on NOP TRB and internal cycle bit is not changed and have
* correct value.
*/
if (pep->wa1_nop_trb) {
field = le32_to_cpu(pep->wa1_nop_trb->trans_event.flags);
field ^= TRB_CYCLE;
pep->wa1_nop_trb->trans_event.flags = cpu_to_le32(field);
pep->wa1_nop_trb = NULL;
}
/* /*
* Don't give the first TRB to the hardware (by toggling the cycle bit) * Don't give the first TRB to the hardware (by toggling the cycle bit)
* until we've finished creating all the other TRBs. The ring's cycle * until we've finished creating all the other TRBs. The ring's cycle
@ -1999,6 +2016,17 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
send_addr = addr; send_addr = addr;
} }
if (cdnsp_trb_is_link(ring->enqueue + 1)) {
field = TRB_TYPE(TRB_TR_NOOP) | TRB_IOC;
if (!ring->cycle_state)
field |= TRB_CYCLE;
pep->wa1_nop_trb = ring->enqueue;
cdnsp_queue_trb(pdev, ring, 0, 0x0, 0x0,
TRB_INTR_TARGET(0), field);
}
cdnsp_check_trb_math(preq, enqd_len); cdnsp_check_trb_math(preq, enqd_len);
ret = cdnsp_giveback_first_trb(pdev, pep, preq->request.stream_id, ret = cdnsp_giveback_first_trb(pdev, pep, preq->request.stream_id,
start_cycle, start_trb); start_cycle, start_trb);

View File

@ -1761,6 +1761,9 @@ static const struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x11ca, 0x0201), /* VeriFone Mx870 Gadget Serial */ { USB_DEVICE(0x11ca, 0x0201), /* VeriFone Mx870 Gadget Serial */
.driver_info = SINGLE_RX_URB, .driver_info = SINGLE_RX_URB,
}, },
{ USB_DEVICE(0x1901, 0x0006), /* GE Healthcare Patient Monitor UI Controller */
.driver_info = DISABLE_ECHO, /* DISABLE ECHO in termios flag */
},
{ USB_DEVICE(0x1965, 0x0018), /* Uniden UBC125XLT */ { USB_DEVICE(0x1965, 0x0018), /* Uniden UBC125XLT */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
}, },

View File

@ -670,6 +670,7 @@ static int add_power_attributes(struct device *dev)
static void remove_power_attributes(struct device *dev) static void remove_power_attributes(struct device *dev)
{ {
sysfs_unmerge_group(&dev->kobj, &usb3_hardware_lpm_attr_group);
sysfs_unmerge_group(&dev->kobj, &usb2_hardware_lpm_attr_group); sysfs_unmerge_group(&dev->kobj, &usb2_hardware_lpm_attr_group);
sysfs_unmerge_group(&dev->kobj, &power_attr_group); sysfs_unmerge_group(&dev->kobj, &power_attr_group);
} }

View File

@ -564,9 +564,17 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc)
void dwc3_event_buffers_cleanup(struct dwc3 *dwc) void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
{ {
struct dwc3_event_buffer *evt; struct dwc3_event_buffer *evt;
u32 reg;
if (!dwc->ev_buf) if (!dwc->ev_buf)
return; return;
/*
* Exynos platforms may not be able to access event buffer if the
* controller failed to halt on dwc3_core_exit().
*/
reg = dwc3_readl(dwc->regs, DWC3_DSTS);
if (!(reg & DWC3_DSTS_DEVCTRLHLT))
return;
evt = dwc->ev_buf; evt = dwc->ev_buf;

View File

@ -522,11 +522,13 @@ static int dwc3_omap_probe(struct platform_device *pdev)
if (ret) { if (ret) {
dev_err(dev, "failed to request IRQ #%d --> %d\n", dev_err(dev, "failed to request IRQ #%d --> %d\n",
omap->irq, ret); omap->irq, ret);
goto err1; goto err2;
} }
dwc3_omap_enable_irqs(omap); dwc3_omap_enable_irqs(omap);
return 0; return 0;
err2:
of_platform_depopulate(dev);
err1: err1:
pm_runtime_put_sync(dev); pm_runtime_put_sync(dev);
pm_runtime_disable(dev); pm_runtime_disable(dev);

View File

@ -219,10 +219,8 @@ static int st_dwc3_probe(struct platform_device *pdev)
dwc3_data->regmap = regmap; dwc3_data->regmap = regmap;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "syscfg-reg"); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "syscfg-reg");
if (!res) { if (!res)
ret = -ENXIO; return -ENXIO;
goto undo_platform_dev_alloc;
}
dwc3_data->syscfg_reg_off = res->start; dwc3_data->syscfg_reg_off = res->start;
@ -233,8 +231,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
devm_reset_control_get_exclusive(dev, "powerdown"); devm_reset_control_get_exclusive(dev, "powerdown");
if (IS_ERR(dwc3_data->rstc_pwrdn)) { if (IS_ERR(dwc3_data->rstc_pwrdn)) {
dev_err(&pdev->dev, "could not get power controller\n"); dev_err(&pdev->dev, "could not get power controller\n");
ret = PTR_ERR(dwc3_data->rstc_pwrdn); return PTR_ERR(dwc3_data->rstc_pwrdn);
goto undo_platform_dev_alloc;
} }
/* Manage PowerDown */ /* Manage PowerDown */
@ -269,7 +266,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
if (!child_pdev) { if (!child_pdev) {
dev_err(dev, "failed to find dwc3 core device\n"); dev_err(dev, "failed to find dwc3 core device\n");
ret = -ENODEV; ret = -ENODEV;
goto err_node_put; goto depopulate;
} }
dwc3_data->dr_mode = usb_get_dr_mode(&child_pdev->dev); dwc3_data->dr_mode = usb_get_dr_mode(&child_pdev->dev);
@ -285,6 +282,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
ret = st_dwc3_drd_init(dwc3_data); ret = st_dwc3_drd_init(dwc3_data);
if (ret) { if (ret) {
dev_err(dev, "drd initialisation failed\n"); dev_err(dev, "drd initialisation failed\n");
of_platform_depopulate(dev);
goto undo_softreset; goto undo_softreset;
} }
@ -294,14 +292,14 @@ static int st_dwc3_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, dwc3_data); platform_set_drvdata(pdev, dwc3_data);
return 0; return 0;
depopulate:
of_platform_depopulate(dev);
err_node_put: err_node_put:
of_node_put(child); of_node_put(child);
undo_softreset: undo_softreset:
reset_control_assert(dwc3_data->rstc_rst); reset_control_assert(dwc3_data->rstc_rst);
undo_powerdown: undo_powerdown:
reset_control_assert(dwc3_data->rstc_pwrdn); reset_control_assert(dwc3_data->rstc_pwrdn);
undo_platform_dev_alloc:
platform_device_put(pdev);
return ret; return ret;
} }

View File

@ -327,9 +327,14 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
goto err_pm_set_suspended; goto err_pm_set_suspended;
pm_suspend_ignore_children(dev, false); pm_suspend_ignore_children(dev, false);
return pm_runtime_resume_and_get(dev); ret = pm_runtime_resume_and_get(dev);
if (ret < 0)
goto err_pm_set_suspended;
return 0;
err_pm_set_suspended: err_pm_set_suspended:
of_platform_depopulate(dev);
pm_runtime_set_suspended(dev); pm_runtime_set_suspended(dev);
err_clk_put: err_clk_put:

View File

@ -232,7 +232,8 @@ void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
/* stall is always issued on EP0 */ /* stall is always issued on EP0 */
dep = dwc->eps[0]; dep = dwc->eps[0];
__dwc3_gadget_ep_set_halt(dep, 1, false); __dwc3_gadget_ep_set_halt(dep, 1, false);
dep->flags = DWC3_EP_ENABLED; dep->flags &= DWC3_EP_RESOURCE_ALLOCATED;
dep->flags |= DWC3_EP_ENABLED;
dwc->delayed_status = false; dwc->delayed_status = false;
if (!list_empty(&dep->pending_list)) { if (!list_empty(&dep->pending_list)) {

View File

@ -753,6 +753,7 @@ int uvcg_video_enable(struct uvc_video *video)
video->req_int_count = 0; video->req_int_count = 0;
uvc_video_ep_queue_initial_requests(video); uvc_video_ep_queue_initial_requests(video);
queue_work(video->async_wq, &video->pump);
return ret; return ret;
} }

View File

@ -619,6 +619,8 @@ static void option_instat_callback(struct urb *urb);
/* MeiG Smart Technology products */ /* MeiG Smart Technology products */
#define MEIGSMART_VENDOR_ID 0x2dee #define MEIGSMART_VENDOR_ID 0x2dee
/* MeiG Smart SRM825L based on Qualcomm 315 */
#define MEIGSMART_PRODUCT_SRM825L 0x4d22
/* MeiG Smart SLM320 based on UNISOC UIS8910 */ /* MeiG Smart SLM320 based on UNISOC UIS8910 */
#define MEIGSMART_PRODUCT_SLM320 0x4d41 #define MEIGSMART_PRODUCT_SLM320 0x4d41
@ -2366,6 +2368,9 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
MODULE_DEVICE_TABLE(usb, option_ids); MODULE_DEVICE_TABLE(usb, option_ids);

View File

@ -274,7 +274,7 @@ static int fsa4480_probe(struct i2c_client *client)
return dev_err_probe(dev, PTR_ERR(fsa->regmap), "failed to initialize regmap\n"); return dev_err_probe(dev, PTR_ERR(fsa->regmap), "failed to initialize regmap\n");
ret = regmap_read(fsa->regmap, FSA4480_DEVICE_ID, &val); ret = regmap_read(fsa->regmap, FSA4480_DEVICE_ID, &val);
if (ret || !val) if (ret)
return dev_err_probe(dev, -ENODEV, "FSA4480 not found\n"); return dev_err_probe(dev, -ENODEV, "FSA4480 not found\n");
dev_dbg(dev, "Found FSA4480 v%lu.%lu (Vendor ID = %lu)\n", dev_dbg(dev, "Found FSA4480 v%lu.%lu (Vendor ID = %lu)\n",