drivers/usb/phy/phy-fsl-usb.c

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

File Facts

System
Linux kernel
Corpus path
drivers/usb/phy/phy-fsl-usb.c
Extension
.c
Size
24365 bytes
Lines
1018
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 (tmp_timer == timer) {
		timer->count = timer->expires;
		return;
	}
	timer->count = timer->expires;
	list_add_tail(&timer->list, &active_timers);
}

static void fsl_otg_fsm_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer t)
{
	struct fsl_otg_timer *timer;

	timer = fsl_otg_get_timer(t);
	if (!timer)
		return;

	fsl_otg_add_timer(fsm, timer);
}

/* Remove timer from the timer list; clear timeout status */
void fsl_otg_del_timer(struct otg_fsm *fsm, void *gtimer)
{
	struct fsl_otg_timer *timer = gtimer;
	struct fsl_otg_timer *tmp_timer, *del_tmp;

	list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list)
		if (tmp_timer == timer)
			list_del(&timer->list);
}

static void fsl_otg_fsm_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer t)
{
	struct fsl_otg_timer *timer;

	timer = fsl_otg_get_timer(t);
	if (!timer)
		return;

	fsl_otg_del_timer(fsm, timer);
}

/* Reset controller, not reset the bus */
void otg_reset_controller(void)
{
	u32 command;

	command = fsl_readl(&usb_dr_regs->usbcmd);
	command |= (1 << 1);
	fsl_writel(command, &usb_dr_regs->usbcmd);
	while (fsl_readl(&usb_dr_regs->usbcmd) & (1 << 1))
		;
}

/* Call suspend/resume routines in host driver */
int fsl_otg_start_host(struct otg_fsm *fsm, int on)
{
	struct usb_otg *otg = fsm->otg;
	struct device *dev;
	struct fsl_otg *otg_dev =
		container_of(otg->usb_phy, struct fsl_otg, phy);
	u32 retval = 0;

	if (!otg->host)
		return -ENODEV;
	dev = otg->host->controller;

	/*
	 * Update a_vbus_vld state as a_vbus_vld int is disabled
	 * in device mode
	 */
	fsm->a_vbus_vld =
		!!(fsl_readl(&usb_dr_regs->otgsc) & OTGSC_STS_A_VBUS_VALID);
	if (on) {
		/* start fsl usb host controller */
		if (otg_dev->host_working)
			goto end;
		else {
			otg_reset_controller();
			VDBG("host on......\n");
			if (dev->driver->pm && dev->driver->pm->resume) {
				retval = dev->driver->pm->resume(dev);
				if (fsm->id) {
					/* default-b */
					fsl_otg_drv_vbus(fsm, 1);
					/*
					 * Workaround: b_host can't driver
					 * vbus, but PP in PORTSC needs to
					 * be 1 for host to work.
					 * So we set drv_vbus bit in
					 * transceiver to 0 thru ULPI.

Annotation

Implementation Notes