drivers/usb/musb/jz4740.c
Source file repositories/reference/linux-study-clean/drivers/usb/musb/jz4740.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/musb/jz4740.c- Extension
.c- Size
- 8677 bytes
- Lines
- 339
- 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/errno.hlinux/kernel.hlinux/module.hlinux/of.hlinux/phy/phy.hlinux/platform_device.hlinux/usb/role.hlinux/usb/usb_phy_generic.hmusb_core.h
Detected Declarations
struct jz4740_gluefunction jz4740_musb_interruptfunction jz4740_musb_role_switch_setfunction jz4740_musb_initfunction jz4740_musb_exitfunction jz4740_probefunction jz4740_remove
Annotated Snippet
struct jz4740_glue {
struct platform_device *pdev;
struct musb *musb;
struct clk *clk;
struct usb_role_switch *role_sw;
};
static irqreturn_t jz4740_musb_interrupt(int irq, void *__hci)
{
unsigned long flags;
irqreturn_t retval = IRQ_NONE, retval_dma = IRQ_NONE;
struct musb *musb = __hci;
if (IS_ENABLED(CONFIG_USB_INVENTRA_DMA) && musb->dma_controller)
retval_dma = dma_controller_irq(irq, musb->dma_controller);
spin_lock_irqsave(&musb->lock, flags);
musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
/*
* The controller is gadget only, the state of the host mode IRQ bits is
* undefined. Mask them to make sure that the musb driver core will
* never see them set
*/
musb->int_usb &= MUSB_INTR_SUSPEND | MUSB_INTR_RESUME |
MUSB_INTR_RESET | MUSB_INTR_SOF;
if (musb->int_usb || musb->int_tx || musb->int_rx)
retval = musb_interrupt(musb);
spin_unlock_irqrestore(&musb->lock, flags);
if (retval == IRQ_HANDLED || retval_dma == IRQ_HANDLED)
return IRQ_HANDLED;
return IRQ_NONE;
}
static const struct musb_fifo_cfg jz4740_musb_fifo_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 = 64, },
};
static const struct musb_hdrc_config jz4740_musb_config = {
/* Silicon does not implement USB OTG. */
.multipoint = 0,
/* Max EPs scanned, driver will decide which EP can be used. */
.num_eps = 4,
/* RAMbits needed to configure EPs from table */
.ram_bits = 9,
.fifo_cfg = jz4740_musb_fifo_cfg,
.fifo_cfg_size = ARRAY_SIZE(jz4740_musb_fifo_cfg),
};
static int jz4740_musb_role_switch_set(struct usb_role_switch *sw,
enum usb_role role)
{
struct jz4740_glue *glue = usb_role_switch_get_drvdata(sw);
struct usb_phy *phy = glue->musb->xceiv;
if (!phy)
return 0;
switch (role) {
case USB_ROLE_NONE:
atomic_notifier_call_chain(&phy->notifier, USB_EVENT_NONE, phy);
break;
case USB_ROLE_DEVICE:
atomic_notifier_call_chain(&phy->notifier, USB_EVENT_VBUS, phy);
break;
case USB_ROLE_HOST:
atomic_notifier_call_chain(&phy->notifier, USB_EVENT_ID, phy);
break;
}
return 0;
}
static int jz4740_musb_init(struct musb *musb)
{
struct device *dev = musb->controller->parent;
struct jz4740_glue *glue = dev_get_drvdata(dev);
struct usb_role_switch_desc role_sw_desc = {
.set = jz4740_musb_role_switch_set,
.driver_data = glue,
.fwnode = dev_fwnode(dev),
Annotation
- Immediate include surface: `linux/clk.h`, `linux/dma-mapping.h`, `linux/errno.h`, `linux/kernel.h`, `linux/module.h`, `linux/of.h`, `linux/phy/phy.h`, `linux/platform_device.h`.
- Detected declarations: `struct jz4740_glue`, `function jz4740_musb_interrupt`, `function jz4740_musb_role_switch_set`, `function jz4740_musb_init`, `function jz4740_musb_exit`, `function jz4740_probe`, `function jz4740_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.