drivers/usb/host/fhci-hcd.c

Source file repositories/reference/linux-study-clean/drivers/usb/host/fhci-hcd.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/host/fhci-hcd.c
Extension
.c
Size
18510 bytes
Lines
795
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

while (ed->td_head != NULL) {
			struct td *td = fhci_remove_td_from_ed(ed);
			fhci_urb_complete_free(fhci, td->urb);
		}
		fhci_recycle_empty_ed(fhci, ed);
		ep->hcpriv = NULL;
	}
	spin_unlock_irqrestore(&fhci->lock, flags);
}

static int fhci_get_frame_number(struct usb_hcd *hcd)
{
	struct fhci_hcd *fhci = hcd_to_fhci(hcd);

	return get_frame_num(fhci);
}

static const struct hc_driver fhci_driver = {
	.description = "fsl,usb-fhci",
	.product_desc = "FHCI HOST Controller",
	.hcd_priv_size = sizeof(struct fhci_hcd),

	/* generic hardware linkage */
	.irq = fhci_irq,
	.flags = HCD_DMA | HCD_USB11 | HCD_MEMORY,

	/* basic lifecycle operation */
	.start = fhci_start,
	.stop = fhci_stop,

	/* managing i/o requests and associated device resources */
	.urb_enqueue = fhci_urb_enqueue,
	.urb_dequeue = fhci_urb_dequeue,
	.endpoint_disable = fhci_endpoint_disable,

	/* scheduling support */
	.get_frame_number = fhci_get_frame_number,

	/* root hub support */
	.hub_status_data = fhci_hub_status_data,
	.hub_control = fhci_hub_control,
};

static int of_fhci_probe(struct platform_device *ofdev)
{
	struct device *dev = &ofdev->dev;
	struct device_node *node = dev->of_node;
	struct usb_hcd *hcd;
	struct fhci_hcd *fhci;
	struct resource usb_regs;
	unsigned long pram_addr;
	unsigned int usb_irq;
	const char *sprop;
	const u32 *iprop;
	int size;
	int ret;
	int i;
	int j;

	if (usb_disabled())
		return -ENODEV;

	sprop = of_get_property(node, "mode", NULL);
	if (sprop && strcmp(sprop, "host"))
		return -ENODEV;

	hcd = usb_create_hcd(&fhci_driver, dev, dev_name(dev));
	if (!hcd) {
		dev_err(dev, "could not create hcd\n");
		return -ENOMEM;
	}

	fhci = hcd_to_fhci(hcd);
	hcd->self.controller = dev;
	dev_set_drvdata(dev, hcd);

	iprop = of_get_property(node, "hub-power-budget", &size);
	if (iprop && size == sizeof(*iprop))
		hcd->power_budget = *iprop;

	/* FHCI registers. */
	ret = of_address_to_resource(node, 0, &usb_regs);
	if (ret) {
		dev_err(dev, "could not get regs\n");
		goto err_regs;
	}

	hcd->regs = ioremap(usb_regs.start, resource_size(&usb_regs));
	if (!hcd->regs) {
		dev_err(dev, "could not ioremap regs\n");

Annotation

Implementation Notes