Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

Merge tag 'fixes-for-v4.16-rc2' of...

Merge tag 'fixes-for-v4.16-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus

Felipe writes:

usb: fixes for v4.16-rc2

First set of fixes for current -rc cycle. Most of the changes are on
dwc3 this time around (59%) with some function changes (25%).

Out of the those, the most important fixes are:

- EP0 TRB counter fix on dwc3
- dwc3-omap stopped missing events during suspend/resume
- maxpacket size fix for ep0 in dwc3
- Descriptor processing fix for functionfs

Apart from these, your usual set of important-but-not-so-critical
fixes all over the place.
parents b86b8eb6 98112041
Loading
Loading
Loading
Loading
+16 −10
Original line number Diff line number Diff line
@@ -1917,7 +1917,9 @@ static void dwc2_hsotg_program_zlp(struct dwc2_hsotg *hsotg,
		/* Not specific buffer needed for ep0 ZLP */
		dma_addr_t dma = hs_ep->desc_list_dma;

		if (!index)
			dwc2_gadget_set_ep0_desc_chain(hsotg, hs_ep);

		dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, dma, 0);
	} else {
		dwc2_writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) |
@@ -2974,11 +2976,15 @@ static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
	if (ints & DXEPINT_STSPHSERCVD) {
		dev_dbg(hsotg->dev, "%s: StsPhseRcvd\n", __func__);

		/* Safety check EP0 state when STSPHSERCVD asserted */
		if (hsotg->ep0_state == DWC2_EP0_DATA_OUT) {
			/* Move to STATUS IN for DDMA */
			if (using_desc_dma(hsotg))
				dwc2_hsotg_ep0_zlp(hsotg, true);
		}

	}

	if (ints & DXEPINT_BACK2BACKSETUP)
		dev_dbg(hsotg->dev, "%s: B2BSetup/INEPNakEff\n", __func__);

@@ -3375,12 +3381,6 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
	dwc2_writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) |
	       DXEPCTL_USBACTEP, hsotg->regs + DIEPCTL0);

	dwc2_hsotg_enqueue_setup(hsotg);

	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
		dwc2_readl(hsotg->regs + DIEPCTL0),
		dwc2_readl(hsotg->regs + DOEPCTL0));

	/* clear global NAKs */
	val = DCTL_CGOUTNAK | DCTL_CGNPINNAK;
	if (!is_usb_reset)
@@ -3391,6 +3391,12 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
	mdelay(3);

	hsotg->lx_state = DWC2_L0;

	dwc2_hsotg_enqueue_setup(hsotg);

	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
		dwc2_readl(hsotg->regs + DIEPCTL0),
		dwc2_readl(hsotg->regs + DOEPCTL0));
}

static void dwc2_hsotg_core_disconnect(struct dwc2_hsotg *hsotg)
+61 −25
Original line number Diff line number Diff line
@@ -100,6 +100,8 @@ static void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
	reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
	reg |= DWC3_GCTL_PRTCAPDIR(mode);
	dwc3_writel(dwc->regs, DWC3_GCTL, reg);

	dwc->current_dr_role = mode;
}

static void __dwc3_set_mode(struct work_struct *work)
@@ -133,8 +135,6 @@ static void __dwc3_set_mode(struct work_struct *work)

	dwc3_set_prtcap(dwc, dwc->desired_dr_role);

	dwc->current_dr_role = dwc->desired_dr_role;

	spin_unlock_irqrestore(&dwc->lock, flags);

	switch (dwc->desired_dr_role) {
@@ -219,7 +219,7 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
	 * XHCI driver will reset the host block. If dwc3 was configured for
	 * host-only mode, then we can return early.
	 */
	if (dwc->dr_mode == USB_DR_MODE_HOST)
	if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST)
		return 0;

	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
@@ -234,6 +234,9 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
		udelay(1);
	} while (--retries);

	phy_exit(dwc->usb3_generic_phy);
	phy_exit(dwc->usb2_generic_phy);

	return -ETIMEDOUT;
}

@@ -483,6 +486,22 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
	parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
}

static int dwc3_core_ulpi_init(struct dwc3 *dwc)
{
	int intf;
	int ret = 0;

	intf = DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3);

	if (intf == DWC3_GHWPARAMS3_HSPHY_IFC_ULPI ||
	    (intf == DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI &&
	     dwc->hsphy_interface &&
	     !strncmp(dwc->hsphy_interface, "ulpi", 4)))
		ret = dwc3_ulpi_init(dwc);

	return ret;
}

/**
 * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
 * @dwc: Pointer to our controller context structure
@@ -494,7 +513,6 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
static int dwc3_phy_setup(struct dwc3 *dwc)
{
	u32 reg;
	int ret;

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

@@ -565,9 +583,6 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
		}
		/* FALLTHROUGH */
	case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
		ret = dwc3_ulpi_init(dwc);
		if (ret)
			return ret;
		/* FALLTHROUGH */
	default:
		break;
@@ -724,6 +739,7 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc)
}

static int dwc3_core_get_phy(struct dwc3 *dwc);
static int dwc3_core_ulpi_init(struct dwc3 *dwc);

/**
 * dwc3_core_init - Low-level initialization of DWC3 Core
@@ -755,17 +771,27 @@ static int dwc3_core_init(struct dwc3 *dwc)
			dwc->maximum_speed = USB_SPEED_HIGH;
	}

	ret = dwc3_core_get_phy(dwc);
	ret = dwc3_phy_setup(dwc);
	if (ret)
		goto err0;

	ret = dwc3_core_soft_reset(dwc);
	if (!dwc->ulpi_ready) {
		ret = dwc3_core_ulpi_init(dwc);
		if (ret)
			goto err0;
		dwc->ulpi_ready = true;
	}

	ret = dwc3_phy_setup(dwc);
	if (!dwc->phys_ready) {
		ret = dwc3_core_get_phy(dwc);
		if (ret)
		goto err0;
			goto err0a;
		dwc->phys_ready = true;
	}

	ret = dwc3_core_soft_reset(dwc);
	if (ret)
		goto err0a;

	dwc3_core_setup_global_control(dwc);
	dwc3_core_num_eps(dwc);
@@ -838,6 +864,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
	phy_exit(dwc->usb2_generic_phy);
	phy_exit(dwc->usb3_generic_phy);

err0a:
	dwc3_ulpi_exit(dwc);

err0:
	return ret;
}
@@ -916,7 +945,6 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)

	switch (dwc->dr_mode) {
	case USB_DR_MODE_PERIPHERAL:
		dwc->current_dr_role = DWC3_GCTL_PRTCAP_DEVICE;
		dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE);

		if (dwc->usb2_phy)
@@ -932,7 +960,6 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
		}
		break;
	case USB_DR_MODE_HOST:
		dwc->current_dr_role = DWC3_GCTL_PRTCAP_HOST;
		dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);

		if (dwc->usb2_phy)
@@ -1234,7 +1261,6 @@ static int dwc3_probe(struct platform_device *pdev)

err3:
	dwc3_free_event_buffers(dwc);
	dwc3_ulpi_exit(dwc);

err2:
	pm_runtime_allow(&pdev->dev);
@@ -1284,7 +1310,7 @@ static int dwc3_remove(struct platform_device *pdev)
}

#ifdef CONFIG_PM
static int dwc3_suspend_common(struct dwc3 *dwc)
static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
{
	unsigned long	flags;

@@ -1296,6 +1322,10 @@ static int dwc3_suspend_common(struct dwc3 *dwc)
		dwc3_core_exit(dwc);
		break;
	case DWC3_GCTL_PRTCAP_HOST:
		/* do nothing during host runtime_suspend */
		if (!PMSG_IS_AUTO(msg))
			dwc3_core_exit(dwc);
		break;
	default:
		/* do nothing */
		break;
@@ -1304,7 +1334,7 @@ static int dwc3_suspend_common(struct dwc3 *dwc)
	return 0;
}

static int dwc3_resume_common(struct dwc3 *dwc)
static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
{
	unsigned long	flags;
	int		ret;
@@ -1320,6 +1350,13 @@ static int dwc3_resume_common(struct dwc3 *dwc)
		spin_unlock_irqrestore(&dwc->lock, flags);
		break;
	case DWC3_GCTL_PRTCAP_HOST:
		/* nothing to do on host runtime_resume */
		if (!PMSG_IS_AUTO(msg)) {
			ret = dwc3_core_init(dwc);
			if (ret)
				return ret;
		}
		break;
	default:
		/* do nothing */
		break;
@@ -1331,12 +1368,11 @@ static int dwc3_resume_common(struct dwc3 *dwc)
static int dwc3_runtime_checks(struct dwc3 *dwc)
{
	switch (dwc->current_dr_role) {
	case USB_DR_MODE_PERIPHERAL:
	case USB_DR_MODE_OTG:
	case DWC3_GCTL_PRTCAP_DEVICE:
		if (dwc->connected)
			return -EBUSY;
		break;
	case USB_DR_MODE_HOST:
	case DWC3_GCTL_PRTCAP_HOST:
	default:
		/* do nothing */
		break;
@@ -1353,7 +1389,7 @@ static int dwc3_runtime_suspend(struct device *dev)
	if (dwc3_runtime_checks(dwc))
		return -EBUSY;

	ret = dwc3_suspend_common(dwc);
	ret = dwc3_suspend_common(dwc, PMSG_AUTO_SUSPEND);
	if (ret)
		return ret;

@@ -1369,7 +1405,7 @@ static int dwc3_runtime_resume(struct device *dev)

	device_init_wakeup(dev, false);

	ret = dwc3_resume_common(dwc);
	ret = dwc3_resume_common(dwc, PMSG_AUTO_RESUME);
	if (ret)
		return ret;

@@ -1416,7 +1452,7 @@ static int dwc3_suspend(struct device *dev)
	struct dwc3	*dwc = dev_get_drvdata(dev);
	int		ret;

	ret = dwc3_suspend_common(dwc);
	ret = dwc3_suspend_common(dwc, PMSG_SUSPEND);
	if (ret)
		return ret;

@@ -1432,7 +1468,7 @@ static int dwc3_resume(struct device *dev)

	pinctrl_pm_select_default_state(dev);

	ret = dwc3_resume_common(dwc);
	ret = dwc3_resume_common(dwc, PMSG_RESUME);
	if (ret)
		return ret;

+14 −7
Original line number Diff line number Diff line
@@ -158,13 +158,15 @@
#define DWC3_GDBGFIFOSPACE_TYPE(n)	(((n) << 5) & 0x1e0)
#define DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(n) (((n) >> 16) & 0xffff)

#define DWC3_TXFIFOQ		1
#define DWC3_RXFIFOQ		3
#define DWC3_TXREQQ		5
#define DWC3_RXREQQ		7
#define DWC3_RXINFOQ		9
#define DWC3_DESCFETCHQ		13
#define DWC3_EVENTQ		15
#define DWC3_TXFIFOQ		0
#define DWC3_RXFIFOQ		1
#define DWC3_TXREQQ		2
#define DWC3_RXREQQ		3
#define DWC3_RXINFOQ		4
#define DWC3_PSTATQ		5
#define DWC3_DESCFETCHQ		6
#define DWC3_EVENTQ		7
#define DWC3_AUXEVENTQ		8

/* Global RX Threshold Configuration Register */
#define DWC3_GRXTHRCFG_MAXRXBURSTSIZE(n) (((n) & 0x1f) << 19)
@@ -795,7 +797,9 @@ struct dwc3_scratchpad_array {
 * @usb3_phy: pointer to USB3 PHY
 * @usb2_generic_phy: pointer to USB2 PHY
 * @usb3_generic_phy: pointer to USB3 PHY
 * @phys_ready: flag to indicate that PHYs are ready
 * @ulpi: pointer to ulpi interface
 * @ulpi_ready: flag to indicate that ULPI is initialized
 * @u2sel: parameter from Set SEL request.
 * @u2pel: parameter from Set SEL request.
 * @u1sel: parameter from Set SEL request.
@@ -893,7 +897,10 @@ struct dwc3 {
	struct phy		*usb2_generic_phy;
	struct phy		*usb3_generic_phy;

	bool			phys_ready;

	struct ulpi		*ulpi;
	bool			ulpi_ready;

	void __iomem		*regs;
	size_t			regs_size;
+1 −0
Original line number Diff line number Diff line
@@ -143,6 +143,7 @@ static int dwc3_of_simple_remove(struct platform_device *pdev)
		clk_disable_unprepare(simple->clks[i]);
		clk_put(simple->clks[i]);
	}
	simple->num_clocks = 0;

	reset_control_assert(simple->resets);
	reset_control_put(simple->resets);
+16 −0
Original line number Diff line number Diff line
@@ -582,9 +582,25 @@ static int dwc3_omap_resume(struct device *dev)
	return 0;
}

static void dwc3_omap_complete(struct device *dev)
{
	struct dwc3_omap	*omap = dev_get_drvdata(dev);

	if (extcon_get_state(omap->edev, EXTCON_USB))
		dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
	else
		dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF);

	if (extcon_get_state(omap->edev, EXTCON_USB_HOST))
		dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
	else
		dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT);
}

static const struct dev_pm_ops dwc3_omap_dev_pm_ops = {

	SET_SYSTEM_SLEEP_PM_OPS(dwc3_omap_suspend, dwc3_omap_resume)
	.complete = dwc3_omap_complete,
};

#define DEV_PM_OPS	(&dwc3_omap_dev_pm_ops)
Loading