drivers/usb/mtu3/mtu3_host.c

Source file repositories/reference/linux-study-clean/drivers/usb/mtu3/mtu3_host.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/mtu3/mtu3_host.c
Extension
.c
Size
9549 bytes
Lines
368
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 ((0x1 << i) & ssusb->u3p_dis_msk) {
			u3_ports_disabled++;
			continue;
		}

		value = mtu3_readl(ibase, SSUSB_U3_CTRL(i));
		value &= ~(SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_DIS);
		value |= SSUSB_U3_PORT_HOST_SEL;
		mtu3_writel(ibase, SSUSB_U3_CTRL(i), value);
	}

	/* power on and enable all u2 ports */
	for (i = 0; i < num_u2p; i++) {
		if ((0x1 << i) & ssusb->u2p_dis_msk)
			continue;

		value = mtu3_readl(ibase, SSUSB_U2_CTRL(i));
		value &= ~(SSUSB_U2_PORT_PDN | SSUSB_U2_PORT_DIS);
		value |= SSUSB_U2_PORT_HOST_SEL;
		mtu3_writel(ibase, SSUSB_U2_CTRL(i), value);
	}

	check_clk = SSUSB_XHCI_RST_B_STS;
	if (num_u3p > u3_ports_disabled)
		check_clk = SSUSB_U3_MAC_RST_B_STS;

	return ssusb_check_clocks(ssusb, check_clk);
}

static int ssusb_host_disable(struct ssusb_mtk *ssusb)
{
	void __iomem *ibase = ssusb->ippc_base;
	int num_u3p = ssusb->u3_ports;
	int num_u2p = ssusb->u2_ports;
	u32 value;
	int i;

	/* power down and disable u3 ports except skipped ones */
	for (i = 0; i < num_u3p; i++) {
		if ((0x1 << i) & ssusb->u3p_dis_msk)
			continue;

		value = mtu3_readl(ibase, SSUSB_U3_CTRL(i));
		value |= SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_DIS;
		mtu3_writel(ibase, SSUSB_U3_CTRL(i), value);
	}

	/* power down and disable u2 ports except skipped ones */
	for (i = 0; i < num_u2p; i++) {
		if ((0x1 << i) & ssusb->u2p_dis_msk)
			continue;

		value = mtu3_readl(ibase, SSUSB_U2_CTRL(i));
		value |= SSUSB_U2_PORT_PDN | SSUSB_U2_PORT_DIS;
		mtu3_writel(ibase, SSUSB_U2_CTRL(i), value);
	}

	/* power down host ip */
	mtu3_setbits(ibase, U3D_SSUSB_IP_PW_CTRL1, SSUSB_IP_HOST_PDN);

	return 0;
}

int ssusb_host_resume(struct ssusb_mtk *ssusb, bool p0_skipped)
{
	void __iomem *ibase = ssusb->ippc_base;
	int u3p_skip_msk = ssusb->u3p_dis_msk;
	int u2p_skip_msk = ssusb->u2p_dis_msk;
	int num_u3p = ssusb->u3_ports;
	int num_u2p = ssusb->u2_ports;
	u32 value;
	int i;

	if (p0_skipped) {
		u2p_skip_msk |= 0x1;
		if (ssusb->otg_switch.is_u3_drd)
			u3p_skip_msk |= 0x1;
	}

	/* power on host ip */
	mtu3_clrbits(ibase, U3D_SSUSB_IP_PW_CTRL1, SSUSB_IP_HOST_PDN);

	/* power on u3 ports except skipped ones */
	for (i = 0; i < num_u3p; i++) {
		if ((0x1 << i) & u3p_skip_msk)
			continue;

		value = mtu3_readl(ibase, SSUSB_U3_CTRL(i));
		value &= ~SSUSB_U3_PORT_PDN;
		mtu3_writel(ibase, SSUSB_U3_CTRL(i), value);

Annotation

Implementation Notes