Commit 3c2bd251 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull USB fixes from Greg KH:
 "Here are some USB driver fixes for 6.16-rc5. I originally wanted this
  to get into -rc4, but there were some regressions that had to be
  handled first. Now all looks good. Included in here are the following
  fixes:

   - cdns3 driver fixes

   - xhci driver fixes

   - typec driver fixes

   - USB hub fixes (this is what took the longest to get right)

   - new USB driver quirks added

   - chipidea driver fixes

  All of these have been in linux-next for a while and now we have no
  more reported problems with them"

* tag 'usb-6.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (21 commits)
  usb: hub: Fix flushing of delayed work used for post resume purposes
  xhci: dbc: Flush queued requests before stopping dbc
  xhci: dbctty: disable ECHO flag by default
  xhci: Disable stream for xHC controller with XHCI_BROKEN_STREAMS
  usb: xhci: quirk for data loss in ISOC transfers
  usb: dwc3: gadget: Fix TRB reclaim logic for short transfers and ZLPs
  usb: hub: Fix flushing and scheduling of delayed work that tunes runtime pm
  usb: typec: displayport: Fix potential deadlock
  usb: typec: altmodes/displayport: do not index invalid pin_assignments
  usb: cdnsp: Fix issue with CV Bad Descriptor test
  usb: typec: tcpm: apply vbus before data bringup in tcpm_src_attach
  Revert "usb: xhci: Implement xhci_handshake_check_state() helper"
  usb: xhci: Skip xhci_reset in xhci_resume if xhci is being removed
  usb: gadget: u_serial: Fix race condition in TTY wakeup
  Revert "usb: gadget: u_serial: Add null pointer check in gs_start_io"
  usb: chipidea: udc: disconnect/reconnect from host when do suspend/resume
  usb: acpi: fix device link removal
  usb: hub: fix detection of high tier USB3 devices behind suspended hubs
  Logitech C-270 even more broken
  usb: dwc3: Abort suspend on soft disconnect failure
  ...
parents d46971e0 9bd9c802
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -327,12 +327,13 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
	case TRB_RESET_EP:
	case TRB_HALT_ENDPOINT:
		ret = scnprintf(str, size,
				"%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c",
				"%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c %c",
				cdnsp_trb_type_string(type),
				ep_num, ep_id % 2 ? "out" : "in",
				TRB_TO_EP_INDEX(field3), field1, field0,
				TRB_TO_SLOT_ID(field3),
				field3 & TRB_CYCLE ? 'C' : 'c');
				field3 & TRB_CYCLE ? 'C' : 'c',
				field3 & TRB_ESP ? 'P' : 'p');
		break;
	case TRB_STOP_RING:
		ret = scnprintf(str, size,
+15 −3
Original line number Diff line number Diff line
@@ -414,6 +414,7 @@ static int cdnsp_ep0_std_request(struct cdnsp_device *pdev,
void cdnsp_setup_analyze(struct cdnsp_device *pdev)
{
	struct usb_ctrlrequest *ctrl = &pdev->setup;
	struct cdnsp_ep *pep;
	int ret = -EINVAL;
	u16 len;

@@ -427,10 +428,21 @@ void cdnsp_setup_analyze(struct cdnsp_device *pdev)
		goto out;
	}

	pep = &pdev->eps[0];

	/* Restore the ep0 to Stopped/Running state. */
	if (pdev->eps[0].ep_state & EP_HALTED) {
		trace_cdnsp_ep0_halted("Restore to normal state");
		cdnsp_halt_endpoint(pdev, &pdev->eps[0], 0);
	if (pep->ep_state & EP_HALTED) {
		if (GET_EP_CTX_STATE(pep->out_ctx) == EP_STATE_HALTED)
			cdnsp_halt_endpoint(pdev, pep, 0);

		/*
		 * Halt Endpoint Command for SSP2 for ep0 preserve current
		 * endpoint state and driver has to synchronize the
		 * software endpoint state with endpoint output context
		 * state.
		 */
		pep->ep_state &= ~EP_HALTED;
		pep->ep_state |= EP_STOPPED;
	}

	/*
+6 −0
Original line number Diff line number Diff line
@@ -987,6 +987,12 @@ enum cdnsp_setup_dev {
#define STREAM_ID_FOR_TRB(p)		((((p)) << 16) & GENMASK(31, 16))
#define SCT_FOR_TRB(p)			(((p) << 1) & 0x7)

/*
 * Halt Endpoint Command TRB field.
 * The ESP bit only exists in the SSP2 controller.
 */
#define TRB_ESP				BIT(9)

/* Link TRB specific fields. */
#define TRB_TC				BIT(1)

+5 −2
Original line number Diff line number Diff line
@@ -772,7 +772,9 @@ static int cdnsp_update_port_id(struct cdnsp_device *pdev, u32 port_id)
	}

	if (port_id != old_port) {
		if (pdev->slot_id)
			cdnsp_disable_slot(pdev);

		pdev->active_port = port;
		cdnsp_enable_slot(pdev);
	}
@@ -2483,7 +2485,8 @@ void cdnsp_queue_halt_endpoint(struct cdnsp_device *pdev, unsigned int ep_index)
{
	cdnsp_queue_command(pdev, 0, 0, 0, TRB_TYPE(TRB_HALT_ENDPOINT) |
			    SLOT_ID_FOR_TRB(pdev->slot_id) |
			    EP_ID_FOR_TRB(ep_index));
			    EP_ID_FOR_TRB(ep_index) |
			    (!ep_index ? TRB_ESP : 0));
}

void cdnsp_force_header_wakeup(struct cdnsp_device *pdev, int intf_num)
+7 −0
Original line number Diff line number Diff line
@@ -2374,6 +2374,10 @@ static void udc_suspend(struct ci_hdrc *ci)
	 */
	if (hw_read(ci, OP_ENDPTLISTADDR, ~0) == 0)
		hw_write(ci, OP_ENDPTLISTADDR, ~0, ~0);

	if (ci->gadget.connected &&
	    (!ci->suspended || !device_may_wakeup(ci->dev)))
		usb_gadget_disconnect(&ci->gadget);
}

static void udc_resume(struct ci_hdrc *ci, bool power_lost)
@@ -2384,6 +2388,9 @@ static void udc_resume(struct ci_hdrc *ci, bool power_lost)
					OTGSC_BSVIS | OTGSC_BSVIE);
		if (ci->vbus_active)
			usb_gadget_vbus_disconnect(&ci->gadget);
	} else if (ci->vbus_active && ci->driver &&
		   !ci->gadget.connected) {
		usb_gadget_connect(&ci->gadget);
	}

	/* Restore value 0 if it was set for power lost check */
Loading