drivers/usb/gadget/udc/bdc/bdc_core.c

Source file repositories/reference/linux-study-clean/drivers/usb/gadget/udc/bdc/bdc_core.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/gadget/udc/bdc/bdc_core.c
Extension
.c
Size
15498 bytes
Lines
657
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 (ret) {
			phy_exit(bdc->phys[phy_num]);
			goto err_exit_phy;
		}
	}

	return 0;

err_exit_phy:
	while (--phy_num >= 0) {
		phy_power_off(bdc->phys[phy_num]);
		phy_exit(bdc->phys[phy_num]);
	}

	return ret;
}

static void bdc_phy_exit(struct bdc *bdc)
{
	int phy_num;

	for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) {
		phy_power_off(bdc->phys[phy_num]);
		phy_exit(bdc->phys[phy_num]);
	}
}

static int bdc_probe(struct platform_device *pdev)
{
	struct bdc *bdc;
	int ret;
	int irq;
	u32 temp;
	struct device *dev = &pdev->dev;
	int phy_num;

	dev_dbg(dev, "%s()\n", __func__);

	bdc = devm_kzalloc(dev, sizeof(*bdc), GFP_KERNEL);
	if (!bdc)
		return -ENOMEM;

	bdc->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(bdc->regs))
		return PTR_ERR(bdc->regs);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;
	spin_lock_init(&bdc->lock);
	platform_set_drvdata(pdev, bdc);
	bdc->irq = irq;
	bdc->dev = dev;
	dev_dbg(dev, "bdc->regs: %p irq=%d\n", bdc->regs, bdc->irq);

	bdc->num_phys = of_count_phandle_with_args(dev->of_node,
						"phys", "#phy-cells");
	if (bdc->num_phys > 0) {
		bdc->phys = devm_kcalloc(dev, bdc->num_phys,
					sizeof(struct phy *), GFP_KERNEL);
		if (!bdc->phys)
			return -ENOMEM;
	} else {
		bdc->num_phys = 0;
	}
	dev_info(dev, "Using %d phy(s)\n", bdc->num_phys);

	for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) {
		bdc->phys[phy_num] = devm_of_phy_get_by_index(
			dev, dev->of_node, phy_num);
		if (IS_ERR(bdc->phys[phy_num])) {
			ret = PTR_ERR(bdc->phys[phy_num]);
			dev_err(bdc->dev,
				"BDC phy specified but not found:%d\n", ret);
			return ret;
		}
	}

	bdc->clk = devm_clk_get_optional(dev, "sw_usbd");
	if (IS_ERR(bdc->clk))
		return PTR_ERR(bdc->clk);

	ret = clk_prepare_enable(bdc->clk);
	if (ret) {
		dev_err(dev, "could not enable clock\n");
		return ret;
	}

	ret = bdc_phy_init(bdc);
	if (ret) {

Annotation

Implementation Notes