How to Implement an IRQ Interrupt Handler in a Linux Kernel Driver (Full Guide)

Interrupts are vital for real-time responsiveness in Linux kernel modules. Whether you’re writing drivers for GPIOs, network interfaces, or custom hardware, implementing IRQ (Interrupt Request) handlers allows the kernel to respond to hardware events asynchronously—without polling.

This tutorial covers:

  • What IRQs are
  • How to register an interrupt handler
  • A sample Linux kernel module
  • Proper cleanup and best practices

📌 What is an IRQ?

IRQ stands for Interrupt Request. When a hardware device needs the CPU’s attention, it sends an IRQ signal. The kernel then interrupts the current process to run the associated handler.


🛠️ Step-by-Step: Implementing an IRQ Handler in a Kernel Module


✅ 1. Include Required Headers

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>

✅ 2. Define Device IRQ and Handler

Choose an IRQ number (you may obtain it via /proc/interrupts or platform_get_irq() for platform devices).

#define MY_IRQ_LINE 19   // Replace with actual IRQ number

static irqreturn_t my_irq_handler(int irq, void *dev_id) {
    printk(KERN_INFO "IRQ %d triggered!\n", irq);
    return IRQ_HANDLED;
}

✅ 3. Request IRQ in init Function

static int __init irq_module_init(void) {
    int result;

    result = request_irq(MY_IRQ_LINE, my_irq_handler, IRQF_SHARED, "my_irq_handler", (void *)(my_irq_handler));
    
    if (result) {
        printk(KERN_ERR "Failed to request IRQ %d\n", MY_IRQ_LINE);
        return result;
    }

    printk(KERN_INFO "IRQ handler registered successfully\n");
    return 0;
}

✅ 4. Free IRQ in exit Function

static void __exit irq_module_exit(void) {
    free_irq(MY_IRQ_LINE, (void *)(my_irq_handler));
    printk(KERN_INFO "IRQ handler unregistered\n");
}

✅ 5. Declare Module Init/Exit

module_init(irq_module_init);
module_exit(irq_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple IRQ handler example");

🔎 Testing the Module

Compile and insert your module:

make
sudo insmod irq_module.ko
dmesg | tail

Trigger the interrupt (depends on your hardware) and observe:

cat /proc/interrupts

Check for your IRQ number and count increment.


⚠️ Important Notes

TipExplanation
Use IRQF_SHAREDIf IRQ is shared among multiple devices
Always free_irq()Prevent memory leaks or undefined behavior on module unload
Avoid heavy processing in handlerDefer using tasklets or workqueues if needed

Implementing an interrupt handler in a Linux kernel driver is a core skill for low-level systems programmers. By correctly registering and cleaning up IRQs, you ensure your driver responds quickly to hardware events—without hogging CPU cycles.

With this knowledge, you can now:

  • Handle GPIO interrupts
  • Build event-driven drivers
  • Expand into threaded IRQs or real-time Linux work

Have you implemented IRQ handlers in your drivers?
Need help debugging spurious interrupts or shared IRQ conflicts? Drop your thoughts and questions in the comments below! 🧑‍💻👇

Leave a Comment