mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2026-03-05 17:00:59 +01:00
Merge "dm: Add callback to modify the device tree"
This commit is contained in:
commit
182d29b9ec
4 changed files with 153 additions and 0 deletions
|
|
@ -763,6 +763,13 @@ static int setup_reloc(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_BOARD_FIXUP
|
||||
static int fix_fdt(void)
|
||||
{
|
||||
return board_fix_fdt((void *)gd->fdt_blob);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ARM calls relocate_code from its crt0.S */
|
||||
#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX)
|
||||
|
||||
|
|
@ -1026,6 +1033,9 @@ static init_fnc_t init_sequence_f[] = {
|
|||
display_new_sp,
|
||||
#ifdef CONFIG_SYS_EXTBDINFO
|
||||
setup_board_extra,
|
||||
#endif
|
||||
#ifdef CONFIG_OF_BOARD_FIXUP
|
||||
fix_fdt,
|
||||
#endif
|
||||
INIT_FUNC_WATCHDOG_RESET
|
||||
reloc_fdt,
|
||||
|
|
|
|||
132
doc/driver-model/fdt-fixup.txt
Normal file
132
doc/driver-model/fdt-fixup.txt
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
Pre-relocation device tree manipulation
|
||||
=======================================
|
||||
|
||||
Contents:
|
||||
|
||||
1. Purpose
|
||||
2. Implementation
|
||||
3. Example
|
||||
4. Work to be done
|
||||
|
||||
1. Purpose
|
||||
----------
|
||||
|
||||
In certain markets, it is beneficial for manufacturers of embedded devices to
|
||||
offer certain ranges of products, where the functionality of the devices within
|
||||
one series either don't differ greatly from another, or can be thought of as
|
||||
"extensions" of each other, where one device only differs from another in the
|
||||
addition of a small number of features (e.g. an additional output connector).
|
||||
|
||||
To realize this in hardware, one method is to have a motherboard, and several
|
||||
possible daughter boards that can be attached to this mother board. Different
|
||||
daughter boards then either offer the slightly different functionality, or the
|
||||
addition of the daughter board to the device realizes the "extension" of
|
||||
functionality to the device described previously.
|
||||
|
||||
For the software, we obviously want to reuse components for all these
|
||||
variations of the device. This means that the software somehow needs to cope
|
||||
with the situation that certain ICs may or may not be present on any given
|
||||
system, depending on which daughter boards are connected to the motherboard.
|
||||
|
||||
In the Linux kernel, one possible solution to this problem is to employ the
|
||||
device tree overlay mechanism: There exists one "base" device tree, which
|
||||
features only the components guaranteed to exist in all varieties of the
|
||||
device. At the start of the kernel, the presence and type of the daughter
|
||||
boards is then detected, and the corresponding device tree overlays are applied
|
||||
to support the components on the daughter boards.
|
||||
|
||||
Note that the components present on every variety of the board must, of course,
|
||||
provide a way to find out if and which daughter boards are installed for this
|
||||
mechanism to work.
|
||||
|
||||
In the U-Boot boot loader, support for device tree overlays has recently been
|
||||
integrated, and is used on some boards to alter the device tree that is later
|
||||
passed to Linux. But since U-Boot's driver model, which is device tree-based as
|
||||
well, is being used in more and more drivers, the same problem of altering the
|
||||
device tree starts cropping up in U-Boot itself as well.
|
||||
|
||||
An additional problem with the device tree in U-Boot is that it is read-only,
|
||||
and the current mechanisms don't allow easy manipulation of the device tree
|
||||
after the driver model has been initialized. While migrating to a live device
|
||||
tree (at least after the relocation) would greatly simplify the solution of
|
||||
this problem, it is a non-negligible task to implement it, an a interim
|
||||
solution is needed to address the problem at least in the medium-term.
|
||||
|
||||
Hence, we propose a solution to this problem by offering a board-specific
|
||||
call-back function, which is passed a writeable pointer to the device tree.
|
||||
This function is called before the device tree is relocated, and specifically
|
||||
before the main U-Boot's driver model is instantiated, hence the main U-Boot
|
||||
"sees" all modifications to the device tree made in this function. Furthermore,
|
||||
we have the pre-relocation driver model at our disposal at this stage, which
|
||||
means that we can query the hardware for the existence and variety of the
|
||||
components easily.
|
||||
|
||||
2. Implementation
|
||||
-----------------
|
||||
|
||||
To take advantage of the pre-relocation device tree manipulation mechanism,
|
||||
boards have to implement the function board_fix_fdt, which has the following
|
||||
signature:
|
||||
|
||||
int board_fix_fdt (void *rw_fdt_blob)
|
||||
|
||||
The passed-in void pointer is a writeable pointer to the device tree, which can
|
||||
be used to manipulate the device tree using e.g. functions from
|
||||
include/fdt_support.h. The return value should either be 0 in case of
|
||||
successful execution of the device tree manipulation or something else for a
|
||||
failure. Note that returning a non-null value from the function will
|
||||
unrecoverably halt the boot process, as with any function from init_sequence_f
|
||||
(in common/board_f.c).
|
||||
|
||||
Furthermore, the Kconfig option OF_BOARD_FIXUP has to be set for the function
|
||||
to be called:
|
||||
|
||||
Device Tree Control
|
||||
-> [*] Board-specific manipulation of Device Tree
|
||||
|
||||
+----------------------------------------------------------+
|
||||
| WARNING: The actual manipulation of the device tree has |
|
||||
| to be the _last_ set of operations in board_fix_fdt! |
|
||||
| Since the pre-relocation driver model does not adapt to |
|
||||
| changes made to the device tree either, its references |
|
||||
| into the device tree will be invalid after manipulating |
|
||||
| it, and unpredictable behavior might occur when |
|
||||
| functions that rely on them are executed! |
|
||||
+----------------------------------------------------------+
|
||||
|
||||
Hence, the recommended layout of the board_fixup_fdt call-back function is the
|
||||
following:
|
||||
|
||||
int board_fix_fdt(void *rw_fdt_blob)
|
||||
{
|
||||
/* Collect information about device's hardware and store them in e.g.
|
||||
local variables */
|
||||
|
||||
/* Do device tree manipulation using the values previously collected */
|
||||
|
||||
/* Return 0 on successful manipulation and non-zero otherwise */
|
||||
}
|
||||
|
||||
If this convention is kept, both an "additive" approach, meaning that nodes for
|
||||
detected components are added to the device tree, as well as a "subtractive"
|
||||
approach, meaning that nodes for absent components are removed from the tree,
|
||||
as well as a combination of both approaches should work.
|
||||
|
||||
3. Example
|
||||
----------
|
||||
|
||||
The controlcenterdc board (board/gdsys/a38x/controlcenterdc.c) features a
|
||||
board_fix_fdt function, in which six GPIO expanders (which might be present or
|
||||
not, since they are on daughter boards) on a I2C bus are queried for, and
|
||||
subsequently deactivated in the device tree if they are not present.
|
||||
|
||||
Note that the dm_i2c_simple_probe function does not use the device tree, hence
|
||||
it is safe to call it after the tree has already been manipulated.
|
||||
|
||||
4. Work to be done
|
||||
------------------
|
||||
|
||||
* The application of device tree overlay should be possible in board_fixup_fdt,
|
||||
but has not been tested at this stage.
|
||||
|
||||
2017-01-06, Mario Six <mario.six@gdsys.cc>
|
||||
10
dts/Kconfig
10
dts/Kconfig
|
|
@ -14,6 +14,16 @@ config OF_CONTROL
|
|||
This feature provides for run-time configuration of U-Boot
|
||||
via a flattened device tree.
|
||||
|
||||
config OF_BOARD_FIXUP
|
||||
bool "Board-specific manipulation of Device Tree"
|
||||
help
|
||||
In certain circumstances it is necessary to be able to modify
|
||||
U-Boot's device tree (e.g. to delete device from it). This option
|
||||
make the Device Tree writeable and provides a board-specific
|
||||
"board_fix_fdt" callback (called during pre-relocation time), which
|
||||
enables the board initialization to modifiy the Device Tree. The
|
||||
modified copy is subsequently used by U-Boot after relocation.
|
||||
|
||||
config SPL_OF_CONTROL
|
||||
bool "Enable run-time configuration via Device Tree in SPL"
|
||||
depends on SPL && OF_CONTROL
|
||||
|
|
|
|||
|
|
@ -532,6 +532,7 @@ extern ssize_t spi_write (uchar *, int, uchar *, int);
|
|||
|
||||
/* $(BOARD)/$(BOARD).c */
|
||||
int board_early_init_f (void);
|
||||
int board_fix_fdt (void *rw_fdt_blob); /* manipulate the U-Boot fdt before its relocation */
|
||||
int board_late_init (void);
|
||||
int board_postclk_init (void); /* after clocks/timebase, before env/serial */
|
||||
int board_early_init_r (void);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue