drivers/usb/musb/mediatek.c
Source file repositories/reference/linux-study-clean/drivers/usb/musb/mediatek.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/musb/mediatek.c- Extension
.c- Size
- 13649 bytes
- Lines
- 538
- 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.
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk.hlinux/dma-mapping.hlinux/module.hlinux/of.hlinux/of_platform.hlinux/platform_device.hlinux/usb/role.hlinux/usb/usb_phy_generic.hmusb_core.hmusb_dma.h
Detected Declarations
struct mtk_gluefunction mtk_musb_clks_getfunction mtk_otg_switch_setfunction musb_usb_role_sx_setfunction musb_usb_role_sx_getfunction mtk_otg_switch_initfunction mtk_otg_switch_exitfunction generic_interruptfunction mtk_musb_interruptfunction mtk_musb_busctl_offsetfunction mtk_musb_clearbfunction mtk_musb_clearwfunction mtk_musb_set_modefunction mtk_musb_initfunction mtk_musb_get_togglefunction mtk_musb_set_togglefunction mtk_musb_exitfunction mtk_musb_probefunction mtk_musb_remove
Annotated Snippet
struct mtk_glue {
struct device *dev;
struct musb *musb;
struct platform_device *musb_pdev;
struct platform_device *usb_phy;
struct phy *phy;
struct usb_phy *xceiv;
enum phy_mode phy_mode;
struct clk_bulk_data clks[MTK_MUSB_CLKS_NUM];
enum usb_role role;
struct usb_role_switch *role_sw;
};
static int mtk_musb_clks_get(struct mtk_glue *glue)
{
struct device *dev = glue->dev;
glue->clks[0].id = "main";
glue->clks[1].id = "mcu";
glue->clks[2].id = "univpll";
return devm_clk_bulk_get(dev, MTK_MUSB_CLKS_NUM, glue->clks);
}
static int mtk_otg_switch_set(struct mtk_glue *glue, enum usb_role role)
{
struct musb *musb = glue->musb;
u8 devctl = readb(musb->mregs + MUSB_DEVCTL);
enum usb_role new_role;
if (role == glue->role)
return 0;
switch (role) {
case USB_ROLE_HOST:
musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
glue->phy_mode = PHY_MODE_USB_HOST;
new_role = USB_ROLE_HOST;
if (glue->role == USB_ROLE_NONE)
phy_power_on(glue->phy);
devctl |= MUSB_DEVCTL_SESSION;
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
MUSB_HST_MODE(musb);
break;
case USB_ROLE_DEVICE:
musb->xceiv->otg->state = OTG_STATE_B_IDLE;
glue->phy_mode = PHY_MODE_USB_DEVICE;
new_role = USB_ROLE_DEVICE;
devctl &= ~MUSB_DEVCTL_SESSION;
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
if (glue->role == USB_ROLE_NONE)
phy_power_on(glue->phy);
MUSB_DEV_MODE(musb);
break;
case USB_ROLE_NONE:
glue->phy_mode = PHY_MODE_USB_OTG;
new_role = USB_ROLE_NONE;
devctl &= ~MUSB_DEVCTL_SESSION;
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
if (glue->role != USB_ROLE_NONE)
phy_power_off(glue->phy);
break;
default:
dev_err(glue->dev, "Invalid State\n");
return -EINVAL;
}
glue->role = new_role;
phy_set_mode(glue->phy, glue->phy_mode);
return 0;
}
static int musb_usb_role_sx_set(struct usb_role_switch *sw, enum usb_role role)
{
return mtk_otg_switch_set(usb_role_switch_get_drvdata(sw), role);
}
static enum usb_role musb_usb_role_sx_get(struct usb_role_switch *sw)
{
struct mtk_glue *glue = usb_role_switch_get_drvdata(sw);
return glue->role;
}
static int mtk_otg_switch_init(struct mtk_glue *glue)
{
Annotation
- Immediate include surface: `linux/clk.h`, `linux/dma-mapping.h`, `linux/module.h`, `linux/of.h`, `linux/of_platform.h`, `linux/platform_device.h`, `linux/usb/role.h`, `linux/usb/usb_phy_generic.h`.
- Detected declarations: `struct mtk_glue`, `function mtk_musb_clks_get`, `function mtk_otg_switch_set`, `function musb_usb_role_sx_set`, `function musb_usb_role_sx_get`, `function mtk_otg_switch_init`, `function mtk_otg_switch_exit`, `function generic_interrupt`, `function mtk_musb_interrupt`, `function mtk_musb_busctl_offset`.
- Atlas domain: Driver Families / drivers/usb.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.