Skip to content

Day 79 - IRQ Subsystem Fundamentals

Date

2026-06-17

Goals

  • Understand Linux IRQ subsystem architecture
  • Understand the relationship between IRQ controller, irq_chip, irq_desc, and irq_action
  • Understand IRQ dispatch flow
  • Understand irqreturn_t semantics
  • Prepare for Bottom Half and Threaded IRQ topics

Topics Studied

Linux IRQ Architecture

Linux interrupt handling is layered between hardware interrupt controllers and driver interrupt service routines.

Hardware IRQ
        ↓
IRQ Controller
        ↓
irq_chip
        ↓
irq_desc
        ↓
irq_action
        ↓
Driver ISR

Unlike MCU vector tables, Linux uses a generic IRQ subsystem to dispatch interrupts.


irq_desc

irq_desc represents a Linux IRQ.

Responsibilities:

  • IRQ number
  • Trigger type
  • Associated IRQ controller
  • Registered interrupt action

Simplified model:

struct irq_desc {
    int irq;
    enum irq_trigger_type trigger;
    struct irq_chip *chip;
    struct irq_action *action;
};

irq_action

irq_action represents a registered interrupt handler.

Responsibilities:

  • ISR callback
  • Device private data
  • Handler name

Simplified model:

struct irq_action {
    irq_handler_t handler;
    const char *name;
    void *dev_id;
};

irq_chip

irq_chip abstracts interrupt controller operations.

Responsibilities:

  • Acknowledge interrupt
  • End interrupt

Simplified model:

struct irq_chip {
    const char *name;
    void (*irq_ack)(int irq);
    void (*irq_eoi)(int irq);
};

IRQ Dispatch Flow

The generic IRQ subsystem dispatches interrupts through irq_desc and irq_action.

irq_trigger()
        ↓
irq_dispatch()
        ↓
irq_chip->irq_ack()
        ↓
ISR
        ↓
irq_chip->irq_eoi()

irqreturn_t

Linux interrupt handlers return irqreturn_t.

typedef enum {
    IRQ_NONE = 0,
    IRQ_HANDLED,
    IRQ_WAKE_THREAD,
} irqreturn_t;

Meaning:

Return Value Description
IRQ_NONE Interrupt not handled by this ISR
IRQ_HANDLED Interrupt successfully handled
IRQ_WAKE_THREAD Wake threaded IRQ handler

IRQ Context vs Process Context

ISR executes in IRQ context.

Restrictions:

  • Cannot sleep
  • Cannot use mutex blocking operations
  • Must complete quickly

Typical ISR responsibilities:

  • Read interrupt status
  • Acknowledge interrupt
  • Schedule deferred work
  • Return immediately

Labs Completed

Lab1 - irq_desc and irq_action

Implemented:

  • struct irq_action
  • struct irq_desc
  • request_irq()
  • free_irq()

Refactored IRQ handler ownership from irq_desc into irq_action.


Lab2 - IRQ Dispatch Flow

Implemented:

  • irq_dispatch()

Flow:

irq_trigger()
        ↓
irq_dispatch()
        ↓
irq_action
        ↓
ISR

Lab3 - irq_chip Simulation

Implemented:

  • struct irq_chip
  • irq_ack()
  • irq_eoi()

Flow:

irq_trigger()
        ↓
irq_dispatch()
        ↓
irq_chip->irq_ack()
        ↓
ISR
        ↓
irq_chip->irq_eoi()

Lab4 - irqreturn_t

Implemented:

  • irqreturn_t
  • IRQ_NONE
  • IRQ_HANDLED
  • IRQ_WAKE_THREAD

Verified:

IRQ_HANDLED
IRQ_NONE

dispatch behavior.


Key Takeaways

Linux does not dispatch interrupts directly from vector tables to drivers.

The interrupt path is managed by the Generic IRQ Subsystem.

IRQ Controller
        ↓
irq_chip
        ↓
irq_desc
        ↓
irq_action
        ↓
ISR

Driver interrupt handlers communicate interrupt status through irqreturn_t.

IRQ_NONE
IRQ_HANDLED
IRQ_WAKE_THREAD

This architecture enables interrupt abstraction, shared IRQ support, and threaded interrupt handling.


Next Steps

Day80:

  • Top Half
  • Bottom Half
  • Workqueue as Bottom Half
  • Threaded IRQ
  • request_threaded_irq()
  • Deferred interrupt processing