drivers/usb/musb/sunxi.c
Source file repositories/reference/linux-study-clean/drivers/usb/musb/sunxi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/musb/sunxi.c- Extension
.c- Size
- 24324 bytes
- Lines
- 871
- 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/err.hlinux/extcon.hlinux/io.hlinux/kernel.hlinux/module.hlinux/of.hlinux/phy/phy-sun4i-usb.hlinux/platform_device.hlinux/reset.hlinux/soc/sunxi/sunxi_sram.hlinux/usb/musb.hlinux/usb/of.hlinux/usb/usb_phy_generic.hlinux/workqueue.hmusb_core.h
Detected Declarations
struct sunxi_musb_cfgstruct sunxi_gluefunction sunxi_musb_workfunction sunxi_musb_set_vbusfunction sunxi_musb_pre_root_reset_endfunction sunxi_musb_post_root_reset_endfunction sunxi_musb_interruptfunction sunxi_musb_host_notifierfunction sunxi_musb_initfunction sunxi_musb_exitfunction sunxi_musb_enablefunction sunxi_musb_disablefunction sunxi_musb_dma_controller_createfunction sunxi_musb_dma_controller_destroyfunction sunxi_musb_recoverfunction sunxi_musb_fifo_offsetfunction sunxi_musb_ep_offsetfunction sunxi_musb_busctl_offsetfunction sunxi_musb_readbfunction sunxi_musb_writebfunction sunxi_musb_readwfunction sunxi_musb_writewfunction sunxi_musb_probefunction sunxi_musb_remove
Annotated Snippet
struct sunxi_musb_cfg {
const struct musb_hdrc_config *hdrc_config;
bool has_sram;
bool has_reset;
bool no_configdata;
};
/* Our read/write methods need access and do not get passed in a musb ref :| */
static struct musb *sunxi_musb;
struct sunxi_glue {
struct device *dev;
struct musb *musb;
struct platform_device *musb_pdev;
struct clk *clk;
struct reset_control *rst;
struct phy *phy;
struct platform_device *usb_phy;
struct usb_phy *xceiv;
enum phy_mode phy_mode;
unsigned long flags;
struct work_struct work;
struct extcon_dev *extcon;
struct notifier_block host_nb;
};
/* phy_power_on / off may sleep, so we use a workqueue */
static void sunxi_musb_work(struct work_struct *work)
{
struct sunxi_glue *glue = container_of(work, struct sunxi_glue, work);
bool vbus_on, phy_on;
if (!test_bit(SUNXI_MUSB_FL_ENABLED, &glue->flags))
return;
if (test_and_clear_bit(SUNXI_MUSB_FL_HOSTMODE_PEND, &glue->flags)) {
struct musb *musb = glue->musb;
unsigned long flags;
u8 devctl;
spin_lock_irqsave(&musb->lock, flags);
devctl = readb(musb->mregs + SUNXI_MUSB_DEVCTL);
if (test_bit(SUNXI_MUSB_FL_HOSTMODE, &glue->flags)) {
set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags);
musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
MUSB_HST_MODE(musb);
devctl |= MUSB_DEVCTL_SESSION;
} else {
clear_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags);
musb->xceiv->otg->state = OTG_STATE_B_IDLE;
MUSB_DEV_MODE(musb);
devctl &= ~MUSB_DEVCTL_SESSION;
}
writeb(devctl, musb->mregs + SUNXI_MUSB_DEVCTL);
spin_unlock_irqrestore(&musb->lock, flags);
}
vbus_on = test_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags);
phy_on = test_bit(SUNXI_MUSB_FL_PHY_ON, &glue->flags);
if (phy_on != vbus_on) {
if (vbus_on) {
phy_power_on(glue->phy);
set_bit(SUNXI_MUSB_FL_PHY_ON, &glue->flags);
} else {
phy_power_off(glue->phy);
clear_bit(SUNXI_MUSB_FL_PHY_ON, &glue->flags);
}
}
if (test_and_clear_bit(SUNXI_MUSB_FL_PHY_MODE_PEND, &glue->flags))
phy_set_mode(glue->phy, glue->phy_mode);
}
static void sunxi_musb_set_vbus(struct musb *musb, int is_on)
{
struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
if (is_on) {
set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags);
musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
} else {
clear_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags);
}
schedule_work(&glue->work);
}
Annotation
- Immediate include surface: `linux/clk.h`, `linux/err.h`, `linux/extcon.h`, `linux/io.h`, `linux/kernel.h`, `linux/module.h`, `linux/of.h`, `linux/phy/phy-sun4i-usb.h`.
- Detected declarations: `struct sunxi_musb_cfg`, `struct sunxi_glue`, `function sunxi_musb_work`, `function sunxi_musb_set_vbus`, `function sunxi_musb_pre_root_reset_end`, `function sunxi_musb_post_root_reset_end`, `function sunxi_musb_interrupt`, `function sunxi_musb_host_notifier`, `function sunxi_musb_init`, `function sunxi_musb_exit`.
- 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.