REQUEST_IRQ

Section: Linux Kernel Functions (9)
Updated: 1997/08/14 07:53:47
Page Index

 

NAME

request_irq, free_irq - register an interrupt handler  

SYNOPSIS

#include <asm/irq.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char *devname, void *dev_id);

void free_irq(unsigned int irq, void *dev_id);  

DESCRIPTION

 

Usage

The request_irq() function requests that a specified function (the handler) be called whenever the kernel receives a given interrupt. The handler may in turn register a bottom half, which is usually a slower part of the handler which does not need to be executed as soon as the interrupt is received. See init_bh(9) for more information on bottom halves.

The irq parameter is the interrupt number you want to handle. It must be less than NR_IRQS (16 on Intel systems), and there may be additional limitations on the value. See arch/*/kernel/irq.c (intr.c on m68k machines) for more information.

handler is a pointer to the a pointer to the function that will handle the interrupt. The handler is passed the following parameters:

int irq
The interrupt number. By testing the value of this parameter, it is possible for a single function to handle multiple IRQs.
void *dev_id
The device ID of this handler (see below).
struct pt_regs *regs
The registers stored on the stack of the process that was interrupted. Normally, one shouldn't mess with these, although they can be read to determine, for example, whether the interrupted process was in kernel or user mode.

irqflags is, as the name suggests, a bitmask of flags pertaining to this interrupt handler. Legal bits are:

SA_INTERRUPT
This bit indicates that you are registering a fast interrupt handler. The semantics of this are discussed below.
SA_SHIRQ
This bit indicates that your handler supports sharing an IRQ with other handlers (see also *dev_id below).
SA_SAMPLE_RANDOM
This bit indicates that this IRQ may be used as an entropy source for /dev/random and /dev/urandom (see drivers/char/random.c).
SA_PROBE
This bit indicates that the IRQ is being probed and that the handler being installed is not a real one. It was intended that this value be used internally by probe_irq_on() (q.v.), but it is no longer used in 2.1.x kernels. In fact, even with 2.0.x kernels, it is only used by the MIPS architecture. You should not be using this value unless you know what you are doing.
SA_STATIC_ALLOC
(Sparc/Sparc64 only) This bit requests that your struct irqaction (see below) be added to a statically allocated array of four handlers, rather than the normal irq_action[] table. This is used for IRQs that must be requested early in the boot process, before kmalloc_init() has been called.

The devname parameter is a short name for the device and is displayed in the /proc/interrupts list.

The dev_id parameter is the device ID. This parameter is usually set to NULL, but should be non-null if you wish to do IRQ sharing. This doesn't matter when hooking the interrupt, but is required so that, when free_irq() is called, the correct driver is unhooked. Since this is a void *, it can point to anything (such as a device-specific structure, or even empty space), but make sure you pass the same pointer to free_irq().

The free_irq() function releases an interrupt handler from operation. It takes as parameters the IRQ to unregister, and the device ID of the handler to be unregistered. You should pass the same values here as you did to request_irq(). You probably shouldn't unregister other people's interrupt handlers unless you know what you are doing.  

Operation

For most architectures, request_irq() operates by allocating memory for a struct irqaction, filling out the fields thereof, and adding it to the irq_action[] table. enable_irq() is then called, which simply tells the kernel to start delivering interrupts to the installed handler. This process is vastly different on m68k machines, where it varies depending on what type of machine (Amiga, Atari, etc.) one is using. free_irq() simply removes the entries that request_irq() added. Note that some of these names differ depending on the architecture (for example, struct irqaction is known as struct irq_action on the Power PC). If you need to know more about the internal workings of these functions, you are best off reading the source, as some of this information may have changed by the time you read this (if so, tell me, so I can try to update this page).  

Fast Interrupt Handlers

A `fast' interrupt handler (one with SA_INTERRUPT set) has the following differences from normal `slow' interrupt handlers:

On the ix86 and MIPS, the handler is called with interrupts disabled (they are enabled by default on these machines; on other machines, they are disabled by default).

On the MIPS, a faster return is used.

On the Alpha, MIPS, Sparc, and Sparc64, a fast and a slow handler may not share the same IRQ.

On all architectures except the m68k and the ix86, a `+' is displayed between the interrupt count and the device name in /proc/interrupts.

The slow-versus-fast interrupt distinction is slowly being phased out. For example, under 2.0.x on the ix86, SA_INTERRUPT enabled a fast return as it still does on the MIPS; this distiction was removed in 2.1.x.  

RETURN VALUE

On success, request_irq() returns 0 if everything goes as planned. Your interrupt handler will start receiving its interrupts immediately. On failure, request_irq() returns:
-EINVAL
The IRQ number you requested was either invalid or reserved, or your passed a NULL pointer for the handler() parameter.
-ENOMEM
request_irq() could not allocate enough memory for something (probably the struct irqaction).
-EBUSY
The IRQ you requested is already being handled, and the IRQ cannot be shared. This can occur because either the handler being registered or the handler already present does not have SA_SHIRQ in its irqflags field. In addition, on most architectures, all handlers sharing a single IRQ must be of the same speed; i.e., either all or none of them may have the SA_INTERRUPT flag set. Finally, it is possible that your architecture may not support sharing of the IRQ you are attempting to use.
-ENXIO
The m68k returns this value for an invalid IRQ number.

free_irq() does not return a value.  

AVAILABILITY

Linux 2.1+. The information on this page should work for 2.0.x, but there may be subtle differences (for example, the semantics of SA_INTERRUPT on Intel-based machines). Versions earlier than 2.0 had these functions, but the dev_id parameter was missing. If you want your code to work with versions both earlier and later than 2.0, you should protect your code with preprocessor macros using LINUX_VERSION_CODE.  

SEE ALSO

init_bh(9), probe_irq_on(9), arch/*/kernel/irq.c, arch/*/kernel/entry.S, include/linux/interrupt.h, include/asm*/signal.h.  

AUTHOR

Neil Moore <amethyst@maxwell.ml.org>  

BUGS

It's not exactly a bug, but request_irq() on the m68k is very strange compared to the same function on the other supported architectures. You should really read arch/m68k/kernel/ints.c, arch/m68k/atari/ataints.c, arch/m68k/amiga/amiints.c, and arch/m68k/amiga/cia.c if you plan on writing drivers for any of these systems.


 

Index

NAME
SYNOPSIS
DESCRIPTION
Usage
Operation
Fast Interrupt Handlers
RETURN VALUE
AVAILABILITY
SEE ALSO
AUTHOR
BUGS