Reader small image

You're reading from  Linux Device Driver Development - Second Edition

Product typeBook
Published inApr 2022
PublisherPackt
ISBN-139781803240060
Edition2nd Edition
Right arrow
Author (1)
John Madieu
John Madieu
author image
John Madieu

John Madieu is an embedded Linux and kernel engineer living in Paris, France. His main activities consist of developing device drivers and Board Support Packages (BSPs) for companies in domains such as IoT, automation, transport, healthcare, energy, and the military. John is the founder and chief consultant at LABCSMART, a company that provides training and services for embedded Linux and Linux kernel engineering. He is an open source and embedded systems enthusiast, convinced that it is only by sharing knowledge that we can learn more. He is passionate about boxing, which he practiced for 6 years professionally, and continues to channel this passion through training sessions that he provides voluntarily.
Read more about John Madieu

Right arrow

Chapter 13: Demystifying the Kernel IRQ Framework

Linux is a system on which devices notify the kernel about events by means of interrupt requests (IRQs), though some devices are polled. The CPU exposes IRQ lines, shared or not, used by connected devices so that when a device needs the CPU, it sends a request to the CPU. When the CPU gets this request, it stops its actual job and saves its context, in order to serve the request issued by the device. After serving the device, its state is restored back to exactly where it stopped when the interruption occurred.

In this chapter, we will deal with the APIs that the kernel offers to manage IRQs and the ways in which multiplexing can be done. Moreover, we will analyze and look closer at interrupt controller driver writing.

To summarize, in this chapter, the following topics will be covered:

  • Brief presentation of interrupts
  • Understanding interrupt controllers and interrupt multiplexing
  • Diving into advanced peripheral...

Brief presentation of interrupts

On many platforms, a special device is responsible for managing IRQ lines. That device is the interrupt controller and it stands between the CPU and the interrupt lines it manages. The following is a diagram that shows the interactions that take place:

Figure 13.1 – Interrupt controller and IRQ lines

Not only can devices raise interrupts, but some processor operations can do that too. There are then two different kinds of interrupts:

  • Synchronous interrupts, called exceptions, are produced by the CPU while processing instructions. These are non-maskable interrupts (NMIs) and result from a critical malfunction such as hardware failure. They are always processed by the CPU.
  • Asynchronous interrupts, called interrupts, are issued by other hardware devices. These are normal and maskable interrupts. These are what we will discuss in the next sections of this chapter.

Before getting deeper into interrupt management...

Understanding interrupt controllers and interrupt multiplexing

Having a single interrupt from the CPU is usually not enough. Most systems have tens or hundreds of them. Now comes interrupt controller, which allows them to be multiplexed. Very often, architecture or platform-specific implementations offer specific facilities, such as the following:

  • Masking/unmasking individual interrupts
  • Setting priorities
  • SMP affinity
  • Exotic features, such as wake-up interrupts

IRQ management and interrupt controller drivers both rely on the concept of the IRQ domain, which is built on top of the following structures:

  • struct irq_chip: This is the interrupt controller data structure. This structure also implements a set of methods that allow to drive the interrupt controller and that are directly called by core IRQ code.
  • struct irqdomain: This provides the following options:
    • A pointer to the interrupt controller's firmware node (fwnode)
    • A function for converting...

Diving into advanced peripheral IRQ management

In Chapter 3, Dealing with Kernel Core Helpers, we introduced peripheral IRQs, using request_irq() and request_threaded_irq(). With the former, you register a handler (top half) that will be executed in an atomic context, from which you can schedule a bottom half using one of the mechanisms discussed in that same chapter. On the other hand, with the _threaded variant, you can provide top and bottom halves to the function, so that the former will be run as the hard IRQ handler, which may decide to raise the second and threaded handler or not, which will be run in a kernel thread.

The problem with those approaches is that sometimes, drivers requesting an IRQ do not know about the nature of the interrupt controller that provides this IRQ line, especially when the interrupt controller is a discrete chip (typically a GPIO expander connected over SPI or I2C buses). Now comes the request_any_context_irq()function with which drivers requesting...

Demystifying per-CPU interrupts

The most common ARM interrupt controller, GIC in the ARM multi-core processor, supports three types of interrupts:

  • CPU private interrupts: These interrupts are private per CPU. If triggered, such a per-CPU interrupt will exclusively be serviced on the target CPU or CPU to which it is bound. Private interrupts can be split into two families:
    • Private peripheral interrupts (PPIs): These are private and can only be generated by hardware bound to the CPU.
    • Software-generated interrupts (SGIs): Unlike PPIs, these are generated by the software. Thanks to this, SGIs are usually used as interrupt IPIs for inter-core communication on multi-core systems, meaning that one CPU can generate an interrupt (by writing the appropriate message, made of the interrupt ID and the target CPU to the GIC controller) to (an)other CPU(s). This is what we will talk about in this section.
  • Shared peripheral interrupts (SPIs) (not to be confused with the SPI bus): These...

Summary

Now, IRQ multiplexing has no more secrets from you. We have discussed the most important element of IRQ management in Linux systems: the IRQ domain API. You have the basics to understand existing interrupt controller drivers, as well as their binding from within the DT. IRQ propagation has been discussed in order to explore what happens between the request and the handler invocation.

In the next chapter, we deal with a completely different topic: the Linux device model.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Linux Device Driver Development - Second Edition
Published in: Apr 2022Publisher: PacktISBN-13: 9781803240060
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
John Madieu

John Madieu is an embedded Linux and kernel engineer living in Paris, France. His main activities consist of developing device drivers and Board Support Packages (BSPs) for companies in domains such as IoT, automation, transport, healthcare, energy, and the military. John is the founder and chief consultant at LABCSMART, a company that provides training and services for embedded Linux and Linux kernel engineering. He is an open source and embedded systems enthusiast, convinced that it is only by sharing knowledge that we can learn more. He is passionate about boxing, which he practiced for 6 years professionally, and continues to channel this passion through training sessions that he provides voluntarily.
Read more about John Madieu