summaryrefslogtreecommitdiff
path: root/doc/driver-model
diff options
context:
space:
mode:
Diffstat (limited to 'doc/driver-model')
-rw-r--r--doc/driver-model/README.txt91
-rw-r--r--doc/driver-model/spi-howto.txt44
2 files changed, 82 insertions, 53 deletions
diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt
index eafa825..f83264d 100644
--- a/doc/driver-model/README.txt
+++ b/doc/driver-model/README.txt
@@ -363,6 +363,10 @@ can leave out platdata_auto_alloc_size. In this case you can use malloc
in your ofdata_to_platdata (or probe) method to allocate the required memory,
and you should free it in the remove method.
+The driver model tree is intended to mirror that of the device tree. The
+root driver is at device tree offset 0 (the root node, '/'), and its
+children are the children of the root node.
+
Declaring Uclasses
------------------
@@ -384,12 +388,12 @@ Device Sequence Numbers
U-Boot numbers devices from 0 in many situations, such as in the command
line for I2C and SPI buses, and the device names for serial ports (serial0,
serial1, ...). Driver model supports this numbering and permits devices
-to be locating by their 'sequence'. This numbering unique identifies a
+to be locating by their 'sequence'. This numbering uniquely identifies a
device in its uclass, so no two devices within a particular uclass can have
the same sequence number.
Sequence numbers start from 0 but gaps are permitted. For example, a board
-may have I2C buses 0, 1, 4, 5 but no 2 or 3. The choice of how devices are
+may have I2C buses 1, 4, 5 but no 0, 2 or 3. The choice of how devices are
numbered is up to a particular board, and may be set by the SoC in some
cases. While it might be tempting to automatically renumber the devices
where there are gaps in the sequence, this can lead to confusion and is
@@ -399,7 +403,7 @@ Each device can request a sequence number. If none is required then the
device will be automatically allocated the next available sequence number.
To specify the sequence number in the device tree an alias is typically
-used.
+used. Make sure that the uclass has the DM_UC_FLAG_SEQ_ALIAS flag set.
aliases {
serial2 = "/serial@22230000";
@@ -409,43 +413,18 @@ This indicates that in the uclass called "serial", the named node
("/serial@22230000") will be given sequence number 2. Any command or driver
which requests serial device 2 will obtain this device.
-Some devices represent buses where the devices on the bus are numbered or
-addressed. For example, SPI typically numbers its slaves from 0, and I2C
-uses a 7-bit address. In these cases the 'reg' property of the subnode is
-used, for example:
-
-{
- aliases {
- spi2 = "/spi@22300000";
- };
-
- spi@22300000 {
- #address-cells = <1>;
- #size-cells = <1>;
- spi-flash@0 {
- reg = <0>;
- ...
- }
- eeprom@1 {
- reg = <1>;
- };
- };
-
-In this case we have a SPI bus with two slaves at 0 and 1. The SPI bus
-itself is numbered 2. So we might access the SPI flash with:
-
- sf probe 2:0
+More commonly you can use node references, which expand to the full path:
-and the eeprom with
-
- sspi 2:1 32 ef
-
-These commands simply need to look up the 2nd device in the SPI uclass to
-find the right SPI bus. Then, they look at the children of that bus for the
-right sequence number (0 or 1 in this case).
+aliases {
+ serial2 = &serial_2;
+};
+...
+serial_2: serial@22230000 {
+...
+};
-Typically the alias method is used for top-level nodes and the 'reg' method
-is used only for buses.
+The alias resolves to the same string in this case, but this version is
+easier to read.
Device sequence numbers are resolved when a device is probed. Before then
the sequence number is only a request which may or may not be honoured,
@@ -462,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
possible to talk to the devices on the bus.
-Driver model provides a few useful features to help with implementing
-buses. Firstly, a bus can request that its children store some 'parent
-data' which can be used to keep track of child state. Secondly, the bus can
-define methods which are called when a child is probed or removed. This is
-similar to the methods the uclass driver provides.
+Driver model provides some useful features to help with implementing buses.
+Firstly, a bus can request that its children store some 'parent data' which
+can be used to keep track of child state. Secondly, the bus can define
+methods which are called when a child is probed or removed. This is similar
+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
a USB bus with several devices attached to it, each from a different (made
@@ -481,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
as the bus speed for each device.
-To achieve this, the bus device can use dev->parent_priv in each of its
-three children. This can be auto-allocated if the bus driver has a non-zero
-value for per_child_auto_alloc_size. If not, then the bus device can
-allocate the space itself before the child device is probed.
+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 (or bus uclass)
+has a non-zero value for per_child_platdata_auto_alloc_size. If not, then
+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()
methods to allow it to do some processing before the child is activated or
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
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
@@ -516,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.
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
-on the bus.
+on the bus. It is the bus' uclass that controls the child with respect to
+the bus.
Driver Lifecycle
diff --git a/doc/driver-model/spi-howto.txt b/doc/driver-model/spi-howto.txt
index 719dbd5..ee4abf4 100644
--- a/doc/driver-model/spi-howto.txt
+++ b/doc/driver-model/spi-howto.txt
@@ -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
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.
@@ -39,8 +40,8 @@ with only minor changes:
Add these to your board config:
-#define CONFIG_DM_SPI
-#define CONFIG_DM_SPI_FLASH
+CONFIG_DM_SPI
+CONFIG_DM_SPI_FLASH
2. Add the skeleton
@@ -262,8 +263,8 @@ U_BOOT_DEVICE(board_spi0) = {
.platdata = &platdata_spi0,
};
-You will unfortunately need to put the struct into a header file in this
-case so that your board file can use it.
+You will unfortunately need to put the struct definition into a header file
+in this case so that your board file can use it.
9. Add the device private data
@@ -592,3 +593,36 @@ board.
You can use 'tools/patman/patman' to prepare, check and send patches for
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.