drivers/irqchip/irq-sg2042-msi.c
Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-sg2042-msi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/irqchip/irq-sg2042-msi.c- Extension
.c- Size
- 9766 bytes
- Lines
- 341
- 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.
- 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/cleanup.hlinux/io.hlinux/irq.hlinux/irqdomain.hlinux/kernel.hlinux/module.hlinux/msi.hlinux/platform_device.hlinux/property.hlinux/slab.hlinux/irqchip/irq-msi-lib.h
Detected Declarations
struct sg204x_msi_chip_infostruct sg204x_msi_chipdatafunction sg204x_msi_allocate_hwirqfunction sg204x_msi_free_hwirqfunction sg2042_msi_irq_ackfunction sg2042_msi_irq_compose_msi_msgfunction sg2044_msi_irq_ackfunction sg2044_msi_irq_compose_msi_msgfunction sg204x_msi_parent_domain_allocfunction sg204x_msi_middle_domain_allocfunction sg204x_msi_middle_domain_freefunction sg204x_msi_init_domainsfunction sg2042_msi_probe
Annotated Snippet
struct sg204x_msi_chip_info {
const struct irq_chip *irqchip;
const struct msi_parent_ops *parent_ops;
};
/**
* struct sg204x_msi_chipdata - chip data for the SG204x MSI IRQ controller
* @reg_clr: clear reg, see TRM, 10.1.33, GP_INTR0_CLR
* @doorbell_addr: see TRM, 10.1.32, GP_INTR0_SET
* @irq_first: First vectors number that MSIs starts
* @num_irqs: Number of vectors for MSIs
* @irq_type: IRQ type for MSIs
* @msi_map: mapping for allocated MSI vectors.
* @msi_map_lock: Lock for msi_map
* @chip_info: chip specific infomations
*/
struct sg204x_msi_chipdata {
void __iomem *reg_clr;
phys_addr_t doorbell_addr;
u32 irq_first;
u32 num_irqs;
unsigned int irq_type;
unsigned long *msi_map;
struct mutex msi_map_lock;
const struct sg204x_msi_chip_info *chip_info;
};
static int sg204x_msi_allocate_hwirq(struct sg204x_msi_chipdata *data, int num_req)
{
int first;
guard(mutex)(&data->msi_map_lock);
first = bitmap_find_free_region(data->msi_map, data->num_irqs,
get_count_order(num_req));
return first >= 0 ? first : -ENOSPC;
}
static void sg204x_msi_free_hwirq(struct sg204x_msi_chipdata *data, int hwirq, int num_req)
{
guard(mutex)(&data->msi_map_lock);
bitmap_release_region(data->msi_map, hwirq, get_count_order(num_req));
}
static void sg2042_msi_irq_ack(struct irq_data *d)
{
struct sg204x_msi_chipdata *data = irq_data_get_irq_chip_data(d);
int bit_off = d->hwirq;
writel(1 << bit_off, data->reg_clr);
irq_chip_ack_parent(d);
}
static void sg2042_msi_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
{
struct sg204x_msi_chipdata *data = irq_data_get_irq_chip_data(d);
msg->address_hi = upper_32_bits(data->doorbell_addr);
msg->address_lo = lower_32_bits(data->doorbell_addr);
msg->data = 1 << d->hwirq;
}
static const struct irq_chip sg2042_msi_middle_irq_chip = {
.name = "SG2042 MSI",
.irq_startup = irq_chip_startup_parent,
.irq_shutdown = irq_chip_shutdown_parent,
.irq_ack = sg2042_msi_irq_ack,
.irq_mask = irq_chip_mask_parent,
.irq_unmask = irq_chip_unmask_parent,
#ifdef CONFIG_SMP
.irq_set_affinity = irq_chip_set_affinity_parent,
#endif
.irq_compose_msi_msg = sg2042_msi_irq_compose_msi_msg,
};
static void sg2044_msi_irq_ack(struct irq_data *d)
{
struct sg204x_msi_chipdata *data = irq_data_get_irq_chip_data(d);
writel(0, (u32 __iomem *)data->reg_clr + d->hwirq);
irq_chip_ack_parent(d);
}
static void sg2044_msi_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
{
struct sg204x_msi_chipdata *data = irq_data_get_irq_chip_data(d);
Annotation
- Immediate include surface: `linux/cleanup.h`, `linux/io.h`, `linux/irq.h`, `linux/irqdomain.h`, `linux/kernel.h`, `linux/module.h`, `linux/msi.h`, `linux/platform_device.h`.
- Detected declarations: `struct sg204x_msi_chip_info`, `struct sg204x_msi_chipdata`, `function sg204x_msi_allocate_hwirq`, `function sg204x_msi_free_hwirq`, `function sg2042_msi_irq_ack`, `function sg2042_msi_irq_compose_msi_msg`, `function sg2044_msi_irq_ack`, `function sg2044_msi_irq_compose_msi_msg`, `function sg204x_msi_parent_domain_alloc`, `function sg204x_msi_middle_domain_alloc`.
- Atlas domain: Driver Families / drivers/irqchip.
- Implementation status: source implementation candidate.
- 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.