drivers/usb/core/phy.c

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

File Facts

System
Linux kernel
Corpus path
drivers/usb/core/phy.c
Extension
.c
Size
8541 bytes
Lines
372
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

struct usb_phy_roothub {
	struct phy		*phy;
	struct list_head	list;
};

/* Allocate the roothub_entry by specific name of phy */
static int usb_phy_roothub_add_phy_by_name(struct device *dev, const char *name,
					   struct list_head *list)
{
	struct usb_phy_roothub *roothub_entry;
	struct phy *phy;

	phy = devm_of_phy_get(dev, dev->of_node, name);
	if (IS_ERR(phy))
		return PTR_ERR(phy);

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

	INIT_LIST_HEAD(&roothub_entry->list);

	roothub_entry->phy = phy;

	list_add_tail(&roothub_entry->list, list);

	return 0;
}

static int usb_phy_roothub_add_phy(struct device *dev, int index,
				   struct list_head *list)
{
	struct usb_phy_roothub *roothub_entry;
	struct phy *phy;

	phy = devm_of_phy_get_by_index(dev, dev->of_node, index);
	if (IS_ERR(phy)) {
		if (PTR_ERR(phy) == -ENODEV)
			return 0;
		else
			return PTR_ERR(phy);
	}

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

	INIT_LIST_HEAD(&roothub_entry->list);

	roothub_entry->phy = phy;

	list_add_tail(&roothub_entry->list, list);

	return 0;
}

struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev)
{
	struct usb_phy_roothub *phy_roothub;
	int i, num_phys, err;

	if (!IS_ENABLED(CONFIG_GENERIC_PHY))
		return NULL;

	num_phys = of_count_phandle_with_args(dev->of_node, "phys",
					      "#phy-cells");
	if (num_phys <= 0)
		return NULL;

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

	INIT_LIST_HEAD(&phy_roothub->list);

	if (!usb_phy_roothub_add_phy_by_name(dev, "usb2-phy", &phy_roothub->list))
		return phy_roothub;

	for (i = 0; i < num_phys; i++) {
		err = usb_phy_roothub_add_phy(dev, i, &phy_roothub->list);
		if (err)
			return ERR_PTR(err);
	}

	return phy_roothub;
}
EXPORT_SYMBOL_GPL(usb_phy_roothub_alloc);

/**
 * usb_phy_roothub_alloc_usb3_phy - alloc the roothub

Annotation

Implementation Notes