drivers/irqchip/irq-mvebu-sei.c
Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-mvebu-sei.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/irqchip/irq-mvebu-sei.c- Extension
.c- Size
- 12850 bytes
- Lines
- 489
- 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/interrupt.hlinux/irq.hlinux/irqchip.hlinux/irqchip/chained_irq.hlinux/irqdomain.hlinux/kernel.hlinux/msi.hlinux/platform_device.hlinux/of_address.hlinux/of_irq.hlinux/of_platform.hlinux/irqchip/irq-msi-lib.h
Detected Declarations
struct mvebu_sei_interrupt_rangestruct mvebu_sei_capsstruct mvebu_seifunction mvebu_sei_ack_irqfunction mvebu_sei_mask_irqfunction mvebu_sei_unmask_irqfunction mvebu_sei_set_affinityfunction mvebu_sei_set_irqchip_statefunction mvebu_sei_ap_set_typefunction mvebu_sei_cp_compose_msi_msgfunction mvebu_sei_cp_set_typefunction mvebu_sei_domain_allocfunction mvebu_sei_domain_freefunction mvebu_sei_ap_translatefunction mvebu_sei_ap_allocfunction mvebu_sei_cp_release_irqfunction mvebu_sei_cp_domain_allocfunction mvebu_sei_cp_domain_freefunction mvebu_sei_handle_cascade_irqfunction for_each_set_bitfunction mvebu_sei_resetfunction mvebu_sei_probe
Annotated Snippet
struct mvebu_sei_interrupt_range {
u32 first;
u32 size;
};
struct mvebu_sei_caps {
struct mvebu_sei_interrupt_range ap_range;
struct mvebu_sei_interrupt_range cp_range;
};
struct mvebu_sei {
struct device *dev;
void __iomem *base;
struct resource *res;
struct irq_domain *sei_domain;
struct irq_domain *ap_domain;
struct irq_domain *cp_domain;
const struct mvebu_sei_caps *caps;
/* Lock on MSI allocations/releases */
struct mutex cp_msi_lock;
DECLARE_BITMAP(cp_msi_bitmap, SEI_IRQ_COUNT);
/* Lock on IRQ masking register */
raw_spinlock_t mask_lock;
};
static void mvebu_sei_ack_irq(struct irq_data *d)
{
struct mvebu_sei *sei = irq_data_get_irq_chip_data(d);
u32 reg_idx = SEI_IRQ_REG_IDX(d->hwirq);
writel_relaxed(BIT(SEI_IRQ_REG_BIT(d->hwirq)),
sei->base + GICP_SECR(reg_idx));
}
static void mvebu_sei_mask_irq(struct irq_data *d)
{
struct mvebu_sei *sei = irq_data_get_irq_chip_data(d);
u32 reg, reg_idx = SEI_IRQ_REG_IDX(d->hwirq);
unsigned long flags;
/* 1 disables the interrupt */
raw_spin_lock_irqsave(&sei->mask_lock, flags);
reg = readl_relaxed(sei->base + GICP_SEMR(reg_idx));
reg |= BIT(SEI_IRQ_REG_BIT(d->hwirq));
writel_relaxed(reg, sei->base + GICP_SEMR(reg_idx));
raw_spin_unlock_irqrestore(&sei->mask_lock, flags);
}
static void mvebu_sei_unmask_irq(struct irq_data *d)
{
struct mvebu_sei *sei = irq_data_get_irq_chip_data(d);
u32 reg, reg_idx = SEI_IRQ_REG_IDX(d->hwirq);
unsigned long flags;
/* 0 enables the interrupt */
raw_spin_lock_irqsave(&sei->mask_lock, flags);
reg = readl_relaxed(sei->base + GICP_SEMR(reg_idx));
reg &= ~BIT(SEI_IRQ_REG_BIT(d->hwirq));
writel_relaxed(reg, sei->base + GICP_SEMR(reg_idx));
raw_spin_unlock_irqrestore(&sei->mask_lock, flags);
}
static int mvebu_sei_set_affinity(struct irq_data *d,
const struct cpumask *mask_val,
bool force)
{
return -EINVAL;
}
static int mvebu_sei_set_irqchip_state(struct irq_data *d,
enum irqchip_irq_state which,
bool state)
{
/* We can only clear the pending state by acking the interrupt */
if (which != IRQCHIP_STATE_PENDING || state)
return -EINVAL;
mvebu_sei_ack_irq(d);
return 0;
}
static struct irq_chip mvebu_sei_irq_chip = {
.name = "SEI",
.irq_ack = mvebu_sei_ack_irq,
.irq_mask = mvebu_sei_mask_irq,
.irq_unmask = mvebu_sei_unmask_irq,
.irq_set_affinity = mvebu_sei_set_affinity,
.irq_set_irqchip_state = mvebu_sei_set_irqchip_state,
Annotation
- Immediate include surface: `linux/interrupt.h`, `linux/irq.h`, `linux/irqchip.h`, `linux/irqchip/chained_irq.h`, `linux/irqdomain.h`, `linux/kernel.h`, `linux/msi.h`, `linux/platform_device.h`.
- Detected declarations: `struct mvebu_sei_interrupt_range`, `struct mvebu_sei_caps`, `struct mvebu_sei`, `function mvebu_sei_ack_irq`, `function mvebu_sei_mask_irq`, `function mvebu_sei_unmask_irq`, `function mvebu_sei_set_affinity`, `function mvebu_sei_set_irqchip_state`, `function mvebu_sei_ap_set_type`, `function mvebu_sei_cp_compose_msi_msg`.
- 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.