drivers/usb/cdns3/core.c

Source file repositories/reference/linux-study-clean/drivers/usb/cdns3/core.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/cdns3/core.c
Extension
.c
Size
12553 bytes
Lines
581
Domain
Driver Families
Bucket
drivers/usb
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (cdns->version == CDNSP_CONTROLLER_V2) {
			if (IS_ENABLED(CONFIG_USB_CDNSP_HOST) &&
			    IS_ENABLED(CONFIG_USB_CDNSP_GADGET))
				dr_mode = USB_DR_MODE_OTG;
			else if (IS_ENABLED(CONFIG_USB_CDNSP_HOST))
				dr_mode = USB_DR_MODE_HOST;
			else if (IS_ENABLED(CONFIG_USB_CDNSP_GADGET))
				dr_mode = USB_DR_MODE_PERIPHERAL;
		} else {
			if (IS_ENABLED(CONFIG_USB_CDNS3_HOST) &&
			    IS_ENABLED(CONFIG_USB_CDNS3_GADGET))
				dr_mode = USB_DR_MODE_OTG;
			else if (IS_ENABLED(CONFIG_USB_CDNS3_HOST))
				dr_mode = USB_DR_MODE_HOST;
			else if (IS_ENABLED(CONFIG_USB_CDNS3_GADGET))
				dr_mode = USB_DR_MODE_PERIPHERAL;
		}
	}

	/*
	 * At this point cdns->dr_mode contains strap configuration.
	 * Driver try update this setting considering kernel configuration
	 */
	best_dr_mode = cdns->dr_mode;

	ret = cdns_idle_init(cdns);
	if (ret)
		return ret;

	if (dr_mode == USB_DR_MODE_OTG) {
		best_dr_mode = cdns->dr_mode;
	} else if (cdns->dr_mode == USB_DR_MODE_OTG) {
		best_dr_mode = dr_mode;
	} else if (cdns->dr_mode != dr_mode) {
		dev_err(dev, "Incorrect DRD configuration\n");
		return -EINVAL;
	}

	dr_mode = best_dr_mode;

	if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
		if ((cdns->version == CDNSP_CONTROLLER_V2 &&
		     IS_ENABLED(CONFIG_USB_CDNSP_HOST)) ||
		    (cdns->version < CDNSP_CONTROLLER_V2 &&
		     IS_ENABLED(CONFIG_USB_CDNS3_HOST)))
			ret = cdns_host_init(cdns);
		else
			ret = -ENXIO;

		if (ret) {
			dev_err(dev, "Host initialization failed with %d\n",
				ret);
			goto err;
		}
	}

	if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) {
		if (cdns->gadget_init)
			ret = cdns->gadget_init(cdns);
		else
			ret = -ENXIO;

		if (ret) {
			dev_err(dev, "Device initialization failed with %d\n",
				ret);
			goto err;
		}
	}

	cdns->dr_mode = dr_mode;

	ret = cdns_drd_update_mode(cdns);
	if (ret)
		goto err;

	/* Initialize idle role to start with */
	ret = cdns_role_start(cdns, USB_ROLE_NONE);
	if (ret)
		goto err;

	switch (cdns->dr_mode) {
	case USB_DR_MODE_OTG:
		ret = cdns_hw_role_switch(cdns);
		if (ret)
			goto err;
		break;
	case USB_DR_MODE_PERIPHERAL:
		ret = cdns_role_start(cdns, USB_ROLE_DEVICE);
		if (ret)
			goto err;

Annotation

Implementation Notes