drivers/usb/dwc2/platform.c

Source file repositories/reference/linux-study-clean/drivers/usb/dwc2/platform.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/dwc2/platform.c
Extension
.c
Size
20762 bytes
Lines
812
Domain
Driver Families
Bucket
drivers/usb
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) {
			dev_err(hsotg->dev,
				"Controller does not support host mode.\n");
			return -EINVAL;
		}
		mode = USB_DR_MODE_PERIPHERAL;
	} else if (dwc2_hw_is_host(hsotg)) {
		if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL)) {
			dev_err(hsotg->dev,
				"Controller does not support device mode.\n");
			return -EINVAL;
		}
		mode = USB_DR_MODE_HOST;
	} else {
		if (IS_ENABLED(CONFIG_USB_DWC2_HOST))
			mode = USB_DR_MODE_HOST;
		else if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL))
			mode = USB_DR_MODE_PERIPHERAL;
	}

	if (mode != hsotg->dr_mode) {
		dev_warn(hsotg->dev,
			 "Configuration mismatch. dr_mode forced to %s\n",
			mode == USB_DR_MODE_HOST ? "host" : "device");

		hsotg->dr_mode = mode;
	}

	return 0;
}

static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
{
	struct platform_device *pdev = to_platform_device(hsotg->dev);
	int ret;

	ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
				    hsotg->supplies);
	if (ret)
		return ret;

	if (hsotg->utmi_clk) {
		ret = clk_prepare_enable(hsotg->utmi_clk);
		if (ret)
			goto err_dis_reg;
	}

	if (hsotg->clk) {
		ret = clk_prepare_enable(hsotg->clk);
		if (ret)
			goto err_dis_utmi_clk;
	}

	if (hsotg->uphy) {
		ret = usb_phy_init(hsotg->uphy);
	} else if (hsotg->plat && hsotg->plat->phy_init) {
		ret = hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
	} else {
		ret = phy_init(hsotg->phy);
		if (ret == 0) {
			ret = phy_power_on(hsotg->phy);
			if (ret)
				phy_exit(hsotg->phy);
		}
	}

	if (ret)
		goto err_dis_clk;

	return 0;

err_dis_clk:
	if (hsotg->clk)
		clk_disable_unprepare(hsotg->clk);

err_dis_utmi_clk:
	if (hsotg->utmi_clk)
		clk_disable_unprepare(hsotg->utmi_clk);

err_dis_reg:
	regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);

	return ret;
}

/**
 * dwc2_lowlevel_hw_enable - enable platform lowlevel hw resources
 * @hsotg: The driver state
 *
 * A wrapper for platform code responsible for controlling

Annotation

Implementation Notes