Extract Platform Resources In Probe
Free Linux Kernel Development Course — Platform Drivers, Part 3
The previous lecture explained what a platform device resource is. Now it is time to actually pull those resources out of struct platform_device inside probe(). This lecture on platform_get_resource and platform_get_irq in Linux kernel programming walks through the classic API first, then shows the modern devm_-managed shortcut that kernel 6.x drivers should prefer, and finishes with an original hands-on driver, ep_res_demo, built for this free linux device drivers course.
Focus Keywords
platform_get_irq linux kernel
devm_platform_ioremap_resource
free linux kernel development course
free embedded linux course
What You Will Learn
platform_get_irq() prototype and use
the modern devm_ managed alternative
an original ep_res_demo driver
building, loading and reading dmesg output
best practices and troubleshooting
Prerequisites
Read the previous lecture on platform device resources first — you should already know what struct resource and the IORESOURCE flags mean before extracting them here. A working kernel build environment from earlier lectures in this free linux development course is also assumed.
platform_get_resource() Explained
Every resource stored on a platform_device can be looked up with a single function:
struct resource *platform_get_resource(struct platform_device *dev,
unsigned int type,
unsigned int num);
- dev — the platform device pointer the kernel handed you as the argument to
probe(). - type — one of the IORESOURCE_* flags from the previous lecture, for example
IORESOURCE_MEM. - num — a zero-based index. Passing
0asks for the first resource of that type,1the second, and so on.
The function returns a pointer to the matching struct resource, or NULL if no such resource exists. Always check for NULL before using the pointer — a missing device tree property is a configuration error, not something your driver should crash over.
platform_get_irq() For Interrupt Lines
Interrupts get their own dedicated helper rather than going through the generic function above:
int platform_get_irq(struct platform_device *pdev, unsigned int num);
It returns the IRQ number directly as a plain integer, ready to hand to request_irq(). On kernel 6.x this function already prints a diagnostic error internally and returns a negative error code on failure, so your driver only needs to check if (irqnum < 0) and propagate that as the probe’s return value.
The Modern Shortcut: devm_platform_ioremap_resource()
The classic pattern from older textbooks is: call platform_get_resource(), check it, call ioremap() on the returned range, then remember to call iounmap() in remove(). Kernel 6.x drivers almost never write that by hand anymore, because a resource-managed helper does the whole sequence in a single call and cleans up automatically when the device is unbound:
void __iomem *devm_platform_ioremap_resource(struct platform_device *pdev,
unsigned int index);
This single call finds resource number index of type IORESOURCE_MEM, maps it, and registers the mapping with the device’s resource-managed (devm_) framework. When the driver is removed, the kernel unmaps it for you — there is no matching call needed inside your remove() function. This removes an entire class of bugs where a driver forgets to unmap memory on the error path.
| Approach | Manual iounmap Needed | Recommended On Kernel 6.x |
|---|---|---|
| platform_get_resource() + ioremap() | Yes | Only when you need the raw struct resource itself |
| devm_platform_ioremap_resource() | No | Yes, for the common “map and use” case |
Original Driver Example: ep_res_demo
This driver is written from scratch for this course. It registers itself as a platform driver named ep_res_demo, and in probe() it walks a memory resource and an IRQ resource, printing what it finds to the kernel log. It does not touch any real hardware, so it is safe to load on any virtual machine or development board.
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/io.h>
static int ep_res_demo_probe(struct platform_device *pdev)
{
struct resource *mem_res;
void __iomem *base;
int irqnum;
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem_res) {
dev_err(&pdev->dev, "ep_res_demo: no memory resource found\n");
return -ENODEV;
}
dev_info(&pdev->dev, "ep_res_demo: mem resource %pa - %pa\n",
&mem_res->start, &mem_res->end);
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base)) {
dev_err(&pdev->dev, "ep_res_demo: ioremap failed\n");
return PTR_ERR(base);
}
irqnum = platform_get_irq(pdev, 0);
if (irqnum < 0)
dev_info(&pdev->dev, "ep_res_demo: no irq resource supplied\n");
else
dev_info(&pdev->dev, "ep_res_demo: irq number is %d\n", irqnum);
dev_info(&pdev->dev, "ep_res_demo: probe completed\n");
return 0;
}
static void ep_res_demo_remove(struct platform_device *pdev)
{
dev_info(&pdev->dev, "ep_res_demo: removed\n");
}
static struct platform_driver ep_res_demo_driver = {
.probe = ep_res_demo_probe,
.remove = ep_res_demo_remove,
.driver = {
.name = "ep_res_demo",
},
};
module_platform_driver(ep_res_demo_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("EmbeddedPathashala");
MODULE_DESCRIPTION("Original demo driver showing platform resource extraction");
To register a matching platform device with one dummy memory resource and no interrupt, you can use a short companion module built with platform_device_register_simple(), the same helper introduced in the previous lecture of this series, passing a single IORESOURCE_MEM entry describing an arbitrary demo address range.
Building And Loading
$ make
$ sudo insmod ep_res_demo.ko
$ sudo insmod ep_res_device.ko
$ dmesg | tail -6
Expected Output
ep_res_demo ep_res_demo.0: ep_res_demo: mem resource 0x10000000 - 0x100000ff
ep_res_demo ep_res_demo.0: ep_res_demo: irq number is -19
ep_res_demo ep_res_demo.0: ep_res_demo: no irq resource supplied
ep_res_demo ep_res_demo.0: ep_res_demo: probe completed
The exact addresses will differ depending on what the companion device module registers, but the structure of the log lines confirms the resource walk is working: the memory range prints first, followed by the IRQ lookup, which fails gracefully here because the demo device did not supply one.
Common Mistakes And Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
| probe() crashes with a NULL pointer dereference | Used the resource pointer without checking for NULL | Always test the return value of platform_get_resource() before use |
| Driver leaks memory mappings after repeated bind/unbind | Called raw ioremap() without a matching iounmap() in remove() | Switch to devm_platform_ioremap_resource() |
| platform_get_irq() always returns a negative number | Device tree node has no interrupts property, or wrong index was requested | Confirm the DT node and check num against the actual interrupt count |
| Wrong memory range printed | Requested resource index does not match the intended entry | Use platform_get_resource_byname() when a device has multiple memory regions |
Best Practices
- Prefer
devm_platform_ioremap_resource()over manualioremap()/iounmap()pairs whenever you simply need to map and use a register block. - Always check return values — both
platform_get_resource()andplatform_get_irq()can legitimately fail on real hardware with an incomplete or mistyped device tree. - Use
platform_get_resource_byname()andplatform_get_irq_byname()once a device exposes more than one resource of the same type, so the driver does not depend on device tree ordering. - Log the resources you found with
dev_info()during early bring-up — it saves a lot of time when debugging a new board.
Performance And Security Considerations
Resource extraction itself runs once per probe and has no measurable runtime cost. The security angle is different: never trust resource values sourced from a device tree overlay loaded from an untrusted or removable source without bounds-checking, since a malformed reg property could describe a memory range that overlaps kernel-critical regions.
Summary And Key Takeaways
platform_get_resource()fetches any resource type by index;platform_get_irq()is the dedicated helper for interrupts.- Kernel 6.x drivers should prefer
devm_platform_ioremap_resource()to avoid manual unmap bugs. - Always check for NULL / negative return values before using a resource.
- The original
ep_res_demodriver in this lecture demonstrates the full extraction pattern end to end.
Frequently Asked Questions
What does platform_get_resource() return if the resource is missing?
It returns NULL, so the driver must check before dereferencing the pointer.
Why prefer devm_platform_ioremap_resource() over plain ioremap()?
It automatically releases the mapping when the device is unbound, eliminating a common source of driver memory leaks.
Does platform_get_irq() work the same way for device tree and ACPI systems?
Yes, it abstracts both firmware sources and always hands back a plain Linux IRQ number.
Can I request a resource by name instead of index?
Yes, use platform_get_resource_byname() and platform_get_irq_byname() when a device lists more than one resource of the same type.
Is it safe to call devm_platform_ioremap_resource() more than once in the same probe?
Yes, each call maps a different resource index and each mapping is tracked and released independently by the devm framework.
What should probe() return if a required resource is missing?
Return a negative error code such as -ENODEV so the driver core knows the probe failed and does not keep the device bound.
Continue The Free Linux Kernel Development Course
Next up: passing custom platform data down to your driver alongside these resources.
