The story of device tree for platfrom device….

The whole story starts from non discover-able devices in the system. This post will provide you information about non discoverable devices as well it will provide you one of way of Linux kernel to deal with it. The second and fresh way is device tree.

Kernel starts, it has to initialize the drivers for the devices on the board. But often on embedded systems, devices can’t be discover at running time(i2c, spi, etc.). In this case, the Linux kernel has a c (board file) file that initialize these devices for the board. The below image shows structure for non discoverable devices and platform data for same. This will be registered with the virtual bus named platform bus and driver will also register it self with platform bus with the same name.

In this method,  kernel must be modified/compiled for each board or change in hardware on board.  Kernels are typically built around a single board file and cannot boot on any other type of system. Solution of this situation is provided by “Device tree”. A device tree is a tree data structure with nodes that describe the physical devices on the board. While using device tree, kernel no longer contains the description of the hardware, it is located in a separate binary blob called the device tree blob. The device tree is passed to the kernel at boot time. Kernel reads through it to learn about what kind of system it is. So on the change of board only developer needs to change device tree blob and that it new port of kernel is ready.

Platfrom device

Platform device

Here, you will get a good article on device tree format. It is recommended to go through it first at this stage.

Platform devices can work with dtb enabled system with out any extra modification. If the device tree includes a platform device that device will be instantiated and matched against a driver. All resource data will be available to the driver probe() in a usual way. The driver dose now know wither this device is not initialized with hard-cored. in board file.

Every device in the system is represented by a device tree node. The next step is to populate the tree with a node for each of the devices. The snippet below shows the dtb with node name “ps7-xadc”.  Every node in the tree represents a device, which must have a compatible property. compatible is the key using which an operating system uses to decide which device driver to bind to a device. In short compatible(ps7-xadc-1.00-a) specifies the name of the platform device which will get registered with bus.

Platform device in DTB

Platform device in DTB

On other side, in device driver when platform deriver structure is declared, it stores a pointer to “of_device_id”. This is shown by the below snippet. This name should be same which was given in the dtb file.  Now, when driver with name of “ps7-xadc-1.00.a” will get register with the platform bus, probe of that driver will get called.

Platform driver registration

Platform driver registration

The below snippet shows the probe function of the driver. In the probe, function platform_get_resource() provides property described by “reg” in dtb file. In our case base address of register set(0xf8007100) for hardware module and offset from the base address(0x20)  can be retrieved. Using which driver can request the memory region form the kernel. As same, function platform_get_irq() provides the property which id describe by “interrupts” in dtb file.

Getting device specific data

Getting device specific data

After garbing all details from dtb file, probe will register device as a normal way.  This is very straight forward procedure using which platform drivers work with device trees. As a result of this,  no need to declare platform_device in board file.

Cheers !!!

4 Comments

Filed under Device tree, Linux Device Driver, Platfrom device, Uncategorized

4 responses to “The story of device tree for platfrom device….

  1. ravi sankar

    Nice explanation.I studied different sites but i didnt get clear explanatioin.Really u explained well.Thanky you

  2. Muhammed

    Thank you very much for your blog and for your time and effort done and sharings , your blog really helped me very much in understanding difficult points .Once again thank you very much.

  3. Kushal

    Can you please brief about the platfrom_get_resource API, which address you are retrieving from dtb ? whether 0xf8_ _ _ _ _ or 0x20 ? If you retrieving 0xf8 _ _ _ +0x20 what is the complete address you will be able to access in driver ?
    And why devm_ioremap_resource API is required ?

  4. shah.b

    Basically, platfrom_get_resource API used to get information on the structure of device tree. The first parameter tells the function which device we are interested in. The second parameter depends on what kind of resource you are handling. If it is memory( or anything that can be mapped as memory :-)) then it’s IORESOURCE_MEM. You can see all the macros at include/linux/ioport.h. The “n” parameter says which resource of that type is desired, with zero indicating the first one.

    I will get 0xf8____ as the base address of resource and 0x20 is size of resource. So i am interested in accessing memory from 0xF8007100 to 0xF8007120.

    In Linux you need to request memory before you are using it. So devm_ioremap_resource() checks resource(memory), requests memory region to use (read/Write) by driver.

Leave a comment