drivers/pci/controller/pcie-iproc-msi.c
Source file repositories/reference/linux-study-clean/drivers/pci/controller/pcie-iproc-msi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pci/controller/pcie-iproc-msi.c- Extension
.c- Size
- 17791 bytes
- Lines
- 678
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/irqchip/chained_irq.hlinux/irqchip/irq-msi-lib.hlinux/irqdomain.hlinux/msi.hlinux/of_irq.hlinux/of_pci.hlinux/pci.hpcie-iproc.h
Detected Declarations
struct iproc_msistruct iproc_msi_grpstruct iproc_msienum iproc_msi_regfunction iproc_msi_read_regfunction iproc_msi_write_regfunction hwirq_to_groupfunction iproc_msi_addr_offsetfunction iproc_msi_eq_offsetfunction hwirq_to_cpufunction hwirq_to_canonical_hwirqfunction iproc_msi_irq_set_affinityfunction iproc_msi_irq_compose_msi_msgfunction iproc_msi_irq_domain_allocfunction iproc_msi_irq_domain_freefunction decode_msi_hwirqfunction iproc_msi_handlerfunction iproc_msi_enablefunction iproc_msi_disablefunction iproc_msi_alloc_domainsfunction iproc_msi_free_domainsfunction iproc_msi_irq_freefunction iproc_msi_irq_setupfunction iproc_msi_initfunction for_each_online_cpufunction iproc_msi_exitexport iproc_msi_initexport iproc_msi_exit
Annotated Snippet
struct iproc_msi_grp {
struct iproc_msi *msi;
int gic_irq;
unsigned int eq;
};
/**
* struct iproc_msi - iProc event queue based MSI
*
* Only meant to be used on platforms without MSI support integrated into the
* GIC.
*
* @pcie: pointer to iProc PCIe data
* @reg_offsets: MSI register offsets
* @grps: MSI groups
* @nr_irqs: number of total interrupts connected to GIC
* @nr_cpus: number of toal CPUs
* @has_inten_reg: indicates the MSI interrupt enable register needs to be
* set explicitly (required for some legacy platforms)
* @bitmap: MSI vector bitmap
* @bitmap_lock: lock to protect access to the MSI bitmap
* @nr_msi_vecs: total number of MSI vectors
* @inner_domain: inner IRQ domain
* @nr_eq_region: required number of 4K aligned memory region for MSI event
* queues
* @nr_msi_region: required number of 4K aligned address region for MSI posted
* writes
* @eq_cpu: pointer to allocated memory region for MSI event queues
* @eq_dma: DMA address of MSI event queues
* @msi_addr: MSI address
*/
struct iproc_msi {
struct iproc_pcie *pcie;
const u16 (*reg_offsets)[IPROC_MSI_REG_SIZE];
struct iproc_msi_grp *grps;
int nr_irqs;
int nr_cpus;
bool has_inten_reg;
unsigned long *bitmap;
struct mutex bitmap_lock;
unsigned int nr_msi_vecs;
struct irq_domain *inner_domain;
unsigned int nr_eq_region;
unsigned int nr_msi_region;
void *eq_cpu;
dma_addr_t eq_dma;
phys_addr_t msi_addr;
};
static const u16 iproc_msi_reg_paxb[NR_HW_IRQS][IPROC_MSI_REG_SIZE] = {
{ 0x200, 0x2c0, 0x204, 0x2c4, 0x210, 0x250, 0x254, 0x208 },
{ 0x200, 0x2c0, 0x204, 0x2c4, 0x214, 0x258, 0x25c, 0x208 },
{ 0x200, 0x2c0, 0x204, 0x2c4, 0x218, 0x260, 0x264, 0x208 },
{ 0x200, 0x2c0, 0x204, 0x2c4, 0x21c, 0x268, 0x26c, 0x208 },
{ 0x200, 0x2c0, 0x204, 0x2c4, 0x220, 0x270, 0x274, 0x208 },
{ 0x200, 0x2c0, 0x204, 0x2c4, 0x224, 0x278, 0x27c, 0x208 },
};
static const u16 iproc_msi_reg_paxc[NR_HW_IRQS][IPROC_MSI_REG_SIZE] = {
{ 0xc00, 0xc04, 0xc08, 0xc0c, 0xc40, 0xc50, 0xc60 },
{ 0xc10, 0xc14, 0xc18, 0xc1c, 0xc44, 0xc54, 0xc64 },
{ 0xc20, 0xc24, 0xc28, 0xc2c, 0xc48, 0xc58, 0xc68 },
{ 0xc30, 0xc34, 0xc38, 0xc3c, 0xc4c, 0xc5c, 0xc6c },
};
static inline u32 iproc_msi_read_reg(struct iproc_msi *msi,
enum iproc_msi_reg reg,
unsigned int eq)
{
struct iproc_pcie *pcie = msi->pcie;
return readl_relaxed(pcie->base + msi->reg_offsets[eq][reg]);
}
static inline void iproc_msi_write_reg(struct iproc_msi *msi,
enum iproc_msi_reg reg,
int eq, u32 val)
{
struct iproc_pcie *pcie = msi->pcie;
writel_relaxed(val, pcie->base + msi->reg_offsets[eq][reg]);
}
static inline u32 hwirq_to_group(struct iproc_msi *msi, unsigned long hwirq)
{
return (hwirq % msi->nr_irqs);
}
static inline unsigned int iproc_msi_addr_offset(struct iproc_msi *msi,
unsigned long hwirq)
Annotation
- Immediate include surface: `linux/interrupt.h`, `linux/irqchip/chained_irq.h`, `linux/irqchip/irq-msi-lib.h`, `linux/irqdomain.h`, `linux/msi.h`, `linux/of_irq.h`, `linux/of_pci.h`, `linux/pci.h`.
- Detected declarations: `struct iproc_msi`, `struct iproc_msi_grp`, `struct iproc_msi`, `enum iproc_msi_reg`, `function iproc_msi_read_reg`, `function iproc_msi_write_reg`, `function hwirq_to_group`, `function iproc_msi_addr_offset`, `function iproc_msi_eq_offset`, `function hwirq_to_cpu`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: integration 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.