Skip to content

Commit

Permalink
Merge tag 'usb-6.13-rc7' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are some small USB driver fixes and new device ids for 6.13-rc7.
  Included in here are:

   - usb serial new device ids

   - typec bugfixes for reported issues

   - dwc3 driver fixes

   - chipidea driver fixes

   - gadget driver fixes

   - other minor fixes for reported problems.

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

* tag 'usb-6.13-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  USB: serial: option: add Neoway N723-EA support
  USB: serial: option: add MeiG Smart SRM815
  USB: serial: cp210x: add Phoenix Contact UPS Device
  usb: typec: fix pm usage counter imbalance in ucsi_ccg_sync_control()
  usb-storage: Add max sectors quirk for Nokia 208
  usb: gadget: midi2: Reverse-select at the right place
  usb: gadget: f_fs: Remove WARN_ON in functionfs_bind
  USB: core: Disable LPM only for non-suspended ports
  usb: fix reference leak in usb_new_device()
  usb: typec: tcpci: fix NULL pointer issue on shared irq case
  usb: gadget: u_serial: Disable ep before setting port to null to fix the crash caused by port being null
  usb: chipidea: ci_hdrc_imx: decrement device's refcount in .remove() and in the error path of .probe()
  usb: typec: ucsi: Set orientation as none when connector is unplugged
  usb: gadget: configfs: Ignore trailing LF for user strings to cdev
  USB: usblp: return error when setting unsupported protocol
  usb: gadget: f_uac2: Fix incorrect setting of bNumEndpoints
  usb: typec: tcpm/tcpci_maxim: fix error code in max_contaminant_read_resistance_kohm()
  usb: host: xhci-plat: set skip_phy_initialization if software node has XHCI_SKIP_PHY_INIT property
  usb: dwc3-am62: Disable autosuspend during remove
  usb: dwc3: gadget: fix writing NYET threshold
  • Loading branch information
Linus Torvalds committed Jan 12, 2025
2 parents be54864 + f3149ed commit 196856d
Show file tree
Hide file tree
Showing 20 changed files with 84 additions and 41 deletions.
25 changes: 17 additions & 8 deletions drivers/usb/chipidea/ci_hdrc_imx.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,25 +370,29 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
data->pinctrl = devm_pinctrl_get(dev);
if (PTR_ERR(data->pinctrl) == -ENODEV)
data->pinctrl = NULL;
else if (IS_ERR(data->pinctrl))
return dev_err_probe(dev, PTR_ERR(data->pinctrl),
else if (IS_ERR(data->pinctrl)) {
ret = dev_err_probe(dev, PTR_ERR(data->pinctrl),
"pinctrl get failed\n");
goto err_put;
}

data->hsic_pad_regulator =
devm_regulator_get_optional(dev, "hsic");
if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) {
/* no pad regulator is needed */
data->hsic_pad_regulator = NULL;
} else if (IS_ERR(data->hsic_pad_regulator))
return dev_err_probe(dev, PTR_ERR(data->hsic_pad_regulator),
} else if (IS_ERR(data->hsic_pad_regulator)) {
ret = dev_err_probe(dev, PTR_ERR(data->hsic_pad_regulator),
"Get HSIC pad regulator error\n");
goto err_put;
}

if (data->hsic_pad_regulator) {
ret = regulator_enable(data->hsic_pad_regulator);
if (ret) {
dev_err(dev,
"Failed to enable HSIC pad regulator\n");
return ret;
goto err_put;
}
}
}
Expand All @@ -402,13 +406,14 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
dev_err(dev,
"pinctrl_hsic_idle lookup failed, err=%ld\n",
PTR_ERR(pinctrl_hsic_idle));
return PTR_ERR(pinctrl_hsic_idle);
ret = PTR_ERR(pinctrl_hsic_idle);
goto err_put;
}

ret = pinctrl_select_state(data->pinctrl, pinctrl_hsic_idle);
if (ret) {
dev_err(dev, "hsic_idle select failed, err=%d\n", ret);
return ret;
goto err_put;
}

data->pinctrl_hsic_active = pinctrl_lookup_state(data->pinctrl,
Expand All @@ -417,7 +422,8 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
dev_err(dev,
"pinctrl_hsic_active lookup failed, err=%ld\n",
PTR_ERR(data->pinctrl_hsic_active));
return PTR_ERR(data->pinctrl_hsic_active);
ret = PTR_ERR(data->pinctrl_hsic_active);
goto err_put;
}
}

Expand Down Expand Up @@ -527,6 +533,8 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
if (pdata.flags & CI_HDRC_PMQOS)
cpu_latency_qos_remove_request(&data->pm_qos_req);
data->ci_pdev = NULL;
err_put:
put_device(data->usbmisc_data->dev);
return ret;
}

Expand All @@ -551,6 +559,7 @@ static void ci_hdrc_imx_remove(struct platform_device *pdev)
if (data->hsic_pad_regulator)
regulator_disable(data->hsic_pad_regulator);
}
put_device(data->usbmisc_data->dev);
}

static void ci_hdrc_imx_shutdown(struct platform_device *pdev)
Expand Down
7 changes: 4 additions & 3 deletions drivers/usb/class/usblp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1337,11 +1337,12 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
if (protocol < USBLP_FIRST_PROTOCOL || protocol > USBLP_LAST_PROTOCOL)
return -EINVAL;

alts = usblp->protocol[protocol].alt_setting;
if (alts < 0)
return -EINVAL;

/* Don't unnecessarily set the interface if there's a single alt. */
if (usblp->intf->num_altsetting > 1) {
alts = usblp->protocol[protocol].alt_setting;
if (alts < 0)
return -EINVAL;
r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
if (r < 0) {
printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n",
Expand Down
6 changes: 4 additions & 2 deletions drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -2663,13 +2663,13 @@ int usb_new_device(struct usb_device *udev)
err = sysfs_create_link(&udev->dev.kobj,
&port_dev->dev.kobj, "port");
if (err)
goto fail;
goto out_del_dev;

err = sysfs_create_link(&port_dev->dev.kobj,
&udev->dev.kobj, "device");
if (err) {
sysfs_remove_link(&udev->dev.kobj, "port");
goto fail;
goto out_del_dev;
}

if (!test_and_set_bit(port1, hub->child_usage_bits))
Expand All @@ -2683,6 +2683,8 @@ int usb_new_device(struct usb_device *udev)
pm_runtime_put_sync_autosuspend(&udev->dev);
return err;

out_del_dev:
device_del(&udev->dev);
fail:
usb_set_device_state(udev, USB_STATE_NOTATTACHED);
pm_runtime_disable(&udev->dev);
Expand Down
7 changes: 4 additions & 3 deletions drivers/usb/core/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,10 +453,11 @@ static int usb_port_runtime_suspend(struct device *dev)
static void usb_port_shutdown(struct device *dev)
{
struct usb_port *port_dev = to_usb_port(dev);
struct usb_device *udev = port_dev->child;

if (port_dev->child) {
usb_disable_usb2_hardware_lpm(port_dev->child);
usb_unlocked_disable_lpm(port_dev->child);
if (udev && !udev->port_is_suspended) {
usb_disable_usb2_hardware_lpm(udev);
usb_unlocked_disable_lpm(udev);
}
}

Expand Down
1 change: 1 addition & 0 deletions drivers/usb/dwc3/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@
#define DWC3_DCTL_TRGTULST_SS_INACT (DWC3_DCTL_TRGTULST(6))

/* These apply for core versions 1.94a and later */
#define DWC3_DCTL_NYET_THRES_MASK (0xf << 20)
#define DWC3_DCTL_NYET_THRES(n) (((n) & 0xf) << 20)

#define DWC3_DCTL_KEEP_CONNECT BIT(19)
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/dwc3/dwc3-am62.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ static void dwc3_ti_remove(struct platform_device *pdev)

pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
pm_runtime_dont_use_autosuspend(dev);
pm_runtime_set_suspended(dev);
}

Expand Down
4 changes: 3 additions & 1 deletion drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -4195,8 +4195,10 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
WARN_ONCE(DWC3_VER_IS_PRIOR(DWC3, 240A) && dwc->has_lpm_erratum,
"LPM Erratum not available on dwc3 revisions < 2.40a\n");

if (dwc->has_lpm_erratum && !DWC3_VER_IS_PRIOR(DWC3, 240A))
if (dwc->has_lpm_erratum && !DWC3_VER_IS_PRIOR(DWC3, 240A)) {
reg &= ~DWC3_DCTL_NYET_THRES_MASK;
reg |= DWC3_DCTL_NYET_THRES(dwc->lpm_nyet_threshold);
}

dwc3_gadget_dctl_write_safe(dwc, reg);
} else {
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/gadget/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ config USB_F_MIDI

config USB_F_MIDI2
tristate
select SND_UMP
select SND_UMP_LEGACY_RAWMIDI

config USB_F_HID
tristate
Expand Down Expand Up @@ -445,8 +447,6 @@ config USB_CONFIGFS_F_MIDI2
depends on USB_CONFIGFS
depends on SND
select USB_LIBCOMPOSITE
select SND_UMP
select SND_UMP_LEGACY_RAWMIDI
select USB_F_MIDI2
help
The MIDI 2.0 function driver provides the generic emulated
Expand Down
6 changes: 5 additions & 1 deletion drivers/usb/gadget/configfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,11 +827,15 @@ static ssize_t gadget_string_s_store(struct config_item *item, const char *page,
{
struct gadget_string *string = to_gadget_string(item);
int size = min(sizeof(string->string), len + 1);
ssize_t cpy_len;

if (len > USB_MAX_STRING_LEN)
return -EINVAL;

return strscpy(string->string, page, size);
cpy_len = strscpy(string->string, page, size);
if (cpy_len > 0 && string->string[cpy_len - 1] == '\n')
string->string[cpy_len - 1] = 0;
return len;
}
CONFIGFS_ATTR(gadget_string_, s);

Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/gadget/function/f_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2285,7 +2285,7 @@ static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev)
struct usb_gadget_strings **lang;
int first_id;

if (WARN_ON(ffs->state != FFS_ACTIVE
if ((ffs->state != FFS_ACTIVE
|| test_and_set_bit(FFS_FL_BOUND, &ffs->flags)))
return -EBADFD;

Expand Down
1 change: 1 addition & 0 deletions drivers/usb/gadget/function/f_uac2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
uac2->as_in_alt = 0;
}

std_ac_if_desc.bNumEndpoints = 0;
if (FUOUT_EN(uac2_opts) || FUIN_EN(uac2_opts)) {
uac2->int_ep = usb_ep_autoconfig(gadget, &fs_ep_int_desc);
if (!uac2->int_ep) {
Expand Down
8 changes: 4 additions & 4 deletions drivers/usb/gadget/function/u_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -1420,6 +1420,10 @@ void gserial_disconnect(struct gserial *gser)
/* REVISIT as above: how best to track this? */
port->port_line_coding = gser->port_line_coding;

/* disable endpoints, aborting down any active I/O */
usb_ep_disable(gser->out);
usb_ep_disable(gser->in);

port->port_usb = NULL;
gser->ioport = NULL;
if (port->port.count > 0) {
Expand All @@ -1431,10 +1435,6 @@ void gserial_disconnect(struct gserial *gser)
spin_unlock(&port->port_lock);
spin_unlock_irqrestore(&serial_port_lock, flags);

/* disable endpoints, aborting down any active I/O */
usb_ep_disable(gser->out);
usb_ep_disable(gser->in);

/* finally, free any unused/unusable I/O buffers */
spin_lock_irqsave(&port->port_lock, flags);
if (port->port.count == 0)
Expand Down
3 changes: 2 additions & 1 deletion drivers/usb/host/xhci-plat.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,8 @@ int xhci_plat_probe(struct platform_device *pdev, struct device *sysdev, const s

hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node);

if (priv && (priv->quirks & XHCI_SKIP_PHY_INIT))
if ((priv && (priv->quirks & XHCI_SKIP_PHY_INIT)) ||
(xhci->quirks & XHCI_SKIP_PHY_INIT))
hcd->skip_phy_initialization = 1;

if (priv && (priv->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK))
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/serial/cp210x.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
{ USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
{ USB_DEVICE(0x1B93, 0x1013) }, /* Phoenix Contact UPS Device */
{ USB_DEVICE(0x1BA4, 0x0002) }, /* Silicon Labs 358x factory default */
{ USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
{ USB_DEVICE(0x1D6F, 0x0010) }, /* Seluxit ApS RF Dongle */
Expand Down
4 changes: 3 additions & 1 deletion drivers/usb/serial/option.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ static void option_instat_callback(struct urb *urb);

/* MeiG Smart Technology products */
#define MEIGSMART_VENDOR_ID 0x2dee
/* MeiG Smart SRM825L based on Qualcomm 315 */
/* MeiG Smart SRM815/SRM825L based on Qualcomm 315 */
#define MEIGSMART_PRODUCT_SRM825L 0x4d22
/* MeiG Smart SLM320 based on UNISOC UIS8910 */
#define MEIGSMART_PRODUCT_SLM320 0x4d41
Expand Down Expand Up @@ -2405,13 +2405,15 @@ static const struct usb_device_id option_ids[] = {
{ 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_SLM770A, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 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) },
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */
.driver_info = NCTRL(1) },
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */
.driver_info = NCTRL(3) },
{ USB_DEVICE_INTERFACE_CLASS(0x2949, 0x8700, 0xff) }, /* Neoway N723-EA */
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
Expand Down
7 changes: 7 additions & 0 deletions drivers/usb/storage/unusual_devs.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,13 @@ UNUSUAL_DEV( 0x0421, 0x06aa, 0x1110, 0x1110,
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_MAX_SECTORS_64 ),

/* Added by Lubomir Rintel <lkundrak@v3.sk>, a very fine chap */
UNUSUAL_DEV( 0x0421, 0x06c2, 0x0000, 0x0406,
"Nokia",
"Nokia 208",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_MAX_SECTORS_64 ),

#ifdef NO_SDDR09
UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100,
"Microtech",
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/typec/tcpm/maxim_contaminant.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ static int max_contaminant_read_resistance_kohm(struct max_tcpci_chip *chip,

mv = max_contaminant_read_adc_mv(chip, channel, sleep_msec, raw, true);
if (mv < 0)
return ret;
return mv;

/* OVP enable */
ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCOVPDIS, 0);
Expand All @@ -157,7 +157,7 @@ static int max_contaminant_read_resistance_kohm(struct max_tcpci_chip *chip,

mv = max_contaminant_read_adc_mv(chip, channel, sleep_msec, raw, true);
if (mv < 0)
return ret;
return mv;
/* Disable current source */
ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, SBURPCTRL, 0);
if (ret < 0)
Expand Down
25 changes: 15 additions & 10 deletions drivers/usb/typec/tcpm/tcpci.c
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ static int tcpci_init(struct tcpc_dev *tcpc)

tcpci->alert_mask = reg;

return tcpci_write16(tcpci, TCPC_ALERT_MASK, reg);
return 0;
}

irqreturn_t tcpci_irq(struct tcpci *tcpci)
Expand Down Expand Up @@ -923,22 +923,27 @@ static int tcpci_probe(struct i2c_client *client)

chip->data.set_orientation = err;

chip->tcpci = tcpci_register_port(&client->dev, &chip->data);
if (IS_ERR(chip->tcpci))
return PTR_ERR(chip->tcpci);

err = devm_request_threaded_irq(&client->dev, client->irq, NULL,
_tcpci_irq,
IRQF_SHARED | IRQF_ONESHOT,
dev_name(&client->dev), chip);
if (err < 0)
return err;
goto unregister_port;

/*
* Disable irq while registering port. If irq is configured as an edge
* irq this allow to keep track and process the irq as soon as it is enabled.
*/
disable_irq(client->irq);
chip->tcpci = tcpci_register_port(&client->dev, &chip->data);
enable_irq(client->irq);
/* Enable chip interrupts at last */
err = tcpci_write16(chip->tcpci, TCPC_ALERT_MASK, chip->tcpci->alert_mask);
if (err < 0)
goto unregister_port;

return PTR_ERR_OR_ZERO(chip->tcpci);
return 0;

unregister_port:
tcpci_unregister_port(chip->tcpci);
return err;
}

static void tcpci_remove(struct i2c_client *client)
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/typec/ucsi/ucsi_ccg.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,16 +646,16 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command)
UCSI_CMD_CONNECTOR_MASK;
if (con_index == 0) {
ret = -EINVAL;
goto unlock;
goto err_put;
}
con = &uc->ucsi->connector[con_index - 1];
ucsi_ccg_update_set_new_cam_cmd(uc, con, &command);
}

ret = ucsi_sync_control_common(ucsi, command);

err_put:
pm_runtime_put_sync(uc->dev);
unlock:
mutex_unlock(&uc->lock);

return ret;
Expand Down
5 changes: 5 additions & 0 deletions drivers/usb/typec/ucsi/ucsi_glink.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@ static void pmic_glink_ucsi_connector_status(struct ucsi_connector *con)
struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi);
int orientation;

if (!UCSI_CONSTAT(con, CONNECTED)) {
typec_set_orientation(con->port, TYPEC_ORIENTATION_NONE);
return;
}

if (con->num > PMIC_GLINK_MAX_PORTS ||
!ucsi->port_orientation[con->num - 1])
return;
Expand Down

0 comments on commit 196856d

Please sign in to comment.