next up previous
Next: Examples Up: PARAPIN: A Parallel Port Previous: Polling Input Pins


Interrupt (IRQ) Handling

The kernel-module version of Parapin lets parallel port drivers catch interrupts generated by devices connected to the parallel port. Most hardware generates interrupts on the rising edge1 of the input to Pin 10.

Before Parapin's interrupt-handling can be used, the Linux kernel itself must be configured to handle parallel port interrupts. Unlike most other hardware devices, the kernel does not detect or claim the parallel port's interrupts by default. It is possible to manually enable kernel IRQ handling for the parallel port by writing the interrupt number into the special file /proc/parport/$n$/irq, where $n$ is the parallel port number. For example, the following command tells the kernel that parport0 is using IRQ 7:

        echo 7 > /proc/parport/0/irq
If parallel port support is being provided to the kernel through modules, it is also possible to configure the IRQ number as an argument to the parport_pc module when it is loaded. For example:
        insmod parport
        insmod parport_pc io=0x378 irq=7
Note that both the io and irq arguments are required, even if the parallel port is using the default I/O base address of 0x378.

The actual interrupt number used by the kernel (7 in the examples above) must, of course, match the interrupt line being used by the hardware. The IRQ used by the parallel port hardware is usually configured in the BIOS setup screen on modern motherboards that have built-in parallel ports. Older motherboards or stand-alone ISA cards usually have jumpers or DIP switches for configuring the interrupt number. The typical assignment of interrupts to parallel ports is as follows:

Port Interrupt
LPT1 7
LPT2 5

These are reasonable defaults if the actual hardware configuration is not known.

As described in Section 5, the pin_init_kernel() function allows installation of an interrupt handler function by passing a pointer to the handler as the second argument. A NULL value for this parameter means that interrupts are disabled. A non-NULL value should be a pointer to a callback function that has the following prototype:

        void my_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs);

If and only if a pointer to such a handler function is passed to pin_init_kernel, the following functions can then be used to turn interrupts on and off:

        pin_enable_irq();
        pin_disable_irq();

Parapin turns parallel port interrupts off by default. That is, no interrupts will be generated until after a call to pin_init_kernel() to install the interrupt handler, and a subsequent call to pin_enable_irq();

Interrupts must not be enabled and disabled from within the interrupt handler itself. In other words, the interrupt handling function passed to pin_init_kernel() must not call pin_enable_irq() or pin_disable_irq(). However, the handler function does not need to be reentrant: the IRQ line that causes an interrupt handler to run is automatically disabled by the Linux kernel while the interrupt's handler is running. There are other important restrictions on kernel programming in general and interrupt-handler writing in particular; these issues are beyond the scope of this document. For more details, the reader is referred to the Linux kernel programming guides mentioned in Section 3.

Some PC hardware generates a spurious parallel port interrupt immediately after the parallel port's interrupts are enabled (perhaps to help auto-detection of the IRQ number). Parapin includes a workaround that prevents this interrupt from being delivered. This is done to ensure consistent interrupt behavior across all platforms.


next up previous
Next: Examples Up: PARAPIN: A Parallel Port Previous: Polling Input Pins
Jeremy Elson 2000-03-30