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

Commit 9f8a67b6 authored by Felipe Balbi's avatar Felipe Balbi
Browse files

usb: dwc3: gadget: fix gadget suspend/resume



Instead of trying hard to stay connected to the
host, it's best (and far easier) to disconnect from
the host already.

Anything relying on KEEP_CONNECT will just have that
ignored, but we don't have proper hibernation
implementation yet, so there are no regressions.

In any case, hibernation is only useful for runtime
PM, not system sleep.

While at that, also remove dwc3.dcfg which has been
rendered unnecessary.

Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent d7be2952
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -819,7 +819,6 @@ struct dwc3 {
	enum usb_dr_mode	dr_mode;

	/* used for suspend/resume */
	u32			dcfg;
	u32			gctl;

	u32			nr_scratch;
+12 −32
Original line number Diff line number Diff line
@@ -2943,60 +2943,40 @@ void dwc3_gadget_exit(struct dwc3 *dwc)

int dwc3_gadget_suspend(struct dwc3 *dwc)
{
	int ret;

	if (!dwc->gadget_driver)
		return 0;

	if (dwc->pullups_connected) {
		dwc3_gadget_disable_irq(dwc);
		dwc3_gadget_run_stop(dwc, true, true);
	}

	__dwc3_gadget_ep_disable(dwc->eps[0]);
	__dwc3_gadget_ep_disable(dwc->eps[1]);
	ret = dwc3_gadget_run_stop(dwc, false, false);
	if (ret < 0)
		return ret;

	dwc->dcfg = dwc3_readl(dwc->regs, DWC3_DCFG);
	dwc3_disconnect_gadget(dwc);
	__dwc3_gadget_stop(dwc);

	return 0;
}

int dwc3_gadget_resume(struct dwc3 *dwc)
{
	struct dwc3_ep		*dep;
	int			ret;

	if (!dwc->gadget_driver)
		return 0;

	/* Start with SuperSpeed Default */
	dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);

	dep = dwc->eps[0];
	ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false,
			false);
	if (ret)
	ret = __dwc3_gadget_start(dwc);
	if (ret < 0)
		goto err0;

	dep = dwc->eps[1];
	ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false,
			false);
	if (ret)
	ret = dwc3_gadget_run_stop(dwc, true, false);
	if (ret < 0)
		goto err1;

	/* begin to receive SETUP packets */
	dwc->ep0state = EP0_SETUP_PHASE;
	dwc3_ep0_out_start(dwc);

	dwc3_writel(dwc->regs, DWC3_DCFG, dwc->dcfg);

	if (dwc->pullups_connected) {
		dwc3_gadget_enable_irq(dwc);
		dwc3_gadget_run_stop(dwc, true, false);
	}

	return 0;

err1:
	__dwc3_gadget_ep_disable(dwc->eps[0]);
	__dwc3_gadget_stop(dwc);

err0:
	return ret;