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.
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 i
s 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.
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.
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.
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.
No comments:
Post a Comment