Commit 5ac93d0c authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'usb-for-v4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next

Felipe writes:

USB changes for v4.21

So it looks like folks are interested in dwc3 again. Almost 64% of the
changes are in dwc3 this time around with some other bits in gadget
functions and dwc2.

There are two important parts here: a. removal of the waitqueue from
dwc3's dequeue implementation, which will guarantee that gadget
functions can dequeue from any context and; b. better method for
starting isochronous transfers to avoid, as much as possible, missed
isoc frames.

Apart from these, we have the usual set of non-critical fixes and new
features all over the place.

* tag 'usb-for-v4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb: (56 commits)
  usb: dwc2: Fix disable all EP's on disconnect
  usb: dwc3: gadget: Disable CSP for stream OUT ep
  usb: dwc2: disable power_down on Amlogic devices
  Revert "usb: dwc3: pci: Use devm functions to get the phy GPIOs"
  USB: gadget: udc: s3c2410_udc: convert to DEFINE_SHOW_ATTRIBUTE
  usb: mtu3: fix dbginfo in qmu_tx_zlp_error_handler
  usb: dwc3: trace: add missing break statement to make compiler happy
  usb: dwc3: gadget: Report isoc transfer frame number
  usb: gadget: Introduce frame_number to usb_request
  usb: renesas_usbhs: Use SIMPLE_DEV_PM_OPS macro
  usb: renesas_usbhs: Remove dummy runtime PM callbacks
  usb: dwc2: host: use hrtimer for NAK retries
  usb: mtu3: clear SOFTCONN when clear USB3_EN if work as HS mode
  usb: mtu3: enable SETUPENDISR interrupt
  usb: mtu3: fix the issue about SetFeature(U1/U2_Enable)
  usb: mtu3: enable hardware remote wakeup from L1 automatically
  usb: mtu3: remove QMU checksum
  usb/mtu3: power down device ip at setup
  usb: dwc2: Disable power down feature on Samsung SoCs
  usb: dwc3: Correct the logic for checking TRB full in __dwc3_prepare_one_trb()
  ...
parents ed0a773b 4fe4f9fe
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -37,7 +37,11 @@ Optional properties:
 - phy-names: from the *Generic PHY* bindings; supported names are "usb2-phy"
	or "usb3-phy".
 - resets: a single pair of phandle and reset specifier
 - snps,usb2-lpm-disable: indicate if we don't want to enable USB2 HW LPM
 - snps,usb3_lpm_capable: determines if platform is USB3 LPM capable
 - snps,dis-start-transfer-quirk: when set, disable isoc START TRANSFER command
			failure SW work-around for DWC_usb31 version 1.70a-ea06
			and prior.
 - snps,disable_scramble_quirk: true when SW should disable data scrambling.
	Only really useful for FPGA builds.
 - snps,has-lpm-erratum: true when DWC3 was configured with LPM Erratum enabled
+25 −19
Original line number Diff line number Diff line
@@ -262,7 +262,7 @@ static void dwc2_gadget_wkup_alert_handler(struct dwc2_hsotg *hsotg)
	if (gintsts2 & GINTSTS2_WKUP_ALERT_INT) {
		dev_dbg(hsotg->dev, "%s: Wkup_Alert_Int\n", __func__);
		dwc2_clear_bit(hsotg, GINTSTS2, GINTSTS2_WKUP_ALERT_INT);
		dwc2_set_bit(hsotg, DCFG, DCTL_RMTWKUPSIG);
		dwc2_set_bit(hsotg, DCTL, DCTL_RMTWKUPSIG);
	}
}

@@ -3165,8 +3165,6 @@ static void kill_all_requests(struct dwc2_hsotg *hsotg,
		dwc2_hsotg_txfifo_flush(hsotg, ep->fifo_index);
}

static int dwc2_hsotg_ep_disable(struct usb_ep *ep);

/**
 * dwc2_hsotg_disconnect - disconnect service
 * @hsotg: The device state.
@@ -3188,9 +3186,11 @@ void dwc2_hsotg_disconnect(struct dwc2_hsotg *hsotg)
	/* all endpoints should be shutdown */
	for (ep = 0; ep < hsotg->num_of_eps; ep++) {
		if (hsotg->eps_in[ep])
			dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
			kill_all_requests(hsotg, hsotg->eps_in[ep],
					  -ESHUTDOWN);
		if (hsotg->eps_out[ep])
			dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
			kill_all_requests(hsotg, hsotg->eps_out[ep],
					  -ESHUTDOWN);
	}

	call_gadget(hsotg, disconnect);
@@ -3234,6 +3234,7 @@ static void dwc2_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic)
			GINTSTS_PTXFEMP |  \
			GINTSTS_RXFLVL)

static int dwc2_hsotg_ep_disable(struct usb_ep *ep);
/**
 * dwc2_hsotg_core_init - issue softreset to the core
 * @hsotg: The device state
@@ -4069,10 +4070,8 @@ static int dwc2_hsotg_ep_disable(struct usb_ep *ep)
	struct dwc2_hsotg *hsotg = hs_ep->parent;
	int dir_in = hs_ep->dir_in;
	int index = hs_ep->index;
	unsigned long flags;
	u32 epctrl_reg;
	u32 ctrl;
	int locked;

	dev_dbg(hsotg->dev, "%s(ep %p)\n", __func__, ep);

@@ -4088,10 +4087,6 @@ static int dwc2_hsotg_ep_disable(struct usb_ep *ep)

	epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index);

	locked = spin_is_locked(&hsotg->lock);
	if (!locked)
		spin_lock_irqsave(&hsotg->lock, flags);

	ctrl = dwc2_readl(hsotg, epctrl_reg);

	if (ctrl & DXEPCTL_EPENA)
@@ -4114,12 +4109,22 @@ static int dwc2_hsotg_ep_disable(struct usb_ep *ep)
	hs_ep->fifo_index = 0;
	hs_ep->fifo_size = 0;

	if (!locked)
		spin_unlock_irqrestore(&hsotg->lock, flags);

	return 0;
}

static int dwc2_hsotg_ep_disable_lock(struct usb_ep *ep)
{
	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
	struct dwc2_hsotg *hsotg = hs_ep->parent;
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&hsotg->lock, flags);
	ret = dwc2_hsotg_ep_disable(ep);
	spin_unlock_irqrestore(&hsotg->lock, flags);
	return ret;
}

/**
 * on_list - check request is on the given endpoint
 * @ep: The endpoint to check.
@@ -4267,7 +4272,7 @@ static int dwc2_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value)

static const struct usb_ep_ops dwc2_hsotg_ep_ops = {
	.enable		= dwc2_hsotg_ep_enable,
	.disable	= dwc2_hsotg_ep_disable,
	.disable	= dwc2_hsotg_ep_disable_lock,
	.alloc_request	= dwc2_hsotg_ep_alloc_request,
	.free_request	= dwc2_hsotg_ep_free_request,
	.queue		= dwc2_hsotg_ep_queue_lock,
@@ -4407,9 +4412,9 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget)
	/* all endpoints should be shutdown */
	for (ep = 1; ep < hsotg->num_of_eps; ep++) {
		if (hsotg->eps_in[ep])
			dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
			dwc2_hsotg_ep_disable_lock(&hsotg->eps_in[ep]->ep);
		if (hsotg->eps_out[ep])
			dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
			dwc2_hsotg_ep_disable_lock(&hsotg->eps_out[ep]->ep);
	}

	spin_lock_irqsave(&hsotg->lock, flags);
@@ -4857,9 +4862,9 @@ int dwc2_hsotg_suspend(struct dwc2_hsotg *hsotg)

		for (ep = 0; ep < hsotg->num_of_eps; ep++) {
			if (hsotg->eps_in[ep])
				dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
				dwc2_hsotg_ep_disable_lock(&hsotg->eps_in[ep]->ep);
			if (hsotg->eps_out[ep])
				dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
				dwc2_hsotg_ep_disable_lock(&hsotg->eps_out[ep]->ep);
		}
	}

@@ -5026,6 +5031,7 @@ void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg)
	val |= hsotg->params.lpm_clock_gating ? GLPMCFG_ENBLSLPM : 0;
	val |= hsotg->params.hird_threshold << GLPMCFG_HIRD_THRES_SHIFT;
	val |= hsotg->params.besl ? GLPMCFG_ENBESL : 0;
	val |= GLPMCFG_LPM_ACCEPT_CTRL_ISOC;
	dwc2_writel(hsotg, val, GLPMCFG);
	dev_dbg(hsotg->dev, "GLPMCFG=0x%08x\n", dwc2_readl(hsotg, GLPMCFG));

+1 −1
Original line number Diff line number Diff line
@@ -366,7 +366,7 @@ struct dwc2_qh {
	u32 desc_list_sz;
	u32 *n_bytes;
	struct timer_list unreserve_timer;
	struct timer_list wait_timer;
	struct hrtimer wait_timer;
	struct dwc2_tt *dwc_tt;
	int ttport;
	unsigned tt_buffer_dirty:1;
+12 −7
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@
#define DWC2_UNRESERVE_DELAY (msecs_to_jiffies(5))

/* If we get a NAK, wait this long before retrying */
#define DWC2_RETRY_WAIT_DELAY (msecs_to_jiffies(1))
#define DWC2_RETRY_WAIT_DELAY 1*1E6L

/**
 * dwc2_periodic_channel_available() - Checks that a channel is available for a
@@ -1464,10 +1464,12 @@ static void dwc2_deschedule_periodic(struct dwc2_hsotg *hsotg,
 * qh back to the "inactive" list, then queues transactions.
 *
 * @t: Pointer to wait_timer in a qh.
 *
 * Return: HRTIMER_NORESTART to not automatically restart this timer.
 */
static void dwc2_wait_timer_fn(struct timer_list *t)
static enum hrtimer_restart dwc2_wait_timer_fn(struct hrtimer *t)
{
	struct dwc2_qh *qh = from_timer(qh, t, wait_timer);
	struct dwc2_qh *qh = container_of(t, struct dwc2_qh, wait_timer);
	struct dwc2_hsotg *hsotg = qh->hsotg;
	unsigned long flags;

@@ -1491,6 +1493,7 @@ static void dwc2_wait_timer_fn(struct timer_list *t)
	}

	spin_unlock_irqrestore(&hsotg->lock, flags);
	return HRTIMER_NORESTART;
}

/**
@@ -1521,7 +1524,8 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
	/* Initialize QH */
	qh->hsotg = hsotg;
	timer_setup(&qh->unreserve_timer, dwc2_unreserve_timer_fn, 0);
	timer_setup(&qh->wait_timer, dwc2_wait_timer_fn, 0);
	hrtimer_init(&qh->wait_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	qh->wait_timer.function = &dwc2_wait_timer_fn;
	qh->ep_type = ep_type;
	qh->ep_is_in = ep_is_in;

@@ -1690,7 +1694,7 @@ void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
	 * won't do anything anyway, but we want it to finish before we free
	 * memory.
	 */
	del_timer_sync(&qh->wait_timer);
	hrtimer_cancel(&qh->wait_timer);

	dwc2_host_put_tt_info(hsotg, qh->dwc_tt);

@@ -1716,6 +1720,7 @@ int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
{
	int status;
	u32 intr_mask;
	ktime_t delay;

	if (dbg_qh(qh))
		dev_vdbg(hsotg->dev, "%s()\n", __func__);
@@ -1734,8 +1739,8 @@ int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
			list_add_tail(&qh->qh_list_entry,
				      &hsotg->non_periodic_sched_waiting);
			qh->wait_timer_cancel = false;
			mod_timer(&qh->wait_timer,
				  jiffies + DWC2_RETRY_WAIT_DELAY + 1);
			delay = ktime_set(0, DWC2_RETRY_WAIT_DELAY);
			hrtimer_start(&qh->wait_timer, delay, HRTIMER_MODE_REL);
		} else {
			list_add_tail(&qh->qh_list_entry,
				      &hsotg->non_periodic_sched_inactive);
+2 −0
Original line number Diff line number Diff line
@@ -333,6 +333,8 @@
#define GLPMCFG_SNDLPM			BIT(24)
#define GLPMCFG_RETRY_CNT_MASK		(0x7 << 21)
#define GLPMCFG_RETRY_CNT_SHIFT		21
#define GLPMCFG_LPM_ACCEPT_CTRL_CONTROL	BIT(21)
#define GLPMCFG_LPM_ACCEPT_CTRL_ISOC	BIT(22)
#define GLPMCFG_LPM_CHNL_INDX_MASK	(0xf << 17)
#define GLPMCFG_LPM_CHNL_INDX_SHIFT	17
#define GLPMCFG_L1RESUMEOK		BIT(16)
Loading