Skip to content
Snippets Groups Projects
Commit 2017aaef authored by Simon Glass's avatar Simon Glass
Browse files

dm: Update documentation for new bus features


Now that we have new bus features, update README.txt and the SPI docs to
explain these.
Signed-off-by: default avatarSimon Glass <sjg@chromium.org>
parent b2568f0d
No related branches found
No related tags found
No related merge requests found
...@@ -441,11 +441,18 @@ access to other devices. Example of buses include SPI and I2C. Typically ...@@ -441,11 +441,18 @@ access to other devices. Example of buses include SPI and I2C. Typically
the bus provides some sort of transport or translation that makes it the bus provides some sort of transport or translation that makes it
possible to talk to the devices on the bus. possible to talk to the devices on the bus.
Driver model provides a few useful features to help with implementing Driver model provides some useful features to help with implementing buses.
buses. Firstly, a bus can request that its children store some 'parent Firstly, a bus can request that its children store some 'parent data' which
data' which can be used to keep track of child state. Secondly, the bus can can be used to keep track of child state. Secondly, the bus can define
define methods which are called when a child is probed or removed. This is methods which are called when a child is probed or removed. This is similar
similar to the methods the uclass driver provides. to the methods the uclass driver provides. Thirdly, per-child platform data
can be provided to specify things like the child's address on the bus. This
persists across child probe()/remove() cycles.
For consistency and ease of implementation, the bus uclass can specify the
per-child platform data, so that it can be the same for all children of buses
in that uclass. There are also uclass methods which can be called when
children are bound and probed.
Here an explanation of how a bus fits with a uclass may be useful. Consider Here an explanation of how a bus fits with a uclass may be useful. Consider
a USB bus with several devices attached to it, each from a different (made a USB bus with several devices attached to it, each from a different (made
...@@ -460,15 +467,23 @@ Each of the devices is connected to a different address on the USB bus. ...@@ -460,15 +467,23 @@ Each of the devices is connected to a different address on the USB bus.
The bus device wants to store this address and some other information such The bus device wants to store this address and some other information such
as the bus speed for each device. as the bus speed for each device.
To achieve this, the bus device can use dev->parent_priv in each of its To achieve this, the bus device can use dev->parent_platdata in each of its
three children. This can be auto-allocated if the bus driver has a non-zero three children. This can be auto-allocated if the bus driver (or bus uclass)
value for per_child_auto_alloc_size. If not, then the bus device can has a non-zero value for per_child_platdata_auto_alloc_size. If not, then
allocate the space itself before the child device is probed. the bus device or uclass can allocate the space itself before the child
device is probed.
Also the bus driver can define the child_pre_probe() and child_post_remove() Also the bus driver can define the child_pre_probe() and child_post_remove()
methods to allow it to do some processing before the child is activated or methods to allow it to do some processing before the child is activated or
after it is deactivated. after it is deactivated.
Similarly the bus uclass can define the child_post_bind() method to obtain
the per-child platform data from the device tree and set it up for the child.
The bus uclass can also provide a child_pre_probe() method. Very often it is
the bus uclass that controls these features, since it avoids each driver
having to do the same processing. Of course the driver can still tweak and
override these activities.
Note that the information that controls this behaviour is in the bus's Note that the information that controls this behaviour is in the bus's
driver, not the child's. In fact it is possible that child has no knowledge driver, not the child's. In fact it is possible that child has no knowledge
that it is connected to a bus. The same child device may even be used on two that it is connected to a bus. The same child device may even be used on two
...@@ -495,7 +510,8 @@ bus device, regardless of its own views on the matter. ...@@ -495,7 +510,8 @@ bus device, regardless of its own views on the matter.
The uclass for the device can also contain data private to that uclass. The uclass for the device can also contain data private to that uclass.
But note that each device on the bus may be a memeber of a different But note that each device on the bus may be a memeber of a different
uclass, and this data has nothing to do with the child data for each child uclass, and this data has nothing to do with the child data for each child
on the bus. on the bus. It is the bus' uclass that controls the child with respect to
the bus.
Driver Lifecycle Driver Lifecycle
......
...@@ -3,7 +3,8 @@ How to port a SPI driver to driver model ...@@ -3,7 +3,8 @@ How to port a SPI driver to driver model
Here is a rough step-by-step guide. It is based around converting the Here is a rough step-by-step guide. It is based around converting the
exynos SPI driver to driver model (DM) and the example code is based exynos SPI driver to driver model (DM) and the example code is based
around U-Boot v2014.10-rc2 (commit be9f643). around U-Boot v2014.10-rc2 (commit be9f643). This has been updated for
v2015.04.
It is quite long since it includes actual code examples. It is quite long since it includes actual code examples.
...@@ -262,8 +263,8 @@ U_BOOT_DEVICE(board_spi0) = { ...@@ -262,8 +263,8 @@ U_BOOT_DEVICE(board_spi0) = {
.platdata = &platdata_spi0, .platdata = &platdata_spi0,
}; };
You will unfortunately need to put the struct into a header file in this You will unfortunately need to put the struct definition into a header file
case so that your board file can use it. in this case so that your board file can use it.
9. Add the device private data 9. Add the device private data
...@@ -592,3 +593,36 @@ board. ...@@ -592,3 +593,36 @@ board.
You can use 'tools/patman/patman' to prepare, check and send patches for You can use 'tools/patman/patman' to prepare, check and send patches for
your work. See the README for details. your work. See the README for details.
20. A little note about SPI uclass features:
The SPI uclass keeps some information about each device 'dev' on the bus:
struct dm_spi_slave_platdata - this is device_get_parent_platdata(dev)
This is where the chip select number is stored, along with
the default bus speed and mode. It is automatically read
from the device tree in spi_child_post_bind(). It must not
be changed at run-time after being set up because platform
data is supposed to be immutable at run-time.
struct spi_slave - this is device_get_parentdata(dev)
Already mentioned above. It holds run-time information about
the device.
There are also some SPI uclass methods that get called behind the scenes:
spi_post_bind() - called when a new bus is bound
This scans the device tree for devices on the bus, and binds
each one. This in turn causes spi_child_post_bind() to be
called for each, which reads the device tree information
into the parent (per-child) platform data.
spi_child_post_bind() - called when a new child is bound
As mentioned above this reads the device tree information
into the per-child platform data
spi_child_pre_probe() - called before a new child is probed
This sets up the mode and speed in struct spi_slave by
copying it from the parent's platform data for this child.
It also sets the 'dev' pointer, needed to permit passing
'struct spi_slave' around the place without needing a
separate 'struct udevice' pointer.
The above housekeeping makes it easier to write your SPI driver.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment