STRUCT MPIC(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’– struct mpic(9) β€” the MPIC private data structure, bestie πŸ’–

okay so this is a page from the Kernel API Manual, and it's literally all about struct mpic β€” the MPIC private data structure. yes, the actual struct, the whole thing, every single member, no gatekeeping here 🫢


✨ NAME ✨

struct mpic β€” the MPIC private data structure. that's it, that's the vibe πŸ’…


🌸 SYNOPSIS 🌸

here's the whole struct, character for character, do not touch, do not "clean it up", just read it:

struct mpic {
    void __iomem *base;
    void __iomem *per_cpu;
    int parent_irq;
    struct irq_domain *domain;
  #ifdef CONFIG_SMP;
    struct irq_domain *ipi_domain;
  #endif;
  #ifdef CONFIG_PCI_MSI;
    struct irq_domain *msi_inner_domain;
    unsigned long msi_used[BITS_TO_LONGS( PCI_MSI_FULL_DOORBELL_NR)];
    struct mutex msi_lock;
    phys_addr_t msi_doorbell_addr;
    u32 msi_doorbell_mask;
    unsigned int msi_doorbell_start, msi_doorbell_size;
  #endif;
    u32 doorbell_mask;
 };

like, notice the #ifdef CONFIG_SMP; and #ifdef CONFIG_PCI_MSI; with the trailing semicolons?? iconic, slightly cursed, but we're not changing it. periodt.


πŸŽ€ Members πŸŽ€

okay bestie, member-by-member tour, let's go πŸ¦‹

  • base β€” MPIC registers base address. the home base, the main character energy ✨
  • per_cpu β€” per-CPU registers base address. one for every CPU, because sharing is not always caring πŸ’œ
  • parent_irq β€” parent IRQ if MPIC is not top-level interrupt controller. like, if MPIC isn't the boss of the interrupt chain, this is who it answers to πŸ‘‘
  • domain β€” MPIC main interrupt domain. the big one, the main domain πŸ’…
  • ipi_domain β€” IPI domain. (this one lives inside #ifdef CONFIG_SMP, iykyk)
  • msi_inner_domain β€” MSI inner domain. the domain inside the domain πŸŒ€
  • msi_used β€” bitmap of used MSI numbers. lowkey a whole tracking system for who's taken 🌈
  • msi_lock β€” mutex serializing access to msi_used. no chaos allowed, only one at a time πŸ”’
  • msi_doorbell_addr β€” physical address of MSI doorbell register. ring ring, it's an interrupt πŸ’€
  • msi_doorbell_mask β€” mask of available doorbell bits for MSIs. and bestie, it's either PCI_MSI_DOORBELL_MASK or PCI_MSI_FULL_DOORBELL_MASK, no in-between 🎯
  • msi_doorbell_start β€” first set bit in msi_doorbell_mask. first out the door, fr fr ⭐
  • msi_doorbell_size β€” number of set bits in msi_doorbell_mask. count 'em up πŸ”₯
  • doorbell_mask β€” doorbell mask of MSIs and IPIs, stored on suspend, restored on resume. like a little nap that saves state, obsessed 😭
real talk: the msi_inner_domain through msi_doorbell_size crew only exist under #ifdef CONFIG_PCI_MSI, and ipi_domain only under #ifdef CONFIG_SMP. and doorbell_mask sits outside both, always present, always thriving πŸ™ˆ

🧚 SEE ALSO 🧚

  • Kernel file ./drivers/irqchip/irq-armada-370-xp.c β€” go read it, tell me everything πŸ’–

okay and finally, the cute sign-off: this little masterpiece comes to you from ./drivers/irqchip, dated October 2026. slay, go configure your interrupts responsibly πŸŒΈπŸŽ€πŸ¦‹

πŸ“¦ where this page comes from