drivers/usb/gadget/udc/at91_udc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/usb/gadget/udc/at91_udc.c
Extension
.c
Size
50725 bytes
Lines
2022
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

else list_for_each_entry (req, &ep->queue, queue) {
		unsigned	length = req->req.actual;

		seq_printf(s, "\treq %p len %d/%d buf %p\n",
				&req->req, length,
				req->req.length, req->req.buf);
	}
	spin_unlock_irqrestore(&udc->lock, flags);
}

static void proc_irq_show(struct seq_file *s, const char *label, u32 mask)
{
	int i;

	seq_printf(s, "%s %04x:%s%s" FOURBITS, label, mask,
		(mask & (1 << 13)) ? " wakeup" : "",
		(mask & (1 << 12)) ? " endbusres" : "",

		(mask & (1 << 11)) ? " sofint" : "",
		(mask & (1 << 10)) ? " extrsm" : "",
		(mask & (1 << 9)) ? " rxrsm" : "",
		(mask & (1 << 8)) ? " rxsusp" : "");
	for (i = 0; i < 8; i++) {
		if (mask & (1 << i))
			seq_printf(s, " ep%d", i);
	}
	seq_printf(s, "\n");
}

static int proc_udc_show(struct seq_file *s, void *unused)
{
	struct at91_udc	*udc = s->private;
	struct at91_ep	*ep;
	u32		tmp;

	seq_printf(s, "%s: version %s\n", driver_name, DRIVER_VERSION);

	seq_printf(s, "vbus %s, pullup %s, %s powered%s, gadget %s\n\n",
		udc->vbus ? "present" : "off",
		udc->enabled
			? (udc->vbus ? "active" : "enabled")
			: "disabled",
		udc->gadget.is_selfpowered ? "self" : "VBUS",
		udc->suspended ? ", suspended" : "",
		udc->driver ? udc->driver->driver.name : "(none)");

	/* don't access registers when interface isn't clocked */
	if (!udc->clocked) {
		seq_printf(s, "(not clocked)\n");
		return 0;
	}

	tmp = at91_udp_read(udc, AT91_UDP_FRM_NUM);
	seq_printf(s, "frame %05x:%s%s frame=%d\n", tmp,
		(tmp & AT91_UDP_FRM_OK) ? " ok" : "",
		(tmp & AT91_UDP_FRM_ERR) ? " err" : "",
		(tmp & AT91_UDP_NUM));

	tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT);
	seq_printf(s, "glbstate %02x:%s" FOURBITS "\n", tmp,
		(tmp & AT91_UDP_RMWUPE) ? " rmwupe" : "",
		(tmp & AT91_UDP_RSMINPR) ? " rsminpr" : "",
		(tmp & AT91_UDP_ESR) ? " esr" : "",
		(tmp & AT91_UDP_CONFG) ? " confg" : "",
		(tmp & AT91_UDP_FADDEN) ? " fadden" : "");

	tmp = at91_udp_read(udc, AT91_UDP_FADDR);
	seq_printf(s, "faddr   %03x:%s fadd=%d\n", tmp,
		(tmp & AT91_UDP_FEN) ? " fen" : "",
		(tmp & AT91_UDP_FADD));

	proc_irq_show(s, "imr   ", at91_udp_read(udc, AT91_UDP_IMR));
	proc_irq_show(s, "isr   ", at91_udp_read(udc, AT91_UDP_ISR));

	if (udc->enabled && udc->vbus) {
		proc_ep_show(s, &udc->ep[0]);
		list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) {
			if (ep->ep.desc)
				proc_ep_show(s, ep);
		}
	}
	return 0;
}

static void create_debug_file(struct at91_udc *udc)
{
	udc->pde = proc_create_single_data(debug_filename, 0, NULL,
			proc_udc_show, udc);
}

Annotation

Implementation Notes