drivers/usb/musb/da8xx.c
Source file repositories/reference/linux-study-clean/drivers/usb/musb/da8xx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/musb/da8xx.c- Extension
.c- Size
- 17748 bytes
- Lines
- 650
- 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/module.hlinux/clk.hlinux/err.hlinux/io.hlinux/of.hlinux/of_platform.hlinux/phy/phy.hlinux/platform_device.hlinux/string_choices.hlinux/dma-mapping.hlinux/usb/usb_phy_generic.hmusb_core.h
Detected Declarations
struct da8xx_gluefunction da8xx_musb_enablefunction da8xx_musb_disablefunction da8xx_musb_set_vbusfunction otg_timerfunction da8xx_musb_try_idlefunction da8xx_babble_recoverfunction da8xx_musb_interruptfunction havefunction da8xx_musb_set_modefunction da8xx_musb_initfunction da8xx_musb_exitfunction get_vbus_powerfunction da8xx_dma_controller_callbackfunction da8xx_dma_controller_createfunction da8xx_probefunction da8xx_removefunction da8xx_suspendfunction da8xx_resume
Annotated Snippet
struct da8xx_glue {
struct device *dev;
struct platform_device *musb;
struct platform_device *usb_phy;
struct clk *clk;
struct phy *phy;
};
/*
* Because we don't set CTRL.UINT, it's "important" to:
* - not read/write INTRUSB/INTRUSBE (except during
* initial setup, as a workaround);
* - use INTSET/INTCLR instead.
*/
/**
* da8xx_musb_enable - enable interrupts
*/
static void da8xx_musb_enable(struct musb *musb)
{
void __iomem *reg_base = musb->ctrl_base;
u32 mask;
/* Workaround: setup IRQs through both register sets. */
mask = ((musb->epmask & DA8XX_USB_TX_EP_MASK) << DA8XX_INTR_TX_SHIFT) |
((musb->epmask & DA8XX_USB_RX_EP_MASK) << DA8XX_INTR_RX_SHIFT) |
DA8XX_INTR_USB_MASK;
musb_writel(reg_base, DA8XX_USB_INTR_MASK_SET_REG, mask);
/* Force the DRVVBUS IRQ so we can start polling for ID change. */
musb_writel(reg_base, DA8XX_USB_INTR_SRC_SET_REG,
DA8XX_INTR_DRVVBUS << DA8XX_INTR_USB_SHIFT);
}
/**
* da8xx_musb_disable - disable HDRC and flush interrupts
*/
static void da8xx_musb_disable(struct musb *musb)
{
void __iomem *reg_base = musb->ctrl_base;
musb_writel(reg_base, DA8XX_USB_INTR_MASK_CLEAR_REG,
DA8XX_INTR_USB_MASK |
DA8XX_INTR_TX_MASK | DA8XX_INTR_RX_MASK);
musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0);
}
#define portstate(stmt) stmt
static void da8xx_musb_set_vbus(struct musb *musb, int is_on)
{
WARN_ON(is_on && is_peripheral_active(musb));
}
#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 DaVinci's 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);
if (devctl & MUSB_DEVCTL_BDEVICE) {
musb->xceiv->otg->state = OTG_STATE_B_IDLE;
MUSB_DEV_MODE(musb);
} else {
musb->xceiv->otg->state = OTG_STATE_A_IDLE;
MUSB_HST_MODE(musb);
}
break;
case OTG_STATE_A_WAIT_VFALL:
/*
* Wait till VBUS falls below SessionEnd (~0.2 V); the 1.3
Annotation
- Immediate include surface: `linux/module.h`, `linux/clk.h`, `linux/err.h`, `linux/io.h`, `linux/of.h`, `linux/of_platform.h`, `linux/phy/phy.h`, `linux/platform_device.h`.
- Detected declarations: `struct da8xx_glue`, `function da8xx_musb_enable`, `function da8xx_musb_disable`, `function da8xx_musb_set_vbus`, `function otg_timer`, `function da8xx_musb_try_idle`, `function da8xx_babble_recover`, `function da8xx_musb_interrupt`, `function have`, `function da8xx_musb_set_mode`.
- 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.