From mboxrd@z Thu Jan 1 00:00:00 1970 From: Stefan Roese Date: Wed, 18 Jan 2017 17:03:15 +0100 Subject: [U-Boot] [PATCH v2 05/18] dm: Add callback to modify the device tree In-Reply-To: <20170111150102.7399-6-mario.six@gdsys.cc> References: <20170111150102.7399-1-mario.six@gdsys.cc> <20170111150102.7399-6-mario.six@gdsys.cc> Message-ID: <67ba99a4-7a49-6877-c45a-321a8f77c95e@denx.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On 11.01.2017 16:00, Mario Six wrote: > Certain boards come in different variations by way of utilizing daughter > boards, for example. These boards might contain additional chips, which > are added to the main board's busses, e.g. I2C. > > The device tree support for such boards would either, quite naturally, > employ the overlay mechanism to add such chips to the tree, or would use > one large default device tree, and delete the devices that are actually > not present. > > Regardless of approach, even on the U-Boot level, a modification of the > device tree is a prerequisite to have such modular families of boards > supported properly. > > Therefore, we add an option to make the U-Boot device tree (the actual > copy later used by the driver model) writeable, and add a callback > method that allows boards to modify the device tree at an early stage, > at which, hopefully, also the application of device tree overlays will > be possible. > > Signed-off-by: Mario Six > --- > Changes in v2: > > * Switched from usage of globally writeable global data pointer to a locally > writeable pointer passed to board_fix_fdt > * Added comments for board_fix_fdt in include/common.h > * Added documentation for pre-relocation device tree manipulation Mario, thanks for the extensive documentation in this new version. I would like to see some review comments from Simon (who is working on a live DT as I've noticed just today) and perhaps others on this patch. Simon, could you please take a look at this? Thanks, Stefan > --- > common/board_f.c | 10 ++++ > doc/driver-model/fdt-fixup.txt | 132 +++++++++++++++++++++++++++++++++++++++++ > dts/Kconfig | 10 ++++ > include/common.h | 1 + > 4 files changed, 153 insertions(+) > create mode 100644 doc/driver-model/fdt-fixup.txt > > diff --git a/common/board_f.c b/common/board_f.c > index cc8aee7..e877bf9 100644 > --- a/common/board_f.c > +++ b/common/board_f.c > @@ -767,6 +767,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) > > @@ -1037,6 +1044,9 @@ static init_fnc_t init_sequence_f[] = { > #ifdef CONFIG_SYS_EXTBDINFO > setup_board_extra, > #endif > +#ifdef CONFIG_OF_BOARD_FIXUP > + fix_fdt, > +#endif > INIT_FUNC_WATCHDOG_RESET > reloc_fdt, > setup_reloc, > diff --git a/doc/driver-model/fdt-fixup.txt b/doc/driver-model/fdt-fixup.txt > new file mode 100644 > index 0000000..70344bd > --- /dev/null > +++ b/doc/driver-model/fdt-fixup.txt > @@ -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 > diff --git a/dts/Kconfig b/dts/Kconfig > index 4b7d8b1..3f64eda 100644 > --- a/dts/Kconfig > +++ b/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 > diff --git a/include/common.h b/include/common.h > index a8d833b..a64f249 100644 > --- a/include/common.h > +++ b/include/common.h > @@ -502,6 +502,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); > -- > 2.9.0 > Viele Gr??e, Stefan -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: sr at denx.de