Commit 2d5c7fe0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull USB fixes from Greg KH:
 "Here are some small USB driver fixes and new device ids for 6.15-rc4.
  Nothing major in here, just the normal set of issues that have cropped
  up after -rc1:

   - new device ids for usb-serial drivers

   - new device quirks added

   - typec driver fixes

   - chipidea driver fixes

   - xhci driver fixes

   - wdm driver fixes

   - cdns3 driver fixes

   - MAINTAINERS file update

  All of these, except for the MAINTAINERS file update, have been in
  linux-next for a while with no reported issues"

* tag 'usb-6.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (27 commits)
  MAINTAINERS: Assign maintainer for the port controller drivers
  USB: serial: simple: add OWON HDS200 series oscilloscope support
  USB: serial: ftdi_sio: add support for Abacus Electrics Optical Probe
  USB: serial: option: add Sierra Wireless EM9291
  usb: typec: class: Unlocked on error in typec_register_partner()
  usb: quirks: Add delay init quirk for SanDisk 3.2Gen1 Flash Drive
  USB: wdm: add annotation
  USB: wdm: wdm_wwan_port_tx_complete mutex in atomic context
  USB: wdm: close race between wdm_open and wdm_wwan_port_stop
  USB: wdm: handle IO errors in wdm_wwan_port_start
  USB: VLI disk crashes if LPM is used
  usb: dwc3: gadget: check that event count does not exceed event buffer length
  USB: storage: quirk for ADATA Portable HDD CH94
  usb: quirks: add DELAY_INIT quirk for Silicon Motion Flash Drive
  USB: OHCI: Add quirk for LS7A OHCI controller (rev 0x02)
  usb: dwc3: xilinx: Prevent spike in reset signal
  usb: cdns3: Fix deadlock when using NCM gadget
  usb: chipidea: ci_hdrc_imx: implement usb_phy_init() error handling
  usb: chipidea: ci_hdrc_imx: fix call balance of regulator routines
  usb: chipidea: ci_hdrc_imx: fix usbmisc handling
  ...
parents 3648af4b 3dfc0445
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -25204,9 +25204,13 @@ S: Maintained
F:	drivers/usb/typec/mux/pi3usb30532.c
USB TYPEC PORT CONTROLLER DRIVERS
M:	Badhri Jagan Sridharan <badhri@google.com>
L:	linux-usb@vger.kernel.org
S:	Orphan
F:	drivers/usb/typec/tcpm/
S:	Maintained
F:	drivers/usb/typec/tcpm/tcpci.c
F:	drivers/usb/typec/tcpm/tcpm.c
F:	include/linux/usb/tcpci.h
F:	include/linux/usb/tcpm.h
USB TYPEC TUSB1046 MUX DRIVER
M:	Romain Gantois <romain.gantois@bootlin.com>
+2 −0
Original line number Diff line number Diff line
@@ -1963,6 +1963,7 @@ static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data)
	unsigned int bit;
	unsigned long reg;

	local_bh_disable();
	spin_lock_irqsave(&priv_dev->lock, flags);

	reg = readl(&priv_dev->regs->usb_ists);
@@ -2004,6 +2005,7 @@ static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data)
irqend:
	writel(~0, &priv_dev->regs->ep_ien);
	spin_unlock_irqrestore(&priv_dev->lock, flags);
	local_bh_enable();

	return ret;
}
+31 −13
Original line number Diff line number Diff line
@@ -336,6 +336,13 @@ static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event)
	return ret;
}

static void ci_hdrc_imx_disable_regulator(void *arg)
{
	struct ci_hdrc_imx_data *data = arg;

	regulator_disable(data->hsic_pad_regulator);
}

static int ci_hdrc_imx_probe(struct platform_device *pdev)
{
	struct ci_hdrc_imx_data *data;
@@ -394,6 +401,13 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
					"Failed to enable HSIC pad regulator\n");
				goto err_put;
			}
			ret = devm_add_action_or_reset(dev,
					ci_hdrc_imx_disable_regulator, data);
			if (ret) {
				dev_err(dev,
					"Failed to add regulator devm action\n");
				goto err_put;
			}
		}
	}

@@ -432,11 +446,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)

	ret = imx_get_clks(dev);
	if (ret)
		goto disable_hsic_regulator;
		goto qos_remove_request;

	ret = imx_prepare_enable_clks(dev);
	if (ret)
		goto disable_hsic_regulator;
		goto qos_remove_request;

	ret = clk_prepare_enable(data->clk_wakeup);
	if (ret)
@@ -470,7 +484,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
	    of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) {
		pdata.flags |= CI_HDRC_OVERRIDE_PHY_CONTROL;
		data->override_phy_control = true;
		usb_phy_init(pdata.usb_phy);
		ret = usb_phy_init(pdata.usb_phy);
		if (ret) {
			dev_err(dev, "Failed to init phy\n");
			goto err_clk;
		}
	}

	if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
@@ -479,7 +497,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
	ret = imx_usbmisc_init(data->usbmisc_data);
	if (ret) {
		dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
		goto err_clk;
		goto phy_shutdown;
	}

	data->ci_pdev = ci_hdrc_add_device(dev,
@@ -488,7 +506,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
	if (IS_ERR(data->ci_pdev)) {
		ret = PTR_ERR(data->ci_pdev);
		dev_err_probe(dev, ret, "ci_hdrc_add_device failed\n");
		goto err_clk;
		goto phy_shutdown;
	}

	if (data->usbmisc_data) {
@@ -522,18 +540,19 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)

disable_device:
	ci_hdrc_remove_device(data->ci_pdev);
phy_shutdown:
	if (data->override_phy_control)
		usb_phy_shutdown(data->phy);
err_clk:
	clk_disable_unprepare(data->clk_wakeup);
err_wakeup_clk:
	imx_disable_unprepare_clks(dev);
disable_hsic_regulator:
	if (data->hsic_pad_regulator)
		/* don't overwrite original ret (cf. EPROBE_DEFER) */
		regulator_disable(data->hsic_pad_regulator);
qos_remove_request:
	if (pdata.flags & CI_HDRC_PMQOS)
		cpu_latency_qos_remove_request(&data->pm_qos_req);
	data->ci_pdev = NULL;
err_put:
	if (data->usbmisc_data)
		put_device(data->usbmisc_data->dev);
	return ret;
}
@@ -556,9 +575,8 @@ static void ci_hdrc_imx_remove(struct platform_device *pdev)
		clk_disable_unprepare(data->clk_wakeup);
		if (data->plat_data->flags & CI_HDRC_PMQOS)
			cpu_latency_qos_remove_request(&data->pm_qos_req);
		if (data->hsic_pad_regulator)
			regulator_disable(data->hsic_pad_regulator);
	}
	if (data->usbmisc_data)
		put_device(data->usbmisc_data->dev);
}

+16 −5
Original line number Diff line number Diff line
@@ -726,7 +726,7 @@ static int wdm_open(struct inode *inode, struct file *file)
		rv = -EBUSY;
		goto out;
	}

	smp_rmb(); /* ordered against wdm_wwan_port_stop() */
	rv = usb_autopm_get_interface(desc->intf);
	if (rv < 0) {
		dev_err(&desc->intf->dev, "Error autopm - %d\n", rv);
@@ -829,6 +829,7 @@ static struct usb_class_driver wdm_class = {
static int wdm_wwan_port_start(struct wwan_port *port)
{
	struct wdm_device *desc = wwan_port_get_drvdata(port);
	int rv;

	/* The interface is both exposed via the WWAN framework and as a
	 * legacy usbmisc chardev. If chardev is already open, just fail
@@ -848,7 +849,15 @@ static int wdm_wwan_port_start(struct wwan_port *port)
	wwan_port_txon(port);

	/* Start getting events */
	return usb_submit_urb(desc->validity, GFP_KERNEL);
	rv = usb_submit_urb(desc->validity, GFP_KERNEL);
	if (rv < 0) {
		wwan_port_txoff(port);
		desc->manage_power(desc->intf, 0);
		/* this must be last lest we race with chardev open */
		clear_bit(WDM_WWAN_IN_USE, &desc->flags);
	}

	return rv;
}

static void wdm_wwan_port_stop(struct wwan_port *port)
@@ -859,8 +868,10 @@ static void wdm_wwan_port_stop(struct wwan_port *port)
	poison_urbs(desc);
	desc->manage_power(desc->intf, 0);
	clear_bit(WDM_READ, &desc->flags);
	clear_bit(WDM_WWAN_IN_USE, &desc->flags);
	unpoison_urbs(desc);
	smp_wmb(); /* ordered against wdm_open() */
	/* this must be last lest we open a poisoned device */
	clear_bit(WDM_WWAN_IN_USE, &desc->flags);
}

static void wdm_wwan_port_tx_complete(struct urb *urb)
@@ -868,7 +879,7 @@ static void wdm_wwan_port_tx_complete(struct urb *urb)
	struct sk_buff *skb = urb->context;
	struct wdm_device *desc = skb_shinfo(skb)->destructor_arg;

	usb_autopm_put_interface(desc->intf);
	usb_autopm_put_interface_async(desc->intf);
	wwan_port_txon(desc->wwanp);
	kfree_skb(skb);
}
@@ -898,7 +909,7 @@ static int wdm_wwan_port_tx(struct wwan_port *port, struct sk_buff *skb)
	req->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
	req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
	req->wValue = 0;
	req->wIndex = desc->inum;
	req->wIndex = desc->inum; /* already converted */
	req->wLength = cpu_to_le16(skb->len);

	skb_shinfo(skb)->destructor_arg = desc;
+9 −0
Original line number Diff line number Diff line
@@ -369,6 +369,9 @@ static const struct usb_device_id usb_quirk_list[] = {
	{ USB_DEVICE(0x0781, 0x5583), .driver_info = USB_QUIRK_NO_LPM },
	{ USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM },

	/* SanDisk Corp. SanDisk 3.2Gen1 */
	{ USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT },

	/* Realforce 87U Keyboard */
	{ USB_DEVICE(0x0853, 0x011b), .driver_info = USB_QUIRK_NO_LPM },

@@ -383,6 +386,9 @@ static const struct usb_device_id usb_quirk_list[] = {
	{ USB_DEVICE(0x0904, 0x6103), .driver_info =
			USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },

	/* Silicon Motion Flash Drive */
	{ USB_DEVICE(0x090c, 0x1000), .driver_info = USB_QUIRK_DELAY_INIT },

	/* Sound Devices USBPre2 */
	{ USB_DEVICE(0x0926, 0x0202), .driver_info =
			USB_QUIRK_ENDPOINT_IGNORE },
@@ -539,6 +545,9 @@ static const struct usb_device_id usb_quirk_list[] = {
	{ USB_DEVICE(0x2040, 0x7200), .driver_info =
			USB_QUIRK_CONFIG_INTF_STRINGS },

	/* VLI disk */
	{ USB_DEVICE(0x2109, 0x0711), .driver_info = USB_QUIRK_NO_LPM },

	/* Raydium Touchscreen */
	{ USB_DEVICE(0x2386, 0x3114), .driver_info = USB_QUIRK_NO_LPM },

Loading