Commit 4f066b18 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull USB / Thunderbolt fixes from Greg KH:
 "Here are some USB and Thunderbolt driver fixes for reported problems
  for 6.16-rc6.  Included in here are:

   - Thunderbolt fixes for some much-reported issues

   - dwc2 driver fixes

   - dwc3 driver fixes

   - new usb-serial driver device ids

   - gadgetfs configfs fix

   - musb driver fix

   - USB hub driver fix

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

* tag 'usb-6.16-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: hub: Don't try to recover devices lost during warm reset.
  usb: dwc2: gadget: Fix enter to hibernation for UTMI+ PHY
  usb: dwc3: qcom: Don't leave BCR asserted
  USB: serial: option: add Telit Cinterion FE910C04 (ECM) composition
  USB: serial: ftdi_sio: add support for NDI EMGUIDE GEMINI
  usb: gadget: configfs: Fix OOB read on empty string write
  usb: musb: fix gadget state on disconnect
  USB: serial: option: add Foxconn T99W640
  thunderbolt: Fix bit masking in tb_dp_port_set_hops()
  thunderbolt: Fix wake on connect at runtime
parents 673cf893 2521106f
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -1450,7 +1450,7 @@ int tb_dp_port_set_hops(struct tb_port *port, unsigned int video,
		return ret;

	data[0] &= ~ADP_DP_CS_0_VIDEO_HOPID_MASK;
	data[1] &= ~ADP_DP_CS_1_AUX_RX_HOPID_MASK;
	data[1] &= ~ADP_DP_CS_1_AUX_TX_HOPID_MASK;
	data[1] &= ~ADP_DP_CS_1_AUX_RX_HOPID_MASK;

	data[0] |= (video << ADP_DP_CS_0_VIDEO_HOPID_SHIFT) &
@@ -3437,7 +3437,7 @@ void tb_sw_set_unplugged(struct tb_switch *sw)
	}
}

static int tb_switch_set_wake(struct tb_switch *sw, unsigned int flags)
static int tb_switch_set_wake(struct tb_switch *sw, unsigned int flags, bool runtime)
{
	if (flags)
		tb_sw_dbg(sw, "enabling wakeup: %#x\n", flags);
@@ -3445,7 +3445,7 @@ static int tb_switch_set_wake(struct tb_switch *sw, unsigned int flags)
		tb_sw_dbg(sw, "disabling wakeup\n");

	if (tb_switch_is_usb4(sw))
		return usb4_switch_set_wake(sw, flags);
		return usb4_switch_set_wake(sw, flags, runtime);
	return tb_lc_set_wake(sw, flags);
}

@@ -3521,7 +3521,7 @@ int tb_switch_resume(struct tb_switch *sw, bool runtime)
		tb_switch_check_wakes(sw);

	/* Disable wakes */
	tb_switch_set_wake(sw, 0);
	tb_switch_set_wake(sw, 0, true);

	err = tb_switch_tmu_init(sw);
	if (err)
@@ -3603,7 +3603,7 @@ void tb_switch_suspend(struct tb_switch *sw, bool runtime)
		flags |= TB_WAKE_ON_USB4 | TB_WAKE_ON_USB3 | TB_WAKE_ON_PCIE;
	}

	tb_switch_set_wake(sw, flags);
	tb_switch_set_wake(sw, flags, runtime);

	if (tb_switch_is_usb4(sw))
		usb4_switch_set_sleep(sw);
+1 −1
Original line number Diff line number Diff line
@@ -1317,7 +1317,7 @@ int usb4_switch_read_uid(struct tb_switch *sw, u64 *uid);
int usb4_switch_drom_read(struct tb_switch *sw, unsigned int address, void *buf,
			  size_t size);
bool usb4_switch_lane_bonding_possible(struct tb_switch *sw);
int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags);
int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags, bool runtime);
int usb4_switch_set_sleep(struct tb_switch *sw);
int usb4_switch_nvm_sector_size(struct tb_switch *sw);
int usb4_switch_nvm_read(struct tb_switch *sw, unsigned int address, void *buf,
+5 −7
Original line number Diff line number Diff line
@@ -403,12 +403,12 @@ bool usb4_switch_lane_bonding_possible(struct tb_switch *sw)
 * usb4_switch_set_wake() - Enabled/disable wake
 * @sw: USB4 router
 * @flags: Wakeup flags (%0 to disable)
 * @runtime: Wake is being programmed during system runtime
 *
 * Enables/disables router to wake up from sleep.
 */
int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags)
int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags, bool runtime)
{
	struct usb4_port *usb4;
	struct tb_port *port;
	u64 route = tb_route(sw);
	u32 val;
@@ -438,13 +438,11 @@ int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags)
			val |= PORT_CS_19_WOU4;
		} else {
			bool configured = val & PORT_CS_19_PC;
			usb4 = port->usb4;
			bool wakeup = runtime || device_may_wakeup(&port->usb4->dev);

			if (((flags & TB_WAKE_ON_CONNECT) &&
			      device_may_wakeup(&usb4->dev)) && !configured)
			if ((flags & TB_WAKE_ON_CONNECT) && wakeup && !configured)
				val |= PORT_CS_19_WOC;
			if (((flags & TB_WAKE_ON_DISCONNECT) &&
			      device_may_wakeup(&usb4->dev)) && configured)
			if ((flags & TB_WAKE_ON_DISCONNECT) && wakeup && configured)
				val |= PORT_CS_19_WOD;
			if ((flags & TB_WAKE_ON_USB4) && configured)
				val |= PORT_CS_19_WOU4;
+6 −2
Original line number Diff line number Diff line
@@ -5751,6 +5751,7 @@ static void port_event(struct usb_hub *hub, int port1)
	struct usb_device *hdev = hub->hdev;
	u16 portstatus, portchange;
	int i = 0;
	int err;

	connect_change = test_bit(port1, hub->change_bits);
	clear_bit(port1, hub->event_bits);
@@ -5847,8 +5848,11 @@ static void port_event(struct usb_hub *hub, int port1)
		} else if (!udev || !(portstatus & USB_PORT_STAT_CONNECTION)
				|| udev->state == USB_STATE_NOTATTACHED) {
			dev_dbg(&port_dev->dev, "do warm reset, port only\n");
			if (hub_port_reset(hub, port1, NULL,
					HUB_BH_RESET_TIME, true) < 0)
			err = hub_port_reset(hub, port1, NULL,
					     HUB_BH_RESET_TIME, true);
			if (!udev && err == -ENOTCONN)
				connect_change = 0;
			else if (err < 0)
				hub_port_disable(hub, port1, 1);
		} else {
			dev_dbg(&port_dev->dev, "do warm reset, full device\n");
+26 −12
Original line number Diff line number Diff line
@@ -5389,7 +5389,6 @@ int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg)
	if (gusbcfg & GUSBCFG_ULPI_UTMI_SEL) {
		/* ULPI interface */
		gpwrdn |= GPWRDN_ULPI_LATCH_EN_DURING_HIB_ENTRY;
	}
		dwc2_writel(hsotg, gpwrdn, GPWRDN);
		udelay(10);

@@ -5403,6 +5402,21 @@ int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg)
		gpwrdn |= GPWRDN_PMUACTV;
		dwc2_writel(hsotg, gpwrdn, GPWRDN);
		udelay(10);
	} else {
		/* UTMI+ Interface */
		dwc2_writel(hsotg, gpwrdn, GPWRDN);
		udelay(10);

		gpwrdn = dwc2_readl(hsotg, GPWRDN);
		gpwrdn |= GPWRDN_PMUACTV;
		dwc2_writel(hsotg, gpwrdn, GPWRDN);
		udelay(10);

		pcgcctl = dwc2_readl(hsotg, PCGCTL);
		pcgcctl |= PCGCTL_STOPPCLK;
		dwc2_writel(hsotg, pcgcctl, PCGCTL);
		udelay(10);
	}

	/* Set flag to indicate that we are in hibernation */
	hsotg->hibernated = 1;
Loading