Commit 3c152370 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull USB driver fixes from Greg KH:
 "Here are some small USB driver fixes for reported problems for
  6.9-rc7. Included in here are:

   - usb core fixes for found issues

   - typec driver fixes for reported problems

   - usb gadget driver fixes for reported problems

   - xhci build fixes

   - dwc3 driver fixes for reported issues

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

* tag 'usb-6.9-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: typec: tcpm: Check for port partner validity before consuming it
  usb: typec: tcpm: enforce ready state when queueing alt mode vdm
  usb: typec: tcpm: unregister existing source caps before re-registration
  usb: typec: tcpm: clear pd_event queue in PORT_RESET
  usb: typec: tcpm: queue correct sop type in tcpm_queue_vdm_unlocked
  usb: Fix regression caused by invalid ep0 maxpacket in virtual SuperSpeed device
  usb: ohci: Prevent missed ohci interrupts
  usb: typec: qcom-pmic: fix pdphy start() error handling
  usb: typec: qcom-pmic: fix use-after-free on late probe errors
  usb: gadget: f_fs: Fix a race condition when processing setup packets.
  USB: core: Fix access violation during port device removal
  usb: dwc3: core: Prevent phy suspend during init
  usb: xhci-plat: Don't include xhci.h
  usb: gadget: uvc: use correct buffer size when parsing configfs lists
  usb: gadget: composite: fix OS descriptors w_value logic
  usb: gadget: f_fs: Fix race between aio_cancel() and AIO request complete
parents 3f1d0865 ae11f04b
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -5110,9 +5110,10 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
	}
	if (usb_endpoint_maxp(&udev->ep0.desc) == i) {
		;	/* Initial ep0 maxpacket guess is right */
	} else if ((udev->speed == USB_SPEED_FULL ||
	} else if (((udev->speed == USB_SPEED_FULL ||
				udev->speed == USB_SPEED_HIGH) &&
			(i == 8 || i == 16 || i == 32 || i == 64)) {
			(i == 8 || i == 16 || i == 32 || i == 64)) ||
			(udev->speed >= USB_SPEED_SUPER && i > 0)) {
		/* Initial guess is wrong; use the descriptor's value */
		if (udev->speed == USB_SPEED_FULL)
			dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
+6 −2
Original line number Diff line number Diff line
@@ -51,13 +51,15 @@ static ssize_t disable_show(struct device *dev,
	struct usb_port *port_dev = to_usb_port(dev);
	struct usb_device *hdev = to_usb_device(dev->parent->parent);
	struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
	struct usb_interface *intf = to_usb_interface(hub->intfdev);
	struct usb_interface *intf = to_usb_interface(dev->parent);
	int port1 = port_dev->portnum;
	u16 portstatus, unused;
	bool disabled;
	int rc;
	struct kernfs_node *kn;

	if (!hub)
		return -ENODEV;
	hub_get(hub);
	rc = usb_autopm_get_interface(intf);
	if (rc < 0)
@@ -101,12 +103,14 @@ static ssize_t disable_store(struct device *dev, struct device_attribute *attr,
	struct usb_port *port_dev = to_usb_port(dev);
	struct usb_device *hdev = to_usb_device(dev->parent->parent);
	struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
	struct usb_interface *intf = to_usb_interface(hub->intfdev);
	struct usb_interface *intf = to_usb_interface(dev->parent);
	int port1 = port_dev->portnum;
	bool disabled;
	int rc;
	struct kernfs_node *kn;

	if (!hub)
		return -ENODEV;
	rc = kstrtobool(buf, &disabled);
	if (rc)
		return rc;
+38 −52
Original line number Diff line number Diff line
@@ -104,6 +104,27 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc)
	return 0;
}

void dwc3_enable_susphy(struct dwc3 *dwc, bool enable)
{
	u32 reg;

	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
	if (enable && !dwc->dis_u3_susphy_quirk)
		reg |= DWC3_GUSB3PIPECTL_SUSPHY;
	else
		reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;

	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);

	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
	if (enable && !dwc->dis_u2_susphy_quirk)
		reg |= DWC3_GUSB2PHYCFG_SUSPHY;
	else
		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;

	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
}

void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
{
	u32 reg;
@@ -585,11 +606,8 @@ static int dwc3_core_ulpi_init(struct dwc3 *dwc)
 */
static int dwc3_phy_setup(struct dwc3 *dwc)
{
	unsigned int hw_mode;
	u32 reg;

	hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);

	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));

	/*
@@ -599,20 +617,15 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
	reg &= ~DWC3_GUSB3PIPECTL_UX_EXIT_PX;

	/*
	 * Above 1.94a, it is recommended to set DWC3_GUSB3PIPECTL_SUSPHY
	 * to '0' during coreConsultant configuration. So default value
	 * will be '0' when the core is reset. Application needs to set it
	 * to '1' after the core initialization is completed.
	 */
	if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A))
		reg |= DWC3_GUSB3PIPECTL_SUSPHY;

	/*
	 * For DRD controllers, GUSB3PIPECTL.SUSPENDENABLE must be cleared after
	 * power-on reset, and it can be set after core initialization, which is
	 * after device soft-reset during initialization.
	 * Above DWC_usb3.0 1.94a, it is recommended to set
	 * DWC3_GUSB3PIPECTL_SUSPHY to '0' during coreConsultant configuration.
	 * So default value will be '0' when the core is reset. Application
	 * needs to set it to '1' after the core initialization is completed.
	 *
	 * Similarly for DRD controllers, GUSB3PIPECTL.SUSPENDENABLE must be
	 * cleared after power-on reset, and it can be set after core
	 * initialization.
	 */
	if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD)
	reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;

	if (dwc->u2ss_inp3_quirk)
@@ -639,9 +652,6 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
	if (dwc->tx_de_emphasis_quirk)
		reg |= DWC3_GUSB3PIPECTL_TX_DEEPH(dwc->tx_de_emphasis);

	if (dwc->dis_u3_susphy_quirk)
		reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;

	if (dwc->dis_del_phy_power_chg_quirk)
		reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE;

@@ -689,23 +699,14 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
	}

	/*
	 * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to
	 * '0' during coreConsultant configuration. So default value will
	 * be '0' when the core is reset. Application needs to set it to
	 * '1' after the core initialization is completed.
	 */
	if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A))
		reg |= DWC3_GUSB2PHYCFG_SUSPHY;

	/*
	 * For DRD controllers, GUSB2PHYCFG.SUSPHY must be cleared after
	 * power-on reset, and it can be set after core initialization, which is
	 * after device soft-reset during initialization.
	 * Above DWC_usb3.0 1.94a, it is recommended to set
	 * DWC3_GUSB2PHYCFG_SUSPHY to '0' during coreConsultant configuration.
	 * So default value will be '0' when the core is reset. Application
	 * needs to set it to '1' after the core initialization is completed.
	 *
	 * Similarly for DRD controllers, GUSB2PHYCFG.SUSPHY must be cleared
	 * after power-on reset, and it can be set after core initialization.
	 */
	if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD)
		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;

	if (dwc->dis_u2_susphy_quirk)
	reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;

	if (dwc->dis_enblslpm_quirk)
@@ -1227,21 +1228,6 @@ static int dwc3_core_init(struct dwc3 *dwc)
	if (ret)
		goto err_exit_phy;

	if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD &&
	    !DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) {
		if (!dwc->dis_u3_susphy_quirk) {
			reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
			reg |= DWC3_GUSB3PIPECTL_SUSPHY;
			dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
		}

		if (!dwc->dis_u2_susphy_quirk) {
			reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
			reg |= DWC3_GUSB2PHYCFG_SUSPHY;
			dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
		}
	}

	dwc3_core_setup_global_control(dwc);
	dwc3_core_num_eps(dwc);

+1 −0
Original line number Diff line number Diff line
@@ -1580,6 +1580,7 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc);
void dwc3_event_buffers_cleanup(struct dwc3 *dwc);

int dwc3_core_soft_reset(struct dwc3 *dwc);
void dwc3_enable_susphy(struct dwc3 *dwc, bool enable);

#if IS_ENABLED(CONFIG_USB_DWC3_HOST) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
int dwc3_host_init(struct dwc3 *dwc);
+2 −0
Original line number Diff line number Diff line
@@ -2924,6 +2924,7 @@ static int __dwc3_gadget_start(struct dwc3 *dwc)
	dwc3_ep0_out_start(dwc);

	dwc3_gadget_enable_irq(dwc);
	dwc3_enable_susphy(dwc, true);

	return 0;

@@ -4690,6 +4691,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
	if (!dwc->gadget)
		return;

	dwc3_enable_susphy(dwc, false);
	usb_del_gadget(dwc->gadget);
	dwc3_gadget_free_endpoints(dwc);
	usb_put_gadget(dwc->gadget);
Loading