Device Tree and Manual Registration

I use Embedded Linux on the board, which is mainly configured using the device tree mechanism ( .dts / .dtc ), that is, entries in the device tree file indicate which devices are registered and, therefore, which drivers to load.

Is there a way to manually load the dynamic module in a way that matches what happens when this driver is loaded by the device tree handler?

To clarify: instead of writing to device XXX in my .dts file, can I manually register this device (for example, loading the shell kernel module dynamically) after the user space is already taken (for example, possibly with dts-unaware drivers)?

Using a simple modprobe / insmod not what I think works, as it will just load the driver, but will not register the device and its parameters (which usually come from a .dts file).

+6
source share
1 answer

Dynamically changing the loaded device tree is not what we usually do, although it is possible.

As I understand it, you do not care about the device tree for this new device.

I suggest you create a new module to add your device and, after loading it (after insmod ing), insmod your driver module. Actually, the order doesn't matter. When you add a device, all drivers will be checked, and those that match will be examined, and when you add a driver, all devices will be checked for it.

To create a device, you first select 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 at least one resource for the memory mapped range. To do this, create and populate the struct resource array. A struct resource pretty simple. Here is an example of how to fill a memory resource:

 struct resource res = { .start = 0x50000000, .end = 0x50001fff, .name = "some_name", .flags = IORESOURCE_MEM, }; 

After that, add it to the platform device you are creating:

 platform_device_add_resources(pdev, &res, 1); 

Make sure res not on the stack (make it global or kzalloc and kfree when unloading the module).

You are now ready to add the platform device:

 platform_device_add(pdev); 

Drop the device to the side, platform devices are mapped to platform drivers by the "platform bus" (and not by the actual actual physical bus) by name. Therefore, your platform driver will need to provide an equivalent name ( unique_name_here here). 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 voila. Your driver should be checked if a single-board platform device is added.

Drivers using the device tree will add another member to .driver , which is .of_match_table . Here is a correspondence table (array of strings). Then the match uses the compatible property of the nodes of the device tree.

+9
source

Source: https://habr.com/ru/post/952741/


All Articles