drivers/irqchip/irq-imx-mu-msi.c
Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-imx-mu-msi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/irqchip/irq-imx-mu-msi.c- Extension
.c- Size
- 10940 bytes
- Lines
- 441
- Domain
- Driver Families
- Bucket
- drivers/irqchip
- 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/irq.hlinux/irqchip.hlinux/irqchip/chained_irq.hlinux/irqdomain.hlinux/kernel.hlinux/module.hlinux/msi.hlinux/of_irq.hlinux/of_platform.hlinux/pm_runtime.hlinux/pm_domain.hlinux/spinlock.hlinux/irqchip/irq-msi-lib.h
Detected Declarations
struct imx_mu_dcfgstruct imx_mu_msienum imx_mu_xcrenum imx_mu_xsrenum imx_mu_typefunction imx_mu_writefunction imx_mu_readfunction imx_mu_xcr_rmwfunction imx_mu_msi_parent_mask_irqfunction imx_mu_msi_parent_unmask_irqfunction imx_mu_msi_parent_ack_irqfunction imx_mu_msi_parent_compose_msgfunction imx_mu_msi_parent_set_affinityfunction imx_mu_msi_domain_irq_allocfunction imx_mu_msi_domain_irq_freefunction imx_mu_msi_irq_handlerfunction imx_mu_msi_domains_initfunction imx_mu_probefunction imx_mu_runtime_suspendfunction imx_mu_runtime_resumefunction imx_mu_imx7ulp_probefunction imx_mu_imx6sx_probefunction imx_mu_imx8ulp_probe
Annotated Snippet
struct imx_mu_dcfg {
enum imx_mu_type type;
u32 xTR; /* Transmit Register0 */
u32 xRR; /* Receive Register0 */
u32 xSR[IMX_MU_xSR_MAX]; /* Status Registers */
u32 xCR[IMX_MU_xCR_MAX]; /* Control Registers */
};
struct imx_mu_msi {
raw_spinlock_t lock;
struct irq_domain *msi_domain;
void __iomem *regs;
phys_addr_t msiir_addr;
const struct imx_mu_dcfg *cfg;
unsigned long used;
struct clk *clk;
};
static void imx_mu_write(struct imx_mu_msi *msi_data, u32 val, u32 offs)
{
iowrite32(val, msi_data->regs + offs);
}
static u32 imx_mu_read(struct imx_mu_msi *msi_data, u32 offs)
{
return ioread32(msi_data->regs + offs);
}
static u32 imx_mu_xcr_rmw(struct imx_mu_msi *msi_data, enum imx_mu_xcr type, u32 set, u32 clr)
{
unsigned long flags;
u32 val;
raw_spin_lock_irqsave(&msi_data->lock, flags);
val = imx_mu_read(msi_data, msi_data->cfg->xCR[type]);
val &= ~clr;
val |= set;
imx_mu_write(msi_data, val, msi_data->cfg->xCR[type]);
raw_spin_unlock_irqrestore(&msi_data->lock, flags);
return val;
}
static void imx_mu_msi_parent_mask_irq(struct irq_data *data)
{
struct imx_mu_msi *msi_data = irq_data_get_irq_chip_data(data);
imx_mu_xcr_rmw(msi_data, IMX_MU_RCR, 0, IMX_MU_xCR_RIEn(msi_data, data->hwirq));
}
static void imx_mu_msi_parent_unmask_irq(struct irq_data *data)
{
struct imx_mu_msi *msi_data = irq_data_get_irq_chip_data(data);
imx_mu_xcr_rmw(msi_data, IMX_MU_RCR, IMX_MU_xCR_RIEn(msi_data, data->hwirq), 0);
}
static void imx_mu_msi_parent_ack_irq(struct irq_data *data)
{
struct imx_mu_msi *msi_data = irq_data_get_irq_chip_data(data);
imx_mu_read(msi_data, msi_data->cfg->xRR + data->hwirq * 4);
}
static void imx_mu_msi_parent_compose_msg(struct irq_data *data,
struct msi_msg *msg)
{
struct imx_mu_msi *msi_data = irq_data_get_irq_chip_data(data);
u64 addr = msi_data->msiir_addr + 4 * data->hwirq;
msg->address_hi = upper_32_bits(addr);
msg->address_lo = lower_32_bits(addr);
msg->data = data->hwirq;
}
static int imx_mu_msi_parent_set_affinity(struct irq_data *irq_data,
const struct cpumask *mask, bool force)
{
return -EINVAL;
}
static struct irq_chip imx_mu_msi_parent_chip = {
.name = "MU",
.irq_mask = imx_mu_msi_parent_mask_irq,
.irq_unmask = imx_mu_msi_parent_unmask_irq,
.irq_ack = imx_mu_msi_parent_ack_irq,
.irq_compose_msi_msg = imx_mu_msi_parent_compose_msg,
.irq_set_affinity = imx_mu_msi_parent_set_affinity,
};
Annotation
- Immediate include surface: `linux/clk.h`, `linux/irq.h`, `linux/irqchip.h`, `linux/irqchip/chained_irq.h`, `linux/irqdomain.h`, `linux/kernel.h`, `linux/module.h`, `linux/msi.h`.
- Detected declarations: `struct imx_mu_dcfg`, `struct imx_mu_msi`, `enum imx_mu_xcr`, `enum imx_mu_xsr`, `enum imx_mu_type`, `function imx_mu_write`, `function imx_mu_read`, `function imx_mu_xcr_rmw`, `function imx_mu_msi_parent_mask_irq`, `function imx_mu_msi_parent_unmask_irq`.
- Atlas domain: Driver Families / drivers/irqchip.
- 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.