What is the difference between setup_irq and request_irq in Linux kernel interrupts ?

Timers are setup very early, before the request_irq() infrastructure has been initialised. Hence, setup_irq is used to initialises timer irqs, while normal drivers should use request_irq.

setup_irq is defined in kernel/irq/manage.c as,

/**
 *      setup_irq - setup an interrupt
 *      @irq: Interrupt line to setup
 *      @act: irqaction for the interrupt
 *
 * Used to statically setup interrupts in the early boot process.
 */
int setup_irq(unsigned int irq, struct irqaction *act)
{
        int retval;
        struct irq_desc *desc = irq_to_desc(irq);

        if (!desc || WARN_ON(irq_settings_is_per_cpu_devid(desc)))
                return -EINVAL;

        retval = irq_chip_pm_get(&desc->irq_data);
        if (retval < 0)
                return retval;

        chip_bus_lock(desc);
        retval = __setup_irq(irq, desc, act);
        chip_bus_sync_unlock(desc);

        if (retval)
                irq_chip_pm_put(&desc->irq_data);

        return retval;
}
EXPORT_SYMBOL_GPL(setup_irq);

whereas, request_irq is defined in include/linux/interrupt.h as

tatic inline int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
            const char *name, void *dev)
{
        return request_threaded_irq(irq, handler, NULL, flags, name, dev);
}

request_threaded_irq is defined in kernel/irq/manage.c as,

[c]
/**
 *      request_threaded_irq - allocate an interrupt line
 *      @irq: Interrupt line to allocate
 *      @handler: Function to be called when the IRQ occurs.
 *                Primary handler for threaded interrupts
 *                If NULL and thread_fn != NULL the default
 *                primary handler is installed
 *      @thread_fn: Function called from the irq handler thread
 *                  If NULL, no irq thread is created
 *      @irqflags: Interrupt type flags
 *      @devname: An ascii name for the claiming device
 *      @dev_id: A cookie passed back to the handler function
 *
 *      This call allocates interrupt resources and enables the
 *      interrupt line and IRQ handling. From the point this
 *      call is made your handler function may be invoked. Since
 *      your handler function must clear any interrupt the board
 *      raises, you must take care both to initialise your hardware
 *      and to set up the interrupt handler in the right order.
 *      If you want to set up a threaded irq handler for your device
 *      then you need to supply @handler and @thread_fn. @handler is
 *      still called in hard interrupt context and has to check
 *      whether the interrupt originates from the device. If yes it
 *      needs to disable the interrupt on the device and return
 *      IRQ_WAKE_THREAD which will wake up the handler thread and run
 *      @thread_fn. This split handler design is necessary to support
 *      shared interrupts.
 *
 *      Dev_id must be globally unique. Normally the address of the
 *      device data structure is used as the cookie. Since the handler
 *      receives this value it makes sense to use it.
 *
 *      If your interrupt is shared you must pass a non NULL dev_id
 *      as this is required when freeing the interrupt.
 *
 *      Flags:
 *
 *      IRQF_SHARED             Interrupt is shared
 *      IRQF_TRIGGER_*          Specify active edge(s) or level
 *
 */
int request_threaded_irq(unsigned int irq, irq_handler_t handler,
                         irq_handler_t thread_fn, unsigned long irqflags,
                         const char *devname, void *dev_id)
{
}

Leave a Comment