drivers/usb/musb/mpfs.c
Source file repositories/reference/linux-study-clean/drivers/usb/musb/mpfs.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/musb/mpfs.c- Extension
.c- Size
- 10175 bytes
- Lines
- 384
- 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/err.hlinux/io.hlinux/kernel.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/usb/usb_phy_generic.hmusb_core.hmusb_dma.h
Detected Declarations
struct mpfs_gluefunction mpfs_musb_set_vbusfunction otg_timerfunction mpfs_musb_try_idlefunction mpfs_musb_interruptfunction mpfs_musb_initfunction mpfs_musb_exitfunction mpfs_probefunction mpfs_remove
Annotated Snippet
struct mpfs_glue {
struct device *dev;
struct platform_device *musb;
struct platform_device *phy;
struct clk *clk;
};
static const struct musb_fifo_cfg mpfs_musb_mode_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 3, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 3, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 4, .style = FIFO_TX, .maxpacket = 1024, },
{ .hw_ep_num = 4, .style = FIFO_RX, .maxpacket = 4096, },
};
static const struct musb_hdrc_config mpfs_musb_hdrc_config = {
.fifo_cfg = mpfs_musb_mode_cfg,
.fifo_cfg_size = ARRAY_SIZE(mpfs_musb_mode_cfg),
.multipoint = true,
.dyn_fifo = true,
.num_eps = MPFS_MUSB_MAX_EP_NUM,
.ram_bits = MPFS_MUSB_RAM_BITS,
};
static void mpfs_musb_set_vbus(struct musb *musb, int is_on)
{
u8 devctl;
/*
* HDRC controls CPEN, but beware current surges during device
* connect. They can trigger transient overcurrent conditions
* that must be ignored.
*/
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
if (is_on) {
musb->is_active = 1;
musb->xceiv->otg->default_a = 1;
musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
devctl |= MUSB_DEVCTL_SESSION;
MUSB_HST_MODE(musb);
} else {
musb->is_active = 0;
/*
* NOTE: skipping A_WAIT_VFALL -> A_IDLE and
* jumping right to B_IDLE...
*/
musb->xceiv->otg->default_a = 0;
musb->xceiv->otg->state = OTG_STATE_B_IDLE;
devctl &= ~MUSB_DEVCTL_SESSION;
MUSB_DEV_MODE(musb);
}
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
dev_dbg(musb->controller, "VBUS %s, devctl %02x\n",
usb_otg_state_string(musb->xceiv->otg->state),
musb_readb(musb->mregs, MUSB_DEVCTL));
}
#define POLL_SECONDS 2
static void otg_timer(struct timer_list *t)
{
struct musb *musb = timer_container_of(musb, t,
dev_timer);
void __iomem *mregs = musb->mregs;
u8 devctl;
unsigned long flags;
/*
* We poll because PolarFire SoC won't expose several OTG-critical
* status change events (from the transceiver) otherwise.
*/
devctl = musb_readb(mregs, MUSB_DEVCTL);
dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl,
usb_otg_state_string(musb->xceiv->otg->state));
spin_lock_irqsave(&musb->lock, flags);
switch (musb->xceiv->otg->state) {
case OTG_STATE_A_WAIT_BCON:
devctl &= ~MUSB_DEVCTL_SESSION;
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
Annotation
- Immediate include surface: `linux/clk.h`, `linux/dma-mapping.h`, `linux/err.h`, `linux/io.h`, `linux/kernel.h`, `linux/module.h`, `linux/of.h`, `linux/platform_device.h`.
- Detected declarations: `struct mpfs_glue`, `function mpfs_musb_set_vbus`, `function otg_timer`, `function mpfs_musb_try_idle`, `function mpfs_musb_interrupt`, `function mpfs_musb_init`, `function mpfs_musb_exit`, `function mpfs_probe`, `function mpfs_remove`.
- 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.