Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 14: Kernel Activities


either callingchip->mask_ackor,ifthisisnotavailable,chip->maskandchip->ackconsecutively. On
multiprocessor systems, a race condition might occur such thathandle_edge_irqis called although the
IRQ is already processed on another CPU. This can be detected by checking for theIRQ_INPROGRESS
flag, and the routine can immediately be left — the IRQ is already being processed on another CPU, in
this case.

If no handler is registered for the IRQ, processing can also be aborted — there is nothing to do. One more
reason to abort processing is whenIRQ_DISABLEDis set. Despite being disabled, broken hardware could
nevertheless issue the IRQ,butitcanbeignored.

Then the proper processing starts.IRQ_INPROGRESSis set to signal that the IRQ is being processed, and
the actual work is delegated tohandle_IRQ_event. This triggers the high-level ISRs, as discussed below.
TheIRQ_INPROGRESScan be removed after the ISRs are finished.

Finally, the IRQ needs to be unmasked. However, the kernel needs to consider that an ISR could have
disabled the interrupt, and in this case, it needs to remain masked. Otherwise, the chip-specific unmask
functionchip->unmaskis used.

Other Types of Interrupts


Besides edge- and level-triggered IRQs, some more less common flow types are also possible. The kernel
also provides default handlers for them.

❑ Modern IRQ hardware requires only very little flow handling. Only one chip-specific function
needs to be called after IRQ processing is finished:chip->eoi. The default handler for this type
ishandle_fasteoi_irq. It is basically identical withhandle_level_irq, except that interaction
with the controller chip is only required at the very end.
❑ Really simple interrupts that require no flow control at all are managed byhandle_simple_irq.
The function can also be used if a caller wants to handle the flow itself.
❑ Per-CPU IRQs, that is, IRQs that can only happen on one specific CPU of a multiprocessor sys-
tem, are handled byhandle_percpu_irq. The function acknowledges the IRQ after reception
and calls the EOI routine after processing. The implementation is very simple because no locking
is required — the code can by definition only run on a single CPU.

14.1.6 Initializing and Reserving IRQs


In this section, we will turn our attention to how IRQs are registered and initialized.

Registering IRQs


Dynamic registration of an ISR by a device driver can be performed very simply using the data structures
described. The function had been implemented by platform-specific code before the interrupt rework in
2.6. Naturally, the prototype was identical on all architecturesasthisisanabsoluteprerequisitefor
programming platform-independent drivers. Nowadays, the function is implemented by common code:

kernel/irq/manage.c
int request_irq(unsigned int irq,
irqreturn_t handler,
unsigned long irqflags, const char *devname, void *dev_id)
Free download pdf