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.
Device trees do not need to be compiled with "architecture-aware" tools. The dtc compiler on your ubuntu machine is probably current enough to compile your device tree. Or you can download the latest source and compile it yourself. The dtc compiler can be found here:
https://git.kernel.org/pub/scm/utils/dtc/dtc.git
There are some good documents in that package that will help you better understand device trees in general.
It's pretty easy to compile (and disassemble) device trees. For example
$ dtc -O dtb -o p4080ds.dtb p4080ds.dts
To get the device tree in text from from the device tree blob, do this:
$ dtc -I dtb -O dts p4080ds.dtb
Hope this helps!
Best Solution
https://linux-sunxi.org/Device_Tree#Compiling_the_Device_Tree
Device tree sources in the kernel deviate from the regular syntax, by using the cpp preprocessor for includes and substitution. This proceeds as follows: