I'm using Embedded Linux on a board that is mainly configured via the device tree mechanism (.dts
/.dtc
files), i.e. entries in the device tree file indicate which devices to register and thereby which drivers to load.
Is there a way to manually load a dynamic module in a way that resembles what would happen when this driver would be loaded by the device tree handler?
To clarify: instead of having an entry for device XXX in my .dts
file, can I "manually" register this device (for example by loading a wrapper kernel module dynamically) after the user space is already up (like it is possible with dts-unaware drivers)?
Using a simple modprobe
/insmod
is not what I think works, since this would just load the driver, but not register a device and its parameters (that usually come from the .dts
file).
Dynamically modifying the loaded device tree is not something we usually do, although it's possible.
I understand you don't really care about the device tree for this new device.
I suggest you create a new module to add your device and, once it's loaded (after insmod
ing it), insmod
your driver module. In fact, the order doesn't matter. When you add a device, all drivers will be checked and the ones that match will be probed, and when you add a driver, all devices are checked against it.
To create the device, you first allocate it:
struct platform_device *pdev;
int inst_id = 1; /* instance unique ID: base address would be a good choice */
pdev = platform_device_alloc("unique_name_here", inst_id);
Then, you will want to create resources, at least one for the memory mapped range. For this, create and fill an array of struct resource
. A struct resource
is pretty simple. Here's an example on how to fill a memory resource:
struct resource res = {
.start = 0x50000000,
.end = 0x50001fff,
.name = "some_name",
.flags = IORESOURCE_MEM,
};
Once you have that, add it to the platform device you're building:
platform_device_add_resources(pdev, &res, 1);
Make sure res
is not on the stack, though (make it global, or kzalloc
it and kfree
when unloading the module).
You're now ready to add the platform device:
platform_device_add(pdev);
Device tree aside, platform devices are matched to platform drivers by the "platform bus" (not a real actual physical bus) by name. So your platform driver will need to provide an equivalent name (unique_name_here
hereabove). Your platform driver will have something like:
static struct platform_driver my_platform_driver = {
.probe = my_probe,
.remove = my_remove,
.driver = {
.name = "unique_name_here",
.owner = THIS_MODULE,
},
};
module_platform_driver(my_platform_driver);
and voilà. Your driver should be probed if a platform device with the same name was added.
Drivers using the device tree add another member to .driver
, which is .of_match_table
. A match table (array of strings) is given there. The match is then using the compatible
property of device tree nodes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With