drivers/usb/host/fsl-mph-dr-of.c

Source file repositories/reference/linux-study-clean/drivers/usb/host/fsl-mph-dr-of.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/host/fsl-mph-dr-of.c
Extension
.c
Size
10110 bytes
Lines
372
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

struct fsl_usb2_dev_data {
	char *dr_mode;		/* controller mode */
	char *drivers[3];	/* drivers to instantiate for this mode */
	enum fsl_usb2_operating_modes op_mode;	/* operating mode */
};

static struct fsl_usb2_dev_data dr_mode_data[] = {
	{
		.dr_mode = "host",
		.drivers = { "fsl-ehci", NULL, NULL, },
		.op_mode = FSL_USB2_DR_HOST,
	},
	{
		.dr_mode = "otg",
		.drivers = { "fsl-usb2-otg", "fsl-ehci", "fsl-usb2-udc", },
		.op_mode = FSL_USB2_DR_OTG,
	},
	{
		.dr_mode = "peripheral",
		.drivers = { "fsl-usb2-udc", NULL, NULL, },
		.op_mode = FSL_USB2_DR_DEVICE,
	},
};

static struct fsl_usb2_dev_data *get_dr_mode_data(struct device_node *np)
{
	const unsigned char *prop;
	int i;

	prop = of_get_property(np, "dr_mode", NULL);
	if (prop) {
		for (i = 0; i < ARRAY_SIZE(dr_mode_data); i++) {
			if (!strcmp(prop, dr_mode_data[i].dr_mode))
				return &dr_mode_data[i];
		}
	}
	pr_warn("%pOF: Invalid 'dr_mode' property, fallback to host mode\n",
		np);
	return &dr_mode_data[0]; /* mode not specified, use host */
}

static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
{
	if (!phy_type)
		return FSL_USB2_PHY_NONE;
	if (!strcasecmp(phy_type, "ulpi"))
		return FSL_USB2_PHY_ULPI;
	if (!strcasecmp(phy_type, "utmi"))
		return FSL_USB2_PHY_UTMI;
	if (!strcasecmp(phy_type, "utmi_wide"))
		return FSL_USB2_PHY_UTMI_WIDE;
	if (!strcasecmp(phy_type, "utmi_dual"))
		return FSL_USB2_PHY_UTMI_DUAL;
	if (!strcasecmp(phy_type, "serial"))
		return FSL_USB2_PHY_SERIAL;

	return FSL_USB2_PHY_NONE;
}

static struct platform_device *fsl_usb2_device_register(
					struct platform_device *ofdev,
					struct fsl_usb2_platform_data *pdata,
					const char *name, int id)
{
	struct platform_device *pdev;
	const struct resource *res = ofdev->resource;
	unsigned int num = ofdev->num_resources;
	int retval;

	pdev = platform_device_alloc(name, id);
	if (!pdev) {
		retval = -ENOMEM;
		goto error;
	}

	pdev->dev.parent = &ofdev->dev;

	pdev->dev.coherent_dma_mask = ofdev->dev.coherent_dma_mask;

	if (!pdev->dev.dma_mask) {
		pdev->dev.dma_mask = &ofdev->dev.coherent_dma_mask;
	} else {
		retval = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
		if (retval)
			goto error;
	}

	retval = platform_device_add_data(pdev, pdata, sizeof(*pdata));
	if (retval)
		goto error;

Annotation

Implementation Notes