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

Commit c499ff71 authored by Felipe Balbi's avatar Felipe Balbi
Browse files

usb: dwc3: core: re-factor init and exit paths



The idea of this patch is for dwc3_core_init() to
abstract all the details about how to initialize
dwc3 and dwc3_core_exit() to do the same for
teardown.

With this, we can simplify suspend/resume operations
by a large margin and always know that we're going
to start dwc3 from a known starting point.

Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent bcdb3272
Loading
Loading
Loading
Loading
+60 −58
Original line number Diff line number Diff line
@@ -506,6 +506,21 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
	return 0;
}

static void dwc3_core_exit(struct dwc3 *dwc)
{
	dwc3_event_buffers_cleanup(dwc);

	usb_phy_shutdown(dwc->usb2_phy);
	usb_phy_shutdown(dwc->usb3_phy);
	phy_exit(dwc->usb2_generic_phy);
	phy_exit(dwc->usb3_generic_phy);

	usb_phy_set_suspend(dwc->usb2_phy, 1);
	usb_phy_set_suspend(dwc->usb3_phy, 1);
	phy_power_off(dwc->usb2_generic_phy);
	phy_power_off(dwc->usb3_generic_phy);
}

/**
 * dwc3_core_init - Low-level initialization of DWC3 Core
 * @dwc: Pointer to our controller context structure
@@ -555,6 +570,10 @@ static int dwc3_core_init(struct dwc3 *dwc)
	if (ret)
		goto err0;

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

	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
	reg &= ~DWC3_GCTL_SCALEDOWN_MASK;

@@ -621,22 +640,45 @@ static int dwc3_core_init(struct dwc3 *dwc)
	if (dwc->revision < DWC3_REVISION_190A)
		reg |= DWC3_GCTL_U2RSTECN;

	dwc3_core_num_eps(dwc);

	dwc3_writel(dwc->regs, DWC3_GCTL, reg);

	ret = dwc3_alloc_scratch_buffers(dwc);
	if (ret)
		goto err1;
	dwc3_core_num_eps(dwc);

	ret = dwc3_setup_scratch_buffers(dwc);
	if (ret)
		goto err1;

	/* Adjust Frame Length */
	dwc3_frame_length_adjustment(dwc);

	usb_phy_set_suspend(dwc->usb2_phy, 0);
	usb_phy_set_suspend(dwc->usb3_phy, 0);
	ret = phy_power_on(dwc->usb2_generic_phy);
	if (ret < 0)
		goto err2;

	ret = phy_power_on(dwc->usb3_generic_phy);
	if (ret < 0)
		goto err3;

	ret = dwc3_event_buffers_setup(dwc);
	if (ret) {
		dev_err(dwc->dev, "failed to setup event buffers\n");
		goto err4;
	}

	return 0;

err4:
	phy_power_off(dwc->usb2_generic_phy);

err3:
	phy_power_off(dwc->usb3_generic_phy);

err2:
	dwc3_free_scratch_buffers(dwc);
	usb_phy_set_suspend(dwc->usb2_phy, 1);
	usb_phy_set_suspend(dwc->usb3_phy, 1);
	dwc3_core_exit(dwc);

err1:
	usb_phy_shutdown(dwc->usb2_phy);
@@ -648,15 +690,6 @@ static int dwc3_core_init(struct dwc3 *dwc)
	return ret;
}

static void dwc3_core_exit(struct dwc3 *dwc)
{
	dwc3_free_scratch_buffers(dwc);
	usb_phy_shutdown(dwc->usb2_phy);
	usb_phy_shutdown(dwc->usb3_phy);
	phy_exit(dwc->usb2_generic_phy);
	phy_exit(dwc->usb3_generic_phy);
}

static int dwc3_core_get_phy(struct dwc3 *dwc)
{
	struct device		*dev = dwc->dev;
@@ -951,10 +984,6 @@ static int dwc3_probe(struct platform_device *pdev)
	platform_set_drvdata(pdev, dwc);
	dwc3_cache_hwparams(dwc);

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

	ret = dwc3_core_get_phy(dwc);
	if (ret)
		goto err0;
@@ -975,7 +1004,7 @@ static int dwc3_probe(struct platform_device *pdev)
	if (ret) {
		dev_err(dwc->dev, "failed to allocate event buffers\n");
		ret = -ENOMEM;
		goto err1;
		goto err0;
	}

	if (IS_ENABLED(CONFIG_USB_DWC3_HOST))
@@ -986,10 +1015,14 @@ static int dwc3_probe(struct platform_device *pdev)
	if (dwc->dr_mode == USB_DR_MODE_UNKNOWN)
		dwc->dr_mode = USB_DR_MODE_OTG;

	ret = dwc3_alloc_scratch_buffers(dwc);
	if (ret)
		goto err1;

	ret = dwc3_core_init(dwc);
	if (ret) {
		dev_err(dev, "failed to initialize core\n");
		goto err1;
		goto err2;
	}

	/* Check the maximum_speed parameter */
@@ -1019,47 +1052,20 @@ static int dwc3_probe(struct platform_device *pdev)
		break;
	}

	/* Adjust Frame Length */
	dwc3_frame_length_adjustment(dwc);

	usb_phy_set_suspend(dwc->usb2_phy, 0);
	usb_phy_set_suspend(dwc->usb3_phy, 0);
	ret = phy_power_on(dwc->usb2_generic_phy);
	if (ret < 0)
		goto err2;

	ret = phy_power_on(dwc->usb3_generic_phy);
	if (ret < 0)
		goto err3;

	ret = dwc3_event_buffers_setup(dwc);
	if (ret) {
		dev_err(dwc->dev, "failed to setup event buffers\n");
		goto err4;
	}

	ret = dwc3_core_init_mode(dwc);
	if (ret)
		goto err5;
		goto err3;

	dwc3_debugfs_init(dwc);
	pm_runtime_allow(dev);

	return 0;

err5:
	dwc3_event_buffers_cleanup(dwc);

err4:
	phy_power_off(dwc->usb3_generic_phy);

err3:
	phy_power_off(dwc->usb2_generic_phy);
	dwc3_event_buffers_cleanup(dwc);

err2:
	usb_phy_set_suspend(dwc->usb2_phy, 1);
	usb_phy_set_suspend(dwc->usb3_phy, 1);
	dwc3_core_exit(dwc);
	dwc3_free_scratch_buffers(dwc);

err1:
	dwc3_free_event_buffers(dwc);
@@ -1090,17 +1096,13 @@ static int dwc3_remove(struct platform_device *pdev)

	dwc3_debugfs_exit(dwc);
	dwc3_core_exit_mode(dwc);
	dwc3_event_buffers_cleanup(dwc);
	dwc3_free_event_buffers(dwc);

	usb_phy_set_suspend(dwc->usb2_phy, 1);
	usb_phy_set_suspend(dwc->usb3_phy, 1);
	phy_power_off(dwc->usb2_generic_phy);
	phy_power_off(dwc->usb3_generic_phy);

	dwc3_core_exit(dwc);
	dwc3_ulpi_exit(dwc);

	dwc3_free_event_buffers(dwc);
	dwc3_free_scratch_buffers(dwc);

	pm_runtime_put_sync(&pdev->dev);
	pm_runtime_disable(&pdev->dev);