Platform Device Resources In Linux- Free Linux Device Drivers Course

Platform Device Resources In Linux

Free Linux Kernel Development Course — Platform Drivers, Part 2

Kernel 6.x Updated
Beginner Friendly
Original Code Examples

In the previous lecture of this free Linux kernel development course you learned how a platform driver registers itself with module_platform_driver() and how the kernel matches a driver to a device by name. But matching a driver to a device is only half the story. Once matched, the driver needs to know where the hardware actually lives — which memory address it responds to, which IRQ line it fires on, and any private configuration data the board needs to pass down. That information is called a platform device resource, and it is the subject of this lecture.

Understanding platform device resources in Linux kernel programming is one of the most practical skills you can pick up in this free embedded Linux course, because almost every real driver — I2C controllers, UART blocks, GPIO banks, DMA engines — is written on top of this exact mechanism.

Focus Keywords

platform device resources linux kernel
struct resource linux
IORESOURCE_MEM IORESOURCE_IRQ
free linux device drivers course
free embedded systems course

What You Will Learn

struct platform_device internals
struct resource fields
the six IORESOURCE types
how resources reach the driver
device tree vs legacy board files
common resource-definition mistakes

Prerequisites

You should be comfortable with the platform bus concept, struct platform_driver, and the probe()/remove() callbacks covered in the previous lecture of this series. Basic C structures and pointers are assumed.

What Is a Platform Device Resource

A pseudo platform bus has no automatic discovery mechanism the way PCI or USB does. Nothing “enumerates” a UART controller soldered onto a board — the kernel has to be told it exists, where its registers sit in memory, and which interrupt line it uses. That description is packaged inside struct platform_device, specifically in an array of struct resource entries.

Think of a resource as a labelled sticky note the board description attaches to a device: “my registers start here and end here”, or “I will raise interrupt number 47 when I need attention”. The driver never guesses these values — it always asks the kernel for them at probe time.

For example, a device named ep_res_demo with num_resources = 3 would carry a resource array shaped like this:

Index Type Meaning
resource[0] IORESOURCE_MEM First register block
resource[1] IORESOURCE_MEM Second register block
resource[2] IORESOURCE_IRQ Interrupt line

struct resource Fields Explained

Every resource, no matter its type, is represented by the same small structure defined in include/linux/ioport.h:

struct resource (simplified)
struct resource {
    resource_size_t start;
    resource_size_t end;
    const char      *name;
    unsigned long   flags;
};
  • start / end — for a memory or I/O resource these mark the beginning and end address of the region. For an IRQ or a DMA channel, start and end hold the same number.
  • name — a human readable label, useful when a device exposes more than one resource of the same type and you want to fetch a specific one by name.
  • flags — a bitmask that tells the kernel what kind of resource this is: memory, IRQ, DMA channel, and so on.

The Six IORESOURCE Types

Kernel 6.x still defines six resource flags in include/linux/ioport.h. Knowing what each one is for prevents a very common beginner mistake: asking for IORESOURCE_MEM when the board description actually supplied IORESOURCE_IO.

Flag Used For Typical Driver
IORESOURCE_IO Legacy PCI/ISA I/O ports Old x86 peripherals
IORESOURCE_MEM Memory-mapped register regions UART, I2C, SPI controllers
IORESOURCE_REG Register offsets within a shared block Multi-function PMIC devices
IORESOURCE_IRQ Interrupt line number Almost every hardware block
IORESOURCE_DMA DMA channel number Audio codecs, storage controllers
IORESOURCE_BUS Bus number range Bridge / bus controller drivers

How The Kernel Learns About Devices

There are two very different eras of platform resource description, and it helps to know both because you will still meet the old one in legacy code.

The Old, Deprecated Way — Board Files

Before Device Tree existed, every board had a C source file that hand-built an array of struct resource and called platform_device_register(). The driver stayed generic; the board file did all the wiring. This approach does not scale — every new board needs a kernel recompile — and mainline Linux has moved almost entirely away from it.

The Modern Way — Device Tree And ACPI

On kernel 6.x, the overwhelming majority of platform devices are created automatically. A Device Tree node with a reg property and an interrupts property is walked by the of_platform layer, which builds the struct platform_device and its resource array for you before your driver’s probe() is ever called. On ACPI-based systems the equivalent job is done by the ACPI core. Either way, your driver code stays identical — it still calls the same resource-fetching functions you will learn in the next lecture.

The path from firmware description to your driver code follows four steps:

  1. A Device Tree node declares its reg and interrupts properties.
  2. The of_platform bus layer walks that node during boot.
  3. It builds a struct platform_device and populates its resource[] array.
  4. Your driver’s probe() function is called with that fully populated device.

Common Mistakes With Platform Device Resources

Mistake Why It Breaks
Assuming resource index 0 is always memory Order depends entirely on how the device tree or board file listed resources
Not checking the return value of a resource lookup A missing or mistyped device tree property returns NULL, and dereferencing it crashes the kernel
Hard-coding physical addresses in the driver Defeats the whole purpose of the resource abstraction and breaks portability
Forgetting the resource name field when several resources share a type Makes name-based lookup impossible and index-based lookup fragile

Summary And Key Takeaways

  • A platform device resource describes memory regions, IRQ lines, DMA channels or bus numbers that a driver needs.
  • struct resource stores a start/end pair, a name, and a type flag.
  • There are six IORESOURCE flags; IORESOURCE_MEM and IORESOURCE_IRQ are the two you will use constantly.
  • Modern kernel 6.x systems build the resource array automatically from Device Tree or ACPI — you rarely hand-write it yourself anymore.

In the next lecture you will extract these resources inside probe() using platform_get_resource() and platform_get_irq(), and build an original demo driver, ep_res_demo, that reads them out and prints them to the kernel log.

Frequently Asked Questions

What is the difference between a platform device and a platform device resource?

The platform device is the object representing the hardware block itself; a resource is one piece of information attached to that device, such as a memory range or an interrupt number.

Do I still need to write struct resource arrays by hand on kernel 6.x?

Almost never for real hardware. Device Tree or ACPI supplies them automatically. You would still hand-build one for a purely virtual or test platform device.

Can a single platform device have more than one memory resource?

Yes. Many controllers expose more than one register block, so you will commonly see two or three IORESOURCE_MEM entries on the same device.

What happens if I request a resource type that the device does not have?

The lookup function returns NULL, and your probe function must check for that and fail gracefully instead of dereferencing a null pointer.

Is IORESOURCE_IO still relevant on modern ARM or RISC-V boards?

Rarely. IORESOURCE_IO exists mainly for legacy x86 I/O port peripherals; almost all embedded platform drivers use IORESOURCE_MEM instead.

Where can I see the resources the kernel assigned to a device at runtime?

Boot with a verbose log level and check dmesg, or read the device’s entry under /sys/devices, which exposes the matched resource ranges.

Continue The Free Linux Kernel Development Course

Next up: extracting these resources inside probe() with an original hands-on driver example.

 

Leave a Reply

Your email address will not be published. Required fields are marked *