Issue
I am trying to create a platform driver I have the following code
Module
// SPDX-License-Identifier: GPL-2.0
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/of_device.h>
#include <linux/fb.h>
static int simple_probe(struct platform_device *pdev)
{
printk(KERN_ERR "SIMPLE: %s\n", "Probing");
return 0;
}
const struct of_device_id simple_of_match[] = {
{
.compatible = "example,simple",
},
{ /*End of List*/ },
};
struct platform_driver simple_driver = {
.probe = simple_probe,
.driver = {
.name = "simple",
.owner = THIS_MODULE,
.of_match_table = simple_of_match
}
};
static int __init init(void)
{
if (platform_driver_register(&simple_driver)) {
printk(KERN_ERR "SIMPLE: %s\n", "Registerered");
} else {
printk(KERN_ERR "SIMPLE: %s\n", "Failed");
}
return 0;
}
static void __exit deinit(void)
{
platform_driver_unregister(&simple_driver);
}
module_init(init);
module_exit(deinit);
MODULE_DESCRIPTION("Simple Platform driver");
MODULE_AUTHOR("Bret Joseph Antonio <[email protected]>");
MODULE_LICENSE("GPL");
My device tree doesn't seem to be running an overlay so the devices status is ok. It is still not running the probe callback.
DEVICE TREE
/dts-v1/;
/ {
simple@0 {
compatible = "example,simple";
pinctrl-names = "lcm_rst_out1_gpio", "lcm_rst_out0_gpio";
pinctrl-0 = <&PHANDLE1>;
pinctrl-1 = <&PHANDLE2>;
status = "okay";
};
};
I am expecting the kernel to register my driver and then run the probe function but the code
if (platform_driver_register(&simple_driver) == 0) {
printk(KERN_ERR "SIMPLE: %s\n", "Registered");
} else {
printk(KERN_ERR "SIMPLE: %s\n", "Failed");
}
returns [ 0.178889] SIMPLE: Registered
but the probe function remains silent. What does the probe function depend on?
Shouldn't it run probe as soon as it finds the node in the device tree?
Solution
You need to export your struct of_device_id simple_of_match[]
to the of (Open Firmware) subsystem with a MODULE_DEVICE_TABLE(of, simple_of_match);
statement. This will create the required alias
entry for the module during build time.
Consolation is that other kernel drivers in mainline have been patched for this very same omission, e.g. [PATCH] mtd: nand: tango: Export OF device ID table as module aliases and [PATCH] pwm: samsung: Use MODULE_DEVICE_TABLE() to include OF modalias.
That latter patch mentions:
If the ... driver is built as a module, modalias information is not filled so the module is not autoloaded. Use the MODULE_DEVICE_TABLE() macro to export the OF device ID so the module contains that information.
That implies that if your driver was always a built-in module rather than a loadable module, then you would not need to have a MODULE_DEVICE_TABLE(of, simple_of_match);
statement.
Convention for kernel code is to declare all symbols as static whenever possible. Your code is inconsistent in that regard, i.e. struct of_device_id simple_of_match[]
and struct platform_driver simple_driver
are global.
Suggested edits in patch form:
- const struct of_device_id simple_of_match[] = {
+ static struct of_device_id simple_of_match[] = {
{
.compatible = "example,simple",
},
{ /*End of List*/ },
};
+ MODULE_DEVICE_TABLE(of, simple_of_match);
- struct platform_driver simple_driver = {
+ static struct platform_driver simple_driver = {
.probe = simple_probe,
.driver = {
.name = "simple",
.owner = THIS_MODULE,
.of_match_table = simple_of_match
}
};
Answered By - sawdust Answer Checked By - Timothy Miller (WPSolving Admin)