STRUCT REGMAP_IRQ_CHIP(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… struct regmap_irq_chip(9) β€” the kernel API manual, bestie edition

okay so. this is struct regmap_irq_chip(9) from the Kernel API Manual, and it's literally the blueprint for a generic regmap irq_chip. think of it as the main-character struct that tells the regmap-IRQ machinery everything it needs to know about your interrupt controller. let's get into it πŸŽ€

✨ SYNOPSIS ✨

struct regmap_irq_chip {
    const char *name;
    const char *domain_suffix;
    unsigned int main_status;
    unsigned int num_main_status_bits;
    const struct regmap_irq_sub_irq_map *sub_reg_offsets;
    int num_main_regs;
    unsigned int status_base;
    unsigned int mask_base;
    unsigned int unmask_base;
    unsigned int ack_base;
    unsigned int wake_base;
    const unsigned int *config_base;
    unsigned int irq_reg_stride;
    unsigned int init_ack_masked:1;
    unsigned int mask_unmask_non_inverted:1;
    unsigned int use_ack:1;
    unsigned int ack_invert:1;
    unsigned int clear_ack:1;
    unsigned int status_invert:1;
    unsigned int status_is_level:1;
    unsigned int wake_invert:1;
    unsigned int type_in_mask:1;
    unsigned int clear_on_unmask:1;
    unsigned int runtime_pm:1;
    unsigned int no_status:1;
    int num_regs;
    const struct regmap_irq *irqs;
    int num_irqs;
    int num_config_bases;
    int num_config_regs;
    int (*handle_pre_irq)(void *irq_drv_data);
    int (*handle_post_irq)(void *irq_drv_data);
    int (*handle_mask_sync)(int index, unsigned int mask_buf_def,
    unsigned int mask_buf, void *irq_drv_data);
    int (*set_type_config)(unsigned int **buf, unsigned int type, const
    struct regmap_irq *irq_data, int idx, void *irq_drv_data);
    unsigned int (*get_irq_reg)(struct regmap_irq_chip_data *data,
    unsigned int base, int index);
    int (*irq_reqres)(void *irq_drv_data, irq_hw_number_t hwirq);
    void (*irq_relres)(void *irq_drv_data, irq_hw_number_t hwirq);
    void *irq_drv_data;
 };

πŸ¦‹ MEMBERS πŸ¦‹

  • name β€” the descriptive name for your IRQ controller. give it a cute one, it deserves it πŸ’–
  • domain_suffix β€” a name suffix that gets appended to the end of the IRQ domain name. you need this when multiple regmap-IRQ controllers are created from the same device (iykyk, can't have two domains with the same name, that's giving chaos).
  • main_status β€” base main status register address. for chips that have interrupts arranged in separate sub-irq blocks with their own IRQ registers, plus a main IRQ register that flags which sub-irq blocks have unhandled interrupts. for those chips, you put the sub-irq register info in status_base, mask_base and ack_base.
  • num_main_status_bits β€” should be given to chips where the number of meaningfull main status bits differs from num_regs. (yes, "meaningfull", we keep it πŸ’€)
  • sub_reg_offsets β€” arrays of mappings from main register bits to sub irq registers. the first item in the array describes the registers for the first main status bit, the second array for the second bit, etc. the offset is given as the sub register status offset to status_base. should contain num_regs arrays. can be provided for chips with a more complex mapping than "1.st bit to 1.st sub-reg, 2.nd bit to 2.nd sub-reg, ..." β€” you know the vibe.
  • num_main_regs β€” number of 'main status' irq registers, for chips that have main_status set.
  • status_base β€” base status register address. the moment ✨
  • mask_base β€” base mask register address. mask bits are set to 1 when an interrupt is masked, 0 when unmasked.
  • unmask_base β€” base unmask register address. unmask bits are set to 1 when an interrupt is unmasked and 0 when masked. iconique.
  • ack_base β€” base ack address. if zero, then the chip is clear on read. using a zero value is possible with the use_ack bit.
  • wake_base β€” base address for wake enables. if zero, unsupported πŸ™ˆ
  • config_base β€” base address for IRQ type config regs. if null, unsupported.
  • irq_reg_stride β€” the stride to use for chips where registers are not contiguous.
  • init_ack_masked β€” ack all masked interrupts once during initalization.
  • mask_unmask_non_inverted β€” controls mask bit inversion for chips that set both mask_base and unmask_base. if false, mask and unmask bits are inverted (which is deprecated behavior 😬); if true, bits will not be inverted and the registers keep their normal behavior. note that if you use only one of mask_base or unmask_base, this flag has no effect and is unnecessary. any new drivers that set both mask_base and unmask_base should set this to true to avoid relying on the deprecated behavior. do it. don't be that driver πŸ’…
  • use_ack β€” use the ack register even if it is zero.
  • ack_invert β€” inverted ack register: cleared bits for ack.
  • clear_ack β€” use this to set 1 and 0 or vice-versa to clear interrupts.
  • status_invert β€” inverted status register: cleared bits are active interrupts.
  • status_is_level β€” the status register is actuall signal level: xor the status register with the previous value to get the active interrupts.
  • wake_invert β€” inverted wake register: cleared bits are wake disabled.
  • type_in_mask β€” use the mask registers for controlling irq type. use this if the hardware provides separate bits for rising/falling edge or low/high level interrupts and they should be combined into a single logical interrupt. use struct regmap_irq_type data to define the mask bit for each irq type.
  • clear_on_unmask β€” for chips with interrupts cleared on read: read the status registers before unmasking interrupts, to clear any bits set when they were masked.
  • runtime_pm β€” hold a runtime PM lock on the device when accessing it. πŸ”’
  • no_status β€” no status register: all interrupts assumed generated by device.
  • num_regs β€” number of registers in each control bank.
  • irqs β€” descriptors for individual IRQs. interrupt numbers are assigned based on the index in the array of the interrupt.
  • num_irqs β€” number of descriptors.
  • num_config_bases β€” number of config base registers.
  • num_config_regs β€” number of config registers for each config base register.
  • handle_pre_irq β€” driver specific callback to handle an interrupt from the device before regmap_irq_handler processes the interrupts.
  • handle_post_irq β€” driver specific callback to handle an interrupt from the device after handling the interrupts in regmap_irq_handler. bestie bookends 🫢
  • handle_mask_sync β€” callback used to handle IRQ mask syncs. the index will be in the range [0, num_regs)
  • set_type_config β€” callback used for configuring irq types.
  • get_irq_reg β€” callback for mapping (base register, index) pairs to register addresses. the base register will be one of status_base, mask_base, etc., main_status, or any of config_base. the index will be in the range [0, num_main_regs[ for the main status base, [0, num_config_regs[ for any config register base, and [0, num_regs[ for any other base. if unspecified then regmap_irq_get_irq_reg_linear is used.
  • irq_reqres β€” callback function to request IRQ resources (may be NULL)
  • irq_relres β€” callback function to release IRQ resources (may be NULL)
  • irq_drv_data β€” driver specific IRQ data which is passed as parameter when the driver specific pre/post interrupt handler is called.

🌸 DESCRIPTION 🌸

so this whole thing is not intended to handle every possible interrupt controller β€” but it should handle a substantial proportion of those that are found in the wild. no cap, it's a solid generalist 🌈


⭐ SEE ALSO ⭐

kernel file ./include/linux/regmap.h β€” and then the whole extended fam: struct reg_default(9), struct reg_sequence(9), regmap_read_poll_timeout(9), regmap_read_poll_timeout_atomic(9), regmap_field_read_poll_timeout(9), struct regmap_range(9), struct regmap_access_table(9), struct regmap_config(9), struct regmap_range_cfg(9), struct regmap_sdw_mbq_cfg(9), struct regmap_bus(9), regmap_init(9), regmap_init_i2c(9), regmap_init_mdio(9), regmap_init_sccb(9), regmap_init_slimbus(9), regmap_init_spi(9), regmap_init_spmi_base(9), regmap_init_spmi_ext(9), regmap_init_w1(9), regmap_init_mmio_clk(9), regmap_init_mmio(9), regmap_init_ac97(9), regmap_init_sdw(9), regmap_init_sdw_mbq(9), regmap_init_sdw_mbq_cfg(9), regmap_init_i3c(9), regmap_init_spi_avmm(9), regmap_init_fsi(9), devm_regmap_init(9), devm_regmap_init_i2c(9), devm_regmap_init_mdio(9), devm_regmap_init_sccb(9), devm_regmap_init_spi(9), devm_regmap_init_spmi_base(9), devm_regmap_init_spmi_ext(9), devm_regmap_init_w1(9), devm_regmap_init_mmio_clk(9), devm_regmap_init_mmio(9), devm_regmap_init_ac97(9), devm_regmap_init_sdw(9), devm_regmap_init_sdw_mbq(9), devm_regmap_init_sdw_mbq_cfg(9), devm_regmap_init_slimbus(9), devm_regmap_init_i3c(9), devm_regmap_init_spi_avmm(9), devm_regmap_init_fsi(9), struct reg_field(9), struct regmap_irq_type(9), struct regmap_irq(9) πŸ‘‘


that's the whole page, bestie, you ate it πŸ’… this one lives in ./include/linux and it's dated October 2026 β€” struct regmap_irq_chip(9), out 🫢✨

πŸ“¦ where this page comes from