All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree
@ 2017-05-10 14:20 Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 01/71] dm: core: Set return value first in lists_bind_fdt() Simon Glass
                   ` (70 more replies)
  0 siblings, 71 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

(this is series 2 of 3 for live tree support - the final series will
fully convert a real board and provide size comparisons)

So far U-Boot uses a 'flat' device tree, which means that it is decoded
on the fly as needed. This uses the libfdt library and avoids needing
extra memory for additional tables.

For some time there has been discussion about moving U-Boot to use a
'live' tree, where the device tree is decoded at start-up into a set of
hierarchical structures with pointers.

The advantages are:

- It is somewhat faster to access (in particular scanning and looking for a
    parent)
- It permits the device tree to be changed at run-time (this is not
    recommended with the flat device tree since devices store the offset
    of their device tree node and updating the tree may invalidate that).
    Enabling this feature could be useful for overlays, for example.
- It allows nodes to be referenced by a single pointer, instead of the
    current device tree pointer plus offset

The disadvantages are:

- It requires more memory
- It takes (a little) time to build the live tree
- It adds more complexity under the hood, including an additional
    abstraction layer

This series is an attempt to introduce a useful live tree feature into
U-Boot. There are many options and trade-offs. This series is the
culmination of quite a bit of thought and experimentation.

The approach used in this series is:

- Before relocation the flat tree is used, to avoid extra memory usage
and time. In general, there is not much access before relocation since
most drivers are not started up. So there is little benefit in having a
live tree

- After relocation the live tree is built. At this point the CPU should be
running quickly and there is plenty of memory. All available devices will
be bound so the overhead of building the live tree may be outweighed by
its greater efficiency.

As a simplification, this series supports only one tree or the other. When
the live tree is active, the flat tree cannot be used. That makes it easy
to know the current state and avoids confusion over mixing offset and node
pointers.

Some drivers will need to be used both before and after relocation. This
means that they must support both the flat and the live tree. To support
this, the concept of a node 'reference' is defined. A reference can hold
either a node offset (for the flat tree) or a node pointer (for the live
tree). This allows drivers to access values from the tree regardless of
which tree is in use.

In addition, since most device tree access happens in the context of a
device (struct udevice), a new 'dev_read' layer is provided to read device
tree configuration associated with a device. This encapsulates the details
of exactly how this information is read.

I have taken the view that code compatibility with Linux is desirable. So
the of_access.c file brings in code from Linux with very little
modification. As new access methods are needed we should be able to bring
in more code and avoid writing it ourselves in U-Boot.

Conversion of drivers and subsystems to support the live tree (as well as
flat tree) is fairly easy. Patch are included to add support to subsystems
for which tests exist, to ensure that 'make tests' still passes.

Future work will enable the live device tree on a real board and include
code size comparisons.

For now here is a code size comparison for firefly (within inlining of
ofnode which I intend to implement):

arm: (for 1/1 boards) all +268.0 bss -24.0 data -4.0 spl/u-boot-spl:all +240.0 spl/u-boot-spl:text +240.0 text +296.0
     firefly-rk3288 : all +268 bss -24 data -4 spl/u-boot-spl:all +240 spl/u-boot-spl:text +240 text +296
        u-boot: add: 18/-4, grow: 2/-22 bytes: 764/-490 (274)
          function                                   old     new   delta
          gpio_request_tail                            -     132    +132
          ofnode_parse_phandle_with_args               -      66     +66
          uclass_find_device_by_ofnode                 -      64     +64
          ofnode_pre_reloc                             -      64     +64
          ofnode_read_string                           -      52     +52
          fdt_support_default_count_cells              -      52     +52
          ofnode_read_u32                              -      48     +48
          gpio_request_by_name                        32      72     +40
          ofnode_read_size                             -      34     +34
          uclass_get_device_by_ofnode                  -      28     +28
          ofnode_read_u32_array                        -      28     +28
          ofnode_read_bool                             -      26     +26
          ofnode_read_prop                             -      24     +24
          ofnode_get_addr_size                         -      24     +24
          ofnode_read_u32_default                      -      22     +22
          ofnode_find_subnode                          -      18     +18
          ofnode_next_subnode                          -      14     +14
          ofnode_first_subnode                         -      14     +14
          ofnode_get_name                              -      12     +12
          dm_init_and_scan                            42      44      +2
          uclass_get_device_by_phandle               106     104      -2
          spi_child_post_bind                         32      30      -2
          i2c_child_post_bind                         32      30      -2
          spi_post_probe                              36      32      -4
          spi_flash_scan                             520     516      -4
          serial_init                                212     208      -4
          i2c_post_probe                              48      44      -4
          clk_fixed_rate_ofdata_to_platdata           36      32      -4
          act8846_bind                                48      44      -4
          simple_bus_post_bind                        60      52      -8
          lists_bind_fdt                             240     232      -8
          i2c_chip_ofdata_to_platdata                 64      56      -8
          clk_get_by_index                           108     100      -8
          usb_child_post_bind                         92      80     -12
          regmap_init_mem                            228     216     -12
          fixed_regulator_ofdata_to_platdata         108      96     -12
          pmic_bind_children                         158     144     -14
          spi_slave_ofdata_to_platdata               256     240     -16
          pinconfig_post_bind                        136     116     -20
          led_gpio_bind                              108      88     -20
          regulator_post_bind                        148     124     -24
          gpio_request_by_name_nodev                  28       -     -28
          fdtdec_get_uint                             30       -     -30
          regulator_pre_probe                        220     184     -36
          of_bus_default_count_cells                  52       -     -52
          _gpio_request_by_name_nodev                152       -    -152
        spl-u-boot-spl: add: 8/-1, grow: 1/-5 bytes: 300/-56 (244)
          function                                   old     new   delta
          ofnode_parse_phandle_with_args               -      66     +66
          uclass_find_device_by_ofnode                 -      64     +64
          ofnode_read_u32                              -      48     +48
          ofnode_read_size                             -      34     +34
          uclass_get_device_by_ofnode                  -      28     +28
          ofnode_read_prop                             -      24     +24
          ofnode_read_u32_default                      -      22     +22
          ofnode_get_name                              -      12     +12
          dm_init_and_scan                            42      44      +2
          dm_scan_fdt_node                            96      94      -2
          clk_fixed_rate_ofdata_to_platdata           36      32      -4
          lists_bind_fdt                             224     216      -8
          clk_get_by_index                           108     100      -8
          regmap_init_mem                            220     208     -12
          device_bind                                 22       -     -22
(no errors to report)


Changes in v2:
- Rewrite based on testing and refining the v1 series
- Convert various subsystems to enable sandbox tests to pass

Simon Glass (71):
  dm: core: Set return value first in lists_bind_fdt()
  Update WARN_ON() to return a value
  dm: core: Add livetree definitions
  dm: core: Add livetree access functions
  dm: Add a function to create a 'live' device tree
  dm: Build a live tree after relocation
  dm: core: Rename of_device_is_compatible()
  dm: core: Add operations on device tree references
  dm: core: Add livetree address functions
  fdt: Update fdt_get_base_address() to use const
  dm: core: Add address operations on device tree references
  dm: core: Add a place to put extra device-tree reading functions
  dm: core: Add device-based 'read' functions to access DT
  dm: core: Implement live tree 'read' functions
  dm: core: Allow binding a device from a live tree
  dm: core: Update lists_bind_fdt() to use ofnode
  dm: core: Update device_bind_driver_to_node() to use ofnode
  dm: core: Scan the live tree when setting up driver model
  dm: core: Add a way to find a device by ofnode
  dm: regmap: Add support for livetree
  dm: simple-bus: Add support for livetree
  dm: core: Update uclass_find_device_by_phandle() for livetree
  sandbox: Add a way to reset sandbox state for tests
  dm: test: Move test running code into a separate function
  dm: test: Show the test filename when running
  dm: test: Add support for running tests with livetree
  dm: core: Run tests with both livetree and flat tree
  dm: gpio: Refactor to prepare for live tree support
  dm: gpio: Drop blank line in gpio_xlate_offs_flags() comment
  dm: gpio: sandbox: Use dev_read...() functions to access DT
  dm: gpio: Add live tree support
  cros_ec: Fix debug() statement in ec_command_inptr()
  cros_ec: Convert to support live tree
  sandbox: Add a new sandbox_flattree board
  test: Update 'make test' to run more tests
  fdt: Rename a few functions in fdt_support
  dm: Add more livetree helpers and definitions
  string: Add strchrnul()
  string: Add strcspn()
  dm: i2c: Convert uclass to livetree
  dm: pmic: Convert uclass to livetree
  sandbox: pmic: Convert pmic emulator to support livetree
  dm: regulator: Convert regulator uclass to support livetree
  dm: regulator: Update fixed regulator to support livetree.
  dm: mmc: Convert uclass to livetree
  dm: adc: Convert uclass to livetree
  dm: usb: Convert uclass to livetree
  sandbox: usb: Convert emulators to livetree
  clk: Modify xlate() method for livetree
  dm: clk: Update uclass to support livetree
  dm: clk: fixed: Update to support livetree
  dm: test: Separate out the bus DT offset test
  dm: test: Disable the fdt_offset test with livetree
  dm: phy: Update tests to use ut_asserteq()
  dm: mailbox: Update uclass to support livetree
  dm: phy: Update uclass to support livetree
  sandbox: phy: Update driver for livetree
  dm: power-domain: Update uclass to support livetree
  dm: reset: Update uclass to support livetree
  dm: pci: Update uclass to support livetree
  dm: Update the I2C eeprom driver for livetree
  cros_ec: Update the cros_ec keyboard driver to livetree
  dm: spi: Convert uclass to livetree
  dm: sandbox: i2c: Drop fdtdec.h header
  dm: sandbox: i2c_rtc: Drop fdtdec.h header
  dm: spi-flash: Convert uclass to livetree
  dm: sandbox: spi: Convert driver to support livetree
  dm: sandbox: sysreset: Convert driver to livetree
  dm: test: Fix nit with position of backslash
  dm: gpio: power: Convert pm8916 drivers to livetree
  sandbox: Move to use live tree

 arch/arm/cpu/armv8/fsl-layerscape/fdt.c          |   4 +-
 arch/arm/mach-tegra/tegra186/nvtboot_mem.c       |   4 +-
 arch/sandbox/cpu/state.c                         |  14 +-
 arch/sandbox/include/asm/state.h                 |   7 +
 board/qualcomm/dragonboard410c/dragonboard410c.c |  12 +-
 board/samsung/common/board.c                     |   4 +-
 board/samsung/common/exynos5-dt.c                |   2 +-
 board/sandbox/MAINTAINERS                        |   7 +
 common/board_r.c                                 |  12 +
 common/fdt_support.c                             |  28 +-
 configs/sandbox_defconfig                        |   1 +
 configs/sandbox_flattree_defconfig               | 179 ++++++
 drivers/adc/adc-uclass.c                         |  14 +-
 drivers/clk/at91/pmc.c                           |   4 +-
 drivers/clk/at91/pmc.h                           |   2 +-
 drivers/clk/clk-uclass.c                         |  14 +-
 drivers/clk/clk_fixed_rate.c                     |   5 +-
 drivers/clk/clk_stm32f7.c                        |   3 +-
 drivers/core/Kconfig                             |   4 +
 drivers/core/Makefile                            |   5 +
 drivers/core/device.c                            |  20 +-
 drivers/core/lists.c                             |  29 +-
 drivers/core/of_access.c                         | 736 +++++++++++++++++++++++
 drivers/core/of_addr.c                           | 359 +++++++++++
 drivers/core/of_extra.c                          |  37 ++
 drivers/core/ofnode.c                            | 579 ++++++++++++++++++
 drivers/core/read.c                              | 140 +++++
 drivers/core/regmap.c                            |  37 +-
 drivers/core/root.c                              |  60 +-
 drivers/core/simple-bus.c                        |   3 +-
 drivers/core/uclass.c                            |  42 +-
 drivers/cpu/cpu-uclass.c                         |   6 +-
 drivers/firmware/psci.c                          |   4 +-
 drivers/gpio/74x164_gpio.c                       |   2 +-
 drivers/gpio/gpio-uclass.c                       |  82 +--
 drivers/gpio/pca953x_gpio.c                      |   2 +-
 drivers/gpio/pm8916_gpio.c                       |   8 +-
 drivers/gpio/sandbox.c                           |  12 +-
 drivers/gpio/sunxi_gpio.c                        |   2 +-
 drivers/gpio/tegra186_gpio.c                     |   2 +-
 drivers/gpio/tegra_gpio.c                        |   2 +-
 drivers/i2c/i2c-uclass.c                         |  28 +-
 drivers/i2c/muxes/i2c-mux-uclass.c               |  11 +-
 drivers/i2c/mxc_i2c.c                            |  12 +-
 drivers/i2c/sandbox_i2c.c                        |   1 -
 drivers/input/cros_ec_keyb.c                     |  24 +-
 drivers/input/key_matrix.c                       |  19 +-
 drivers/input/tegra-kbc.c                        |   3 +-
 drivers/led/led_gpio.c                           |  13 +-
 drivers/mailbox/mailbox-uclass.c                 |  20 +-
 drivers/mailbox/tegra-hsp.c                      |   2 +-
 drivers/misc/cros_ec.c                           |  36 +-
 drivers/misc/cros_ec_sandbox.c                   |  23 +-
 drivers/misc/i2c_eeprom_emul.c                   |   7 +-
 drivers/misc/tegra186_bpmp.c                     |   6 +-
 drivers/misc/tegra_car.c                         |   4 +-
 drivers/mmc/fsl_esdhc.c                          |   6 +-
 drivers/mmc/mmc-uclass.c                         |   3 +-
 drivers/mmc/s5p_sdhci.c                          |   8 +-
 drivers/mmc/xenon_sdhci.c                        |   2 +-
 drivers/mtd/altera_qspi.c                        |   2 +-
 drivers/mtd/cfi_flash.c                          |   2 +-
 drivers/mtd/nand/sunxi_nand.c                    |   2 +-
 drivers/mtd/nand/tegra_nand.c                    |   4 +-
 drivers/mtd/pic32_flash.c                        |   2 +-
 drivers/mtd/spi/sandbox.c                        |   6 +-
 drivers/mtd/spi/spi_flash.c                      |   7 +-
 drivers/net/altera_tse.c                         |   2 +-
 drivers/net/cpsw-common.c                        |   4 +-
 drivers/net/keystone_net.c                       |   6 +-
 drivers/net/mvneta.c                             |   2 +-
 drivers/net/pic32_eth.c                          |   3 +-
 drivers/pci/pci-uclass.c                         |  26 +-
 drivers/phy/marvell/comphy_core.c                |   4 +-
 drivers/phy/phy-uclass.c                         |  21 +-
 drivers/phy/sandbox-phy.c                        |   3 +-
 drivers/pinctrl/pinctrl-uclass.c                 |  15 +-
 drivers/power/domain/power-domain-uclass.c       |  19 +-
 drivers/power/pmic/act8846.c                     |   8 +-
 drivers/power/pmic/i2c_pmic_emul.c               |   6 +-
 drivers/power/pmic/lp873x.c                      |  12 +-
 drivers/power/pmic/max77686.c                    |   8 +-
 drivers/power/pmic/palmas.c                      |  16 +-
 drivers/power/pmic/pfuze100.c                    |   8 +-
 drivers/power/pmic/pm8916.c                      |   2 +-
 drivers/power/pmic/pmic-uclass.c                 |  22 +-
 drivers/power/pmic/rk808.c                       |   8 +-
 drivers/power/pmic/s5m8767.c                     |   7 +-
 drivers/power/pmic/sandbox.c                     |   2 +-
 drivers/power/pmic/tps65090.c                    |   8 +-
 drivers/power/regulator/fixed.c                  |  17 +-
 drivers/power/regulator/regulator-uclass.c       |  39 +-
 drivers/reset/reset-uclass.c                     |  21 +-
 drivers/rtc/i2c_rtc_emul.c                       |   1 -
 drivers/serial/serial-uclass.c                   |   3 +-
 drivers/sound/max98095.c                         |   2 +
 drivers/sound/wm8994.c                           |   2 +-
 drivers/spi/pic32_spi.c                          |   2 +-
 drivers/spi/spi-uclass.c                         |  31 +-
 drivers/sysreset/sysreset_sandbox.c              |   2 +-
 drivers/timer/timer-uclass.c                     |   3 +-
 drivers/usb/emul/sandbox_flash.c                 |   4 +-
 drivers/usb/emul/sandbox_hub.c                   |   3 +-
 drivers/usb/host/ehci-marvell.c                  |   2 +-
 drivers/usb/host/ehci-tegra.c                    |   7 +-
 drivers/usb/host/ehci-vf.c                       |   5 +-
 drivers/usb/host/usb-uclass.c                    |   8 +-
 drivers/usb/host/xhci-rockchip.c                 |   2 +-
 drivers/usb/musb-new/ti-musb.c                   |   2 +-
 dts/Kconfig                                      |  11 +
 include/asm-generic/global_data.h                |   3 +
 include/asm-generic/gpio.h                       |  17 +-
 include/clk-uclass.h                             |   5 +-
 include/cros_ec.h                                |   8 +-
 include/dm.h                                     |   2 +
 include/dm/device-internal.h                     |  10 +-
 include/dm/device.h                              |   4 +-
 include/dm/lists.h                               |   9 +-
 include/dm/of.h                                  | 139 +++++
 include/dm/of_access.h                           | 347 +++++++++++
 include/dm/of_addr.h                             |  64 ++
 include/dm/of_extra.h                            |  46 ++
 include/dm/ofnode.h                              | 487 ++++++++++++++-
 include/dm/read.h                                | 439 ++++++++++++++
 include/dm/root.h                                |   3 +-
 include/dm/test.h                                |   2 +
 include/dm/uclass-internal.h                     |  16 +
 include/dm/uclass.h                              |  16 +
 include/fdt_support.h                            |   6 +-
 include/fdtdec.h                                 |  34 --
 include/generic-phy.h                            |   3 +-
 include/i2c.h                                    |   3 +-
 include/key_matrix.h                             |   3 +-
 include/linux/compat.h                           |   8 +-
 include/linux/string.h                           |  28 +
 include/mailbox-uclass.h                         |   2 +-
 include/of_live.h                                |  24 +
 include/power-domain-uclass.h                    |   2 +-
 include/power/pmic.h                             |   2 +-
 include/reset-uclass.h                           |   4 +-
 include/spi.h                                    |   2 +-
 include/test/test.h                              |   4 +
 include/test/ut.h                                |   2 +-
 lib/Makefile                                     |   1 +
 lib/fdtdec.c                                     |  33 +-
 lib/of_live.c                                    | 333 ++++++++++
 lib/string.c                                     |  32 +
 test/dm/bus.c                                    |  16 +-
 test/dm/phy.c                                    |  15 +-
 test/dm/test-fdt.c                               |   3 +-
 test/dm/test-main.c                              | 105 +++-
 test/run                                         |   8 +-
 152 files changed, 4749 insertions(+), 662 deletions(-)
 create mode 100644 configs/sandbox_flattree_defconfig
 create mode 100644 drivers/core/of_access.c
 create mode 100644 drivers/core/of_addr.c
 create mode 100644 drivers/core/of_extra.c
 create mode 100644 drivers/core/ofnode.c
 create mode 100644 drivers/core/read.c
 create mode 100644 include/dm/of.h
 create mode 100644 include/dm/of_access.h
 create mode 100644 include/dm/of_addr.h
 create mode 100644 include/dm/of_extra.h
 create mode 100644 include/dm/read.h
 create mode 100644 include/of_live.h
 create mode 100644 lib/of_live.c

-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 01/71] dm: core: Set return value first in lists_bind_fdt()
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 02/71] Update WARN_ON() to return a value Simon Glass
                   ` (69 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

Adjust the order to make it clear that *devp is set to NULL by default.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/lists.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index 23b6ba78d3..72c55e205f 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -140,10 +140,10 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
 	int result = 0;
 	int ret = 0;
 
-	name = fdt_get_name(blob, offset, NULL);
-	dm_dbg("bind node %s\n", name);
 	if (devp)
 		*devp = NULL;
+	name = fdt_get_name(blob, offset, NULL);
+	dm_dbg("bind node %s\n", name);
 
 	compat_list = fdt_getprop(blob, offset, "compatible", &compat_length);
 	if (!compat_list) {
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 02/71] Update WARN_ON() to return a value
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 01/71] dm: core: Set return value first in lists_bind_fdt() Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 03/71] dm: core: Add livetree definitions Simon Glass
                   ` (68 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

In linux v4.9 this returns a value. This saves checking the warning
condition twice in some code.

Update the U-Boot version to do this also.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/linux/compat.h | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/include/linux/compat.h b/include/linux/compat.h
index a43e4d6698..03f9bef0da 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -106,8 +106,12 @@ static inline void kmem_cache_destroy(struct kmem_cache *cachep)
 #define BUG_ON(condition) do { if (condition) BUG(); } while(0)
 #endif /* BUG */
 
-#define WARN_ON(x) if (x) {printf("WARNING in %s line %d\n" \
-				  , __FILE__, __LINE__); }
+#define WARN_ON(condition) ({						\
+	int __ret_warn_on = !!(condition);				\
+	if (unlikely(__ret_warn_on))					\
+		printf("WARNING in %s line %d\n", __FILE__, __LINE__);;	\
+	unlikely(__ret_warn_on);					\
+})
 
 #define PAGE_SIZE	4096
 
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 03/71] dm: core: Add livetree definitions
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 01/71] dm: core: Set return value first in lists_bind_fdt() Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 02/71] Update WARN_ON() to return a value Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 04/71] dm: core: Add livetree access functions Simon Glass
                   ` (67 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

Add a Kconfig option to enable a live device tree, built at run time from
the flat tree. Also add structure definitions and a root node.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 dts/Kconfig                       |  11 ++++
 include/asm-generic/global_data.h |   3 ++
 include/dm/of.h                   | 103 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 117 insertions(+)
 create mode 100644 include/dm/of.h

diff --git a/dts/Kconfig b/dts/Kconfig
index 6fe7a5bc08..4d8e476831 100644
--- a/dts/Kconfig
+++ b/dts/Kconfig
@@ -32,6 +32,17 @@ config SPL_OF_CONTROL
 	  which is not enough to support device tree. Enable this option to
 	  allow such boards to be supported by U-Boot SPL.
 
+config OF_LIVE
+	bool "Enable use of a live tree"
+	depends on OF_CONTROL
+	help
+	  Normally U-Boot uses a flat device tree which saves space and
+	  avoids the need to unpack the tree before use. However a flat
+	  tree does not support modifcation from within U-Boot since it
+	  can invalidate driver-model device tree offsets. This option
+	  enables a live tree which is available after relocation,
+	  and can be adjusted as needed.
+
 choice
 	prompt "Provider of DTB for DT control"
 	depends on OF_CONTROL
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 1a77c982fa..28c6cab831 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -72,6 +72,9 @@ typedef struct global_data {
 	const void *fdt_blob;		/* Our device tree, NULL if none */
 	void *new_fdt;			/* Relocated FDT */
 	unsigned long fdt_size;		/* Space reserved for relocated FDT */
+#ifdef CONFIG_OF_LIVE
+	struct device_node *of_root;
+#endif
 	struct jt_funcs *jt;		/* jump table */
 	char env_buf[32];		/* buffer for getenv() before reloc. */
 #ifdef CONFIG_TRACE
diff --git a/include/dm/of.h b/include/dm/of.h
new file mode 100644
index 0000000000..102565018e
--- /dev/null
+++ b/include/dm/of.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _DM_OF_H
+#define _DM_OF_H
+
+/* integer value within a device tree property which references another node */
+typedef u32 phandle;
+
+/**
+ * struct property: Device tree property
+ *
+ * @name: Property name
+ * @length: Length of property in bytes
+ * @value: Pointer to property value
+ * @next: Pointer to next property, or NULL if none
+ */
+struct property {
+	char *name;
+	int length;
+	void *value;
+	struct property *next;
+};
+
+/**
+ * struct device_node: Device tree node
+ *
+ * @name: Node name
+ * @type: Node type (value of device_type property) or "<NULL>" if none
+ * @phandle: Phandle value of this none, or 0 if none
+ * @full_name: Full path to node, e.g. "/bus at 1/spi at 1100"
+ * @properties: Pointer to head of list of properties, or NULL if none
+ * @parent: Pointer to parent node, or NULL if this is the root node
+ * @child: Pointer to head of child node list, or NULL if no children
+ * @sibling: Pointer to the next sibling node, or NULL if this is the last
+ */
+struct device_node {
+	const char *name;
+	const char *type;
+	phandle phandle;
+	const char *full_name;
+
+	struct property *properties;
+	struct device_node *parent;
+	struct device_node *child;
+	struct device_node *sibling;
+};
+
+#define OF_MAX_PHANDLE_ARGS 16
+
+/**
+ * struct of_phandle_args - structure to hold phandle and arguments
+ *
+ * This is used when decoding a phandle in a device tree property. Typically
+ * these look like this:
+ *
+ * wibble {
+ *    phandle = <5>;
+ * };
+ *
+ * ...
+ * some-prop = <&wibble 1 2 3>
+ *
+ * Here &node is the phandle of the node 'wibble', i.e. 5. There are three
+ * arguments: 1, 2, 3.
+ *
+ * So when decoding the phandle in some-prop, np will point to wibble,
+ * args_count will be 3 and the three arguments will be in args.
+ *
+ * @np: Node that the phandle refers to
+ * @args_count: Number of arguments
+ * @args: Argument values
+ */
+struct of_phandle_args {
+	struct device_node *np;
+	int args_count;
+	uint32_t args[OF_MAX_PHANDLE_ARGS];
+};
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * of_live_active() - check if livetree is active
+ *
+ * @returns true if livetree is active, false it not
+ */
+#ifdef CONFIG_OF_LIVE
+static inline bool of_live_active(void)
+{
+	return gd->of_root != NULL;
+}
+#else
+static inline bool of_live_active(void)
+{
+	return false;
+}
+#endif
+
+#endif
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 04/71] dm: core: Add livetree access functions
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (2 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 03/71] dm: core: Add livetree definitions Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 05/71] dm: Add a function to create a 'live' device tree Simon Glass
                   ` (66 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

Add a basic assortment of functions to access the live device tree. These
come from Linux v4.9 and are modified for U-Boot to the minimum extent
possible. While these functions are now very stable in Linux, it will be
possible to merge in fixes if needed.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/Makefile    |   1 +
 drivers/core/of_access.c | 736 +++++++++++++++++++++++++++++++++++++++++++++++
 include/dm/of_access.h   | 347 ++++++++++++++++++++++
 3 files changed, 1084 insertions(+)
 create mode 100644 drivers/core/of_access.c
 create mode 100644 include/dm/of_access.h

diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index 8261f14f45..4211fd1e22 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_$(SPL_)SIMPLE_BUS)	+= simple-bus.o
 obj-$(CONFIG_DM)	+= dump.o
 obj-$(CONFIG_$(SPL_)REGMAP)	+= regmap.o
 obj-$(CONFIG_$(SPL_)SYSCON)	+= syscon-uclass.o
+obj-$(CONFIG_OF_LIVE) += of_access.o
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c
new file mode 100644
index 0000000000..79f12b4c67
--- /dev/null
+++ b/drivers/core/of_access.c
@@ -0,0 +1,736 @@
+/*
+ * Originally from Linux v4.9
+ * Paul Mackerras	August 1996.
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
+ *   {engebret|bergner}@us.ibm.com
+ *
+ * Adapted for sparc and sparc64 by David S. Miller davem at davemloft.net
+ *
+ * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and
+ * Grant Likely.
+ *
+ * Modified for U-Boot
+ * Copyright (c) 2017 Google, Inc
+ *
+ * This file follows drivers/of/base.c with functions in the same order as the
+ * Linux version.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <dm/of_access.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/ioport.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* list of struct alias_prop aliases */
+LIST_HEAD(aliases_lookup);
+
+/* "/aliaes" node */
+static struct device_node *of_aliases;
+
+/* "/chosen" node */
+static struct device_node *of_chosen;
+
+/* node pointed to by the stdout-path alias */
+static struct device_node *of_stdout;
+
+/* pointer to options given after the alias (separated by :) or NULL if none */
+static const char *of_stdout_options;
+
+/**
+ * struct alias_prop - Alias property in 'aliases' node
+ *
+ * The structure represents one alias property of 'aliases' node as
+ * an entry in aliases_lookup list.
+ *
+ * @link:	List node to link the structure in aliases_lookup list
+ * @alias:	Alias property name
+ * @np:		Pointer to device_node that the alias stands for
+ * @id:		Index value from end of alias name
+ * @stem:	Alias string without the index
+ */
+struct alias_prop {
+	struct list_head link;
+	const char *alias;
+	struct device_node *np;
+	int id;
+	char stem[0];
+};
+
+int of_n_addr_cells(const struct device_node *np)
+{
+	const __be32 *ip;
+
+	do {
+		if (np->parent)
+			np = np->parent;
+		ip = of_get_property(np, "#address-cells", NULL);
+		if (ip)
+			return be32_to_cpup(ip);
+	} while (np->parent);
+
+	/* No #address-cells property for the root node */
+	return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
+}
+
+int of_n_size_cells(const struct device_node *np)
+{
+	const __be32 *ip;
+
+	do {
+		if (np->parent)
+			np = np->parent;
+		ip = of_get_property(np, "#size-cells", NULL);
+		if (ip)
+			return be32_to_cpup(ip);
+	} while (np->parent);
+
+	/* No #size-cells property for the root node */
+	return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
+}
+
+struct property *of_find_property(const struct device_node *np,
+				  const char *name, int *lenp)
+{
+	struct property *pp;
+
+	if (!np)
+		return NULL;
+
+	for (pp = np->properties; pp; pp = pp->next) {
+		if (strcmp(pp->name, name) == 0) {
+			if (lenp)
+				*lenp = pp->length;
+			break;
+		}
+	}
+	if (!pp && lenp)
+		*lenp = -FDT_ERR_NOTFOUND;
+
+	return pp;
+}
+
+struct device_node *of_find_all_nodes(struct device_node *prev)
+{
+	struct device_node *np;
+
+	if (!prev) {
+		np = gd->of_root;
+	} else if (prev->child) {
+		np = prev->child;
+	} else {
+		/*
+		 * Walk back up looking for a sibling, or the end of the
+		 * structure
+		 */
+		np = prev;
+		while (np->parent && !np->sibling)
+			np = np->parent;
+		np = np->sibling; /* Might be null at the end of the tree */
+	}
+
+	return np;
+}
+
+const void *of_get_property(const struct device_node *np, const char *name,
+			    int *lenp)
+{
+	struct property *pp = of_find_property(np, name, lenp);
+
+	return pp ? pp->value : NULL;
+}
+
+static const char *of_prop_next_string(struct property *prop, const char *cur)
+{
+	const void *curv = cur;
+
+	if (!prop)
+		return NULL;
+
+	if (!cur)
+		return prop->value;
+
+	curv += strlen(cur) + 1;
+	if (curv >= prop->value + prop->length)
+		return NULL;
+
+	return curv;
+}
+
+int of_device_is_compatible(const struct device_node *device,
+			    const char *compat, const char *type,
+			    const char *name)
+{
+	struct property *prop;
+	const char *cp;
+	int index = 0, score = 0;
+
+	/* Compatible match has highest priority */
+	if (compat && compat[0]) {
+		prop = of_find_property(device, "compatible", NULL);
+		for (cp = of_prop_next_string(prop, NULL); cp;
+		     cp = of_prop_next_string(prop, cp), index++) {
+			if (of_compat_cmp(cp, compat, strlen(compat)) == 0) {
+				score = INT_MAX/2 - (index << 2);
+				break;
+			}
+		}
+		if (!score)
+			return 0;
+	}
+
+	/* Matching type is better than matching name */
+	if (type && type[0]) {
+		if (!device->type || of_node_cmp(type, device->type))
+			return 0;
+		score += 2;
+	}
+
+	/* Matching name is a bit better than not */
+	if (name && name[0]) {
+		if (!device->name || of_node_cmp(name, device->name))
+			return 0;
+		score++;
+	}
+
+	return score;
+}
+
+bool of_device_is_available(const struct device_node *device)
+{
+	const char *status;
+	int statlen;
+
+	if (!device)
+		return false;
+
+	status = of_get_property(device, "status", &statlen);
+	if (status == NULL)
+		return true;
+
+	if (statlen > 0) {
+		if (!strcmp(status, "okay"))
+			return true;
+	}
+
+	return false;
+}
+
+struct device_node *of_get_parent(const struct device_node *node)
+{
+	const struct device_node *np;
+
+	if (!node)
+		return NULL;
+
+	np = of_node_get(node->parent);
+
+	return (struct device_node *)np;
+}
+
+static struct device_node *__of_get_next_child(const struct device_node *node,
+					       struct device_node *prev)
+{
+	struct device_node *next;
+
+	if (!node)
+		return NULL;
+
+	next = prev ? prev->sibling : node->child;
+	for (; next; next = next->sibling)
+		if (of_node_get(next))
+			break;
+	of_node_put(prev);
+	return next;
+}
+
+#define __for_each_child_of_node(parent, child) \
+	for (child = __of_get_next_child(parent, NULL); child != NULL; \
+	     child = __of_get_next_child(parent, child))
+
+static struct device_node *__of_find_node_by_path(struct device_node *parent,
+						  const char *path)
+{
+	struct device_node *child;
+	int len;
+
+	len = strcspn(path, "/:");
+	if (!len)
+		return NULL;
+
+	__for_each_child_of_node(parent, child) {
+		const char *name = strrchr(child->full_name, '/');
+		if (WARN_ON(child->full_name))
+			continue;
+		name++;
+		if (strncmp(path, name, len) == 0 && (strlen(name) == len))
+			return child;
+	}
+	return NULL;
+}
+
+#define for_each_property_of_node(dn, pp) \
+	for (pp = dn->properties; pp != NULL; pp = pp->next)
+
+struct device_node *of_find_node_opts_by_path(const char *path,
+					      const char **opts)
+{
+	struct device_node *np = NULL;
+	struct property *pp;
+	const char *separator = strchr(path, ':');
+
+	if (opts)
+		*opts = separator ? separator + 1 : NULL;
+
+	if (strcmp(path, "/") == 0)
+		return of_node_get(gd->of_root);
+
+	/* The path could begin with an alias */
+	if (*path != '/') {
+		int len;
+		const char *p = separator;
+
+		if (!p)
+			p = strchrnul(path, '/');
+		len = p - path;
+
+		/* of_aliases must not be NULL */
+		if (!of_aliases)
+			return NULL;
+
+		for_each_property_of_node(of_aliases, pp) {
+			if (strlen(pp->name) == len && !strncmp(pp->name, path,
+								len)) {
+				np = of_find_node_by_path(pp->value);
+				break;
+			}
+		}
+		if (!np)
+			return NULL;
+		path = p;
+	}
+
+	/* Step down the tree matching path components */
+	if (!np)
+		np = of_node_get(gd->of_root);
+	while (np && *path == '/') {
+		struct device_node *tmp = np;
+
+		path++; /* Increment past '/' delimiter */
+		np = __of_find_node_by_path(np, path);
+		of_node_put(tmp);
+		path = strchrnul(path, '/');
+		if (separator && separator < path)
+			break;
+	}
+
+	return np;
+}
+
+struct device_node *of_find_compatible_node(struct device_node *from,
+		const char *type, const char *compatible)
+{
+	struct device_node *np;
+
+	for_each_of_allnodes_from(from, np)
+		if (of_device_is_compatible(np, compatible, type, NULL) &&
+		    of_node_get(np))
+			break;
+	of_node_put(from);
+
+	return np;
+}
+
+struct device_node *of_find_node_by_phandle(phandle handle)
+{
+	struct device_node *np;
+
+	if (!handle)
+		return NULL;
+
+	for_each_of_allnodes(np)
+		if (np->phandle == handle)
+			break;
+	(void)of_node_get(np);
+
+	return np;
+}
+
+/**
+ * of_find_property_value_of_size() - find property of given size
+ *
+ * Search for a property in a device node and validate the requested size.
+ *
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ * @len:	requested length of property value
+ *
+ * @return the property value on success, -EINVAL if the property does not
+ * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ */
+static void *of_find_property_value_of_size(const struct device_node *np,
+					    const char *propname, u32 len)
+{
+	struct property *prop = of_find_property(np, propname, NULL);
+
+	if (!prop)
+		return ERR_PTR(-EINVAL);
+	if (!prop->value)
+		return ERR_PTR(-ENODATA);
+	if (len > prop->length)
+		return ERR_PTR(-EOVERFLOW);
+
+	return prop->value;
+}
+
+int of_read_u32(const struct device_node *np, const char *propname, u32 *outp)
+{
+	const __be32 *val;
+
+	debug("%s: %s: ", __func__, propname);
+	if (!np)
+		return -EINVAL;
+	val = of_find_property_value_of_size(np, propname, sizeof(*outp));
+	if (IS_ERR(val)) {
+		debug("(not found)\n");
+		return PTR_ERR(val);
+	}
+
+	*outp = be32_to_cpup(val);
+	debug("%#x (%d)\n", *outp, *outp);
+
+	return 0;
+}
+
+int of_read_u32_array(const struct device_node *np, const char *propname,
+		      u32 *out_values, size_t sz)
+{
+	const __be32 *val;
+
+	debug("%s: %s: ", __func__, propname);
+	val = of_find_property_value_of_size(np, propname,
+					     sz * sizeof(*out_values));
+
+	if (IS_ERR(val))
+		return PTR_ERR(val);
+
+	debug("size %zd\n", sz);
+	while (sz--)
+		*out_values++ = be32_to_cpup(val++);
+
+	return 0;
+}
+
+int of_property_match_string(const struct device_node *np, const char *propname,
+			     const char *string)
+{
+	const struct property *prop = of_find_property(np, propname, NULL);
+	size_t l;
+	int i;
+	const char *p, *end;
+
+	if (!prop)
+		return -EINVAL;
+	if (!prop->value)
+		return -ENODATA;
+
+	p = prop->value;
+	end = p + prop->length;
+
+	for (i = 0; p < end; i++, p += l) {
+		l = strnlen(p, end - p) + 1;
+		if (p + l > end)
+			return -EILSEQ;
+		debug("comparing %s with %s\n", string, p);
+		if (strcmp(string, p) == 0)
+			return i; /* Found it; return index */
+	}
+	return -ENODATA;
+}
+
+/**
+ * of_property_read_string_helper() - Utility helper for parsing string properties
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ * @out_strs:	output array of string pointers.
+ * @sz:		number of array elements to read.
+ * @skip:	Number of strings to skip over at beginning of list.
+ *
+ * Don't call this function directly. It is a utility helper for the
+ * of_property_read_string*() family of functions.
+ */
+int of_property_read_string_helper(const struct device_node *np,
+				   const char *propname, const char **out_strs,
+				   size_t sz, int skip)
+{
+	const struct property *prop = of_find_property(np, propname, NULL);
+	int l = 0, i = 0;
+	const char *p, *end;
+
+	if (!prop)
+		return -EINVAL;
+	if (!prop->value)
+		return -ENODATA;
+	p = prop->value;
+	end = p + prop->length;
+
+	for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) {
+		l = strnlen(p, end - p) + 1;
+		if (p + l > end)
+			return -EILSEQ;
+		if (out_strs && i >= skip)
+			*out_strs++ = p;
+	}
+	i -= skip;
+	return i <= 0 ? -ENODATA : i;
+}
+
+static int __of_parse_phandle_with_args(const struct device_node *np,
+					const char *list_name,
+					const char *cells_name,
+					int cell_count, int index,
+					struct of_phandle_args *out_args)
+{
+	const __be32 *list, *list_end;
+	int rc = 0, cur_index = 0;
+	uint32_t count = 0;
+	struct device_node *node = NULL;
+	phandle phandle;
+	int size;
+
+	/* Retrieve the phandle list property */
+	list = of_get_property(np, list_name, &size);
+	if (!list)
+		return -ENOENT;
+	list_end = list + size / sizeof(*list);
+
+	/* Loop over the phandles until all the requested entry is found */
+	while (list < list_end) {
+		rc = -EINVAL;
+		count = 0;
+
+		/*
+		 * If phandle is 0, then it is an empty entry with no
+		 * arguments.  Skip forward to the next entry.
+		 */
+		phandle = be32_to_cpup(list++);
+		if (phandle) {
+			/*
+			 * Find the provider node and parse the #*-cells
+			 * property to determine the argument length.
+			 *
+			 * This is not needed if the cell count is hard-coded
+			 * (i.e. cells_name not set, but cell_count is set),
+			 * except when we're going to return the found node
+			 * below.
+			 */
+			if (cells_name || cur_index == index) {
+				node = of_find_node_by_phandle(phandle);
+				if (!node) {
+					debug("%s: could not find phandle\n",
+					      np->full_name);
+					goto err;
+				}
+			}
+
+			if (cells_name) {
+				if (of_read_u32(node, cells_name, &count)) {
+					debug("%s: could not get %s for %s\n",
+					      np->full_name, cells_name,
+					      node->full_name);
+					goto err;
+				}
+			} else {
+				count = cell_count;
+			}
+
+			/*
+			 * Make sure that the arguments actually fit in the
+			 * remaining property data length
+			 */
+			if (list + count > list_end) {
+				debug("%s: arguments longer than property\n",
+				      np->full_name);
+				goto err;
+			}
+		}
+
+		/*
+		 * All of the error cases above bail out of the loop, so at
+		 * this point, the parsing is successful. If the requested
+		 * index matches, then fill the out_args structure and return,
+		 * or return -ENOENT for an empty entry.
+		 */
+		rc = -ENOENT;
+		if (cur_index == index) {
+			if (!phandle)
+				goto err;
+
+			if (out_args) {
+				int i;
+				if (WARN_ON(count > OF_MAX_PHANDLE_ARGS))
+					count = OF_MAX_PHANDLE_ARGS;
+				out_args->np = node;
+				out_args->args_count = count;
+				for (i = 0; i < count; i++)
+					out_args->args[i] =
+							be32_to_cpup(list++);
+			} else {
+				of_node_put(node);
+			}
+
+			/* Found it! return success */
+			return 0;
+		}
+
+		of_node_put(node);
+		node = NULL;
+		list += count;
+		cur_index++;
+	}
+
+	/*
+	 * Unlock node before returning result; will be one of:
+	 * -ENOENT : index is for empty phandle
+	 * -EINVAL : parsing error on data
+	 * [1..n]  : Number of phandle (count mode; when index = -1)
+	 */
+	rc = index < 0 ? cur_index : -ENOENT;
+ err:
+	if (node)
+		of_node_put(node);
+	return rc;
+}
+
+struct device_node *of_parse_phandle(const struct device_node *np,
+				     const char *phandle_name, int index)
+{
+	struct of_phandle_args args;
+
+	if (index < 0)
+		return NULL;
+
+	if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, index,
+					 &args))
+		return NULL;
+
+	return args.np;
+}
+
+int of_parse_phandle_with_args(const struct device_node *np,
+			       const char *list_name, const char *cells_name,
+			       int index, struct of_phandle_args *out_args)
+{
+	if (index < 0)
+		return -EINVAL;
+
+	return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
+					    index, out_args);
+}
+
+static void of_alias_add(struct alias_prop *ap, struct device_node *np,
+			 int id, const char *stem, int stem_len)
+{
+	ap->np = np;
+	ap->id = id;
+	strncpy(ap->stem, stem, stem_len);
+	ap->stem[stem_len] = 0;
+	list_add_tail(&ap->link, &aliases_lookup);
+	debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
+	      ap->alias, ap->stem, ap->id, of_node_full_name(np));
+}
+
+int of_alias_scan(void)
+{
+	struct property *pp;
+
+	of_aliases = of_find_node_by_path("/aliases");
+	of_chosen = of_find_node_by_path("/chosen");
+	if (of_chosen == NULL)
+		of_chosen = of_find_node_by_path("/chosen at 0");
+
+	if (of_chosen) {
+		const char *name;
+
+		name = of_get_property(of_chosen, "stdout-path", NULL);
+		if (name)
+			of_stdout = of_find_node_opts_by_path(name,
+							&of_stdout_options);
+	}
+
+	if (!of_aliases)
+		return 0;
+
+	for_each_property_of_node(of_aliases, pp) {
+		const char *start = pp->name;
+		const char *end = start + strlen(start);
+		struct device_node *np;
+		struct alias_prop *ap;
+		ulong id;
+		int len;
+
+		/* Skip those we do not want to proceed */
+		if (!strcmp(pp->name, "name") ||
+		    !strcmp(pp->name, "phandle") ||
+		    !strcmp(pp->name, "linux,phandle"))
+			continue;
+
+		np = of_find_node_by_path(pp->value);
+		if (!np)
+			continue;
+
+		/*
+		 * walk the alias backwards to extract the id and work out
+		 * the 'stem' string
+		 */
+		while (isdigit(*(end-1)) && end > start)
+			end--;
+		len = end - start;
+
+		if (strict_strtoul(end, 10, &id) < 0)
+			continue;
+
+		/* Allocate an alias_prop with enough space for the stem */
+		ap = malloc(sizeof(*ap) + len + 1);
+		if (!ap)
+			return -ENOMEM;
+		memset(ap, 0, sizeof(*ap) + len + 1);
+		ap->alias = start;
+		of_alias_add(ap, np, id, start, len);
+	}
+
+	return 0;
+}
+
+int of_alias_get_id(const struct device_node *np, const char *stem)
+{
+	struct alias_prop *app;
+	int id = -ENODEV;
+
+	mutex_lock(&of_mutex);
+	list_for_each_entry(app, &aliases_lookup, link) {
+		if (strcmp(app->stem, stem) != 0)
+			continue;
+
+		if (np == app->np) {
+			id = app->id;
+			break;
+		}
+	}
+	mutex_unlock(&of_mutex);
+
+	return id;
+}
+
+struct device_node *of_get_stdout(void)
+{
+	return of_stdout;
+}
diff --git a/include/dm/of_access.h b/include/dm/of_access.h
new file mode 100644
index 0000000000..142f0f43c9
--- /dev/null
+++ b/include/dm/of_access.h
@@ -0,0 +1,347 @@
+/*
+ * Originally from Linux v4.9
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp.
+ * Updates for SPARC64 by David S. Miller
+ * Derived from PowerPC and Sparc prom.h files by Stephen Rothwell, IBM Corp.
+ *
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * Modified for U-Boot
+ * Copyright (c) 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _DM_OF_ACCESS_H
+#define _DM_OF_ACCESS_H
+
+#include <dm/of.h>
+
+/**
+ * of_find_all_nodes - Get next node in global list
+ * @prev:	Previous node or NULL to start iteration
+ *		of_node_put() will be called on it
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_all_nodes(struct device_node *prev);
+
+#define for_each_of_allnodes_from(from, dn) \
+	for (dn = of_find_all_nodes(from); dn; dn = of_find_all_nodes(dn))
+#define for_each_of_allnodes(dn) for_each_of_allnodes_from(NULL, dn)
+
+/* Dummy functions to mirror Linux. These are not used in U-Boot */
+#define of_node_get(x) (x)
+static inline void of_node_put(const struct device_node *np) { }
+
+/**
+ * of_n_addr_cells() - Get the number of address cells for a node
+ *
+ * This walks back up the tree to find the closest #address-cells property
+ * which controls the given node.
+ *
+ * @np: Node pointer to check
+ * @return number of address cells this node uses
+ */
+int of_n_addr_cells(const struct device_node *np);
+
+/**
+ * of_n_size_cells() - Get the number of size cells for a node
+ *
+ * This walks back up the tree to find the closest #size-cells property
+ * which controls the given node.
+ *
+ * @np: Node pointer to check
+ * @return number of size cells this node uses
+ */
+int of_n_size_cells(const struct device_node *np);
+
+/**
+ * of_find_property() - find a property in a node
+ *
+ * @np: Pointer to device node holding property
+ * @name: Name of property
+ * @lenp: If non-NULL, returns length of property
+ * @return pointer to property, or NULL if not found
+ */
+struct property *of_find_property(const struct device_node *np,
+				  const char *name, int *lenp);
+
+/**
+ * of_get_property() - get a property value
+ *
+ * Find a property with a given name for a given node and return the value.
+ *
+ * @np: Pointer to device node holding property
+ * @name: Name of property
+ * @lenp: If non-NULL, returns length of property
+ * @return pointer to property value, or NULL if not found
+ */
+const void *of_get_property(const struct device_node *np, const char *name,
+			    int *lenp);
+
+/**
+ * of_device_is_compatible() - Check if the node matches given constraints
+ * @device: pointer to node
+ * @compat: required compatible string, NULL or "" for any match
+ * @type: required device_type value, NULL or "" for any match
+ * @name: required node name, NULL or "" for any match
+ *
+ * Checks if the given @compat, @type and @name strings match the
+ * properties of the given @device. A constraints can be skipped by
+ * passing NULL or an empty string as the constraint.
+ *
+ * @return 0 for no match, and a positive integer on match. The return
+ * value is a relative score with larger values indicating better
+ * matches. The score is weighted for the most specific compatible value
+ * to get the highest score. Matching type is next, followed by matching
+ * name. Practically speaking, this results in the following priority
+ * order for matches:
+ *
+ * 1. specific compatible && type && name
+ * 2. specific compatible && type
+ * 3. specific compatible && name
+ * 4. specific compatible
+ * 5. general compatible && type && name
+ * 6. general compatible && type
+ * 7. general compatible && name
+ * 8. general compatible
+ * 9. type && name
+ * 10. type
+ * 11. name
+ */
+int of_device_is_compatible(const struct device_node *np, const char *compat,
+			    const char *type, const char *name);
+
+/**
+ * of_device_is_available() - check if a device is available for use
+ *
+ * @device: Node to check for availability
+ *
+ * @return true if the status property is absent or set to "okay", false
+ * otherwise
+ */
+bool of_device_is_available(const struct device_node *np);
+
+/**
+ * of_get_parent() - Get a node's parent, if any
+ *
+ * @node: Node to check
+ * @eturns a node pointer, or NULL if none
+ */
+struct device_node *of_get_parent(const struct device_node *np);
+
+/**
+ * of_find_node_opts_by_path() - Find a node matching a full OF path
+ *
+ * @path: Either the full path to match, or if the path does not start with
+ *	'/', the name of a property of the /aliases node (an alias). In the
+ *	case of an alias, the node matching the alias' value will be returned.
+ * @opts: Address of a pointer into which to store the start of an options
+ *	string appended to the end of the path with a ':' separator. Can be NULL
+ *
+ * Valid paths:
+ *	/foo/bar	Full path
+ *	foo		Valid alias
+ *	foo/bar		Valid alias + relative path
+ *
+ * @return a node pointer or NULL if not found
+ */
+struct device_node *of_find_node_opts_by_path(const char *path,
+					      const char **opts);
+
+static inline struct device_node *of_find_node_by_path(const char *path)
+{
+	return of_find_node_opts_by_path(path, NULL);
+}
+
+/**
+ * of_find_compatible_node() - find a node based on its compatible string
+ *
+ * Find a node based on type and one of the tokens in its "compatible" property
+ * @from: Node to start searching from or NULL. the node you pass will not be
+ *	searched, only the next one will; typically, you pass what the previous
+ *	call returned.
+ * @type: The type string to match "device_type" or NULL to ignore
+ * @compatible:	The string to match to one of the tokens in the device
+ *	"compatible" list.
+ * @return node pointer or NULL if not found
+ */
+struct device_node *of_find_compatible_node(struct device_node *from,
+				const char *type, const char *compatible);
+
+/**
+ * of_find_node_by_phandle() - Find a node given a phandle
+ *
+ * @handle:	phandle of the node to find
+ *
+ * @return node pointer, or NULL if not found
+ */
+struct device_node *of_find_node_by_phandle(phandle handle);
+
+/**
+ * of_read_u32() - Find and read a 32-bit integer from a property
+ *
+ * Search for a property in a device node and read a 32-bit value from
+ * it.
+ *
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ * @outp:	pointer to return value, modified only if return value is 0.
+ *
+ * @return 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ */
+int of_read_u32(const struct device_node *np, const char *propname, u32 *outp);
+
+/**
+ * of_read_u32_array() - Find and read an array of 32 bit integers
+ *
+ * Search for a property in a device node and read 32-bit value(s) from
+ * it.
+ *
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ * @out_values:	pointer to return value, modified only if return value is 0.
+ * @sz:		number of array elements to read
+ * @return 0 on success, -EINVAL if the property does not exist, -ENODATA
+ * if property does not have a value, and -EOVERFLOW is longer than sz.
+ */
+int of_read_u32_array(const struct device_node *np, const char *propname,
+		      u32 *out_values, size_t sz);
+
+/**
+ * of_property_match_string() - Find string in a list and return index
+ *
+ * This function searches a string list property and returns the index
+ * of a specific string value.
+ *
+ * @np: pointer to node containing string list property
+ * @propname: string list property name
+ * @string: pointer to string to search for in string list
+ * @return 0 on success, -EINVAL if the property does not exist, -ENODATA
+ * if property does not have a value, and -EOVERFLOW is longer than sz.
+ */
+int of_property_match_string(const struct device_node *np, const char *propname,
+			     const char *string);
+
+int of_property_read_string_helper(const struct device_node *np,
+				   const char *propname, const char **out_strs,
+				   size_t sz, int index);
+
+/**
+ * of_property_read_string_index() - Find and read a string from a multiple
+ * strings property.
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ * @index:	index of the string in the list of strings
+ * @out_string:	pointer to null terminated return string, modified only if
+ *		return value is 0.
+ *
+ * Search for a property in a device tree node and retrieve a null
+ * terminated string value (pointer to data, not a copy) in the list of strings
+ * contained in that property.
+ * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
+ * property does not have a value, and -EILSEQ if the string is not
+ * null-terminated within the length of the property data.
+ *
+ * The out_string pointer is modified only if a valid string can be decoded.
+ */
+static inline int of_property_read_string_index(const struct device_node *np,
+						const char *propname,
+						int index, const char **output)
+{
+	int rc = of_property_read_string_helper(np, propname, output, 1, index);
+	return rc < 0 ? rc : 0;
+}
+
+/**
+ * of_parse_phandle - Resolve a phandle property to a device_node pointer
+ * @np: Pointer to device node holding phandle property
+ * @phandle_name: Name of property holding a phandle value
+ * @index: For properties holding a table of phandles, this is the index into
+ *         the table
+ *
+ * Returns the device_node pointer with refcount incremented.  Use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_parse_phandle(const struct device_node *np,
+				     const char *phandle_name, int index);
+
+/**
+ * of_parse_phandle_with_args() - Find a node pointed by phandle in a list
+ *
+ * @np:		pointer to a device tree node containing a list
+ * @list_name:	property name that contains a list
+ * @cells_name:	property name that specifies phandles' arguments count
+ * @index:	index of a phandle to parse out
+ * @out_args:	optional pointer to output arguments structure (will be filled)
+ * @return 0 on success (with @out_args filled out if not NULL), -ENOENT if
+ *	@list_name does not exist, -EINVAL if a phandle was not found,
+ *	@cells_name could not be found, the arguments were truncated or there
+ *	were too many arguments.
+ *
+ * This function is useful to parse lists of phandles and their arguments.
+ * Returns 0 on success and fills out_args, on error returns appropriate
+ * errno value.
+ *
+ * Caller is responsible to call of_node_put() on the returned out_args->np
+ * pointer.
+ *
+ * Example:
+ *
+ * phandle1: node1 {
+ *	#list-cells = <2>;
+ * }
+ *
+ * phandle2: node2 {
+ *	#list-cells = <1>;
+ * }
+ *
+ * node3 {
+ *	list = <&phandle1 1 2 &phandle2 3>;
+ * }
+ *
+ * To get a device_node of the `node2' node you may call this:
+ * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
+ */
+int of_parse_phandle_with_args(const struct device_node *np,
+			       const char *list_name, const char *cells_name,
+			       int index, struct of_phandle_args *out_args);
+
+/**
+ * of_alias_scan() - Scan all properties of the 'aliases' node
+ *
+ * The function scans all the properties of the 'aliases' node and populates
+ * the lookup table with the properties.  It returns the number of alias
+ * properties found, or an error code in case of failure.
+ *
+ * @return 9 if OK, -ENOMEM if not enough memory
+ */
+int of_alias_scan(void);
+
+/**
+ * of_alias_get_id - Get alias id for the given device_node
+ *
+ * Travels the lookup table to get the alias id for the given device_node and
+ * alias stem.
+ *
+ * @np:		Pointer to the given device_node
+ * @stem:	Alias stem of the given device_node
+ * @return alias ID, if found, else -ENODEV
+ */
+int of_alias_get_id(const struct device_node *np, const char *stem);
+
+/**
+ * of_get_stdout() - Get node to use for stdout
+ *
+ * @return node referred to by stdout-path alias, or NULL if none
+ */
+struct device_node *of_get_stdout(void);
+
+#endif
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 05/71] dm: Add a function to create a 'live' device tree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (3 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 04/71] dm: core: Add livetree access functions Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-11 14:59   ` Lothar Waßmann
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 06/71] dm: Build a live tree after relocation Simon Glass
                   ` (65 subsequent siblings)
  70 siblings, 1 reply; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

This function converts the flat device tree into a hierarchical one with
C structures and pointers. This is easier to access.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/of_live.h |  24 ++++
 lib/Makefile      |   1 +
 lib/of_live.c     | 333 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 358 insertions(+)
 create mode 100644 include/of_live.h
 create mode 100644 lib/of_live.c

diff --git a/include/of_live.h b/include/of_live.h
new file mode 100644
index 0000000000..f5303bb018
--- /dev/null
+++ b/include/of_live.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Support for a 'live' (as opposed to flat) device tree
+ */
+
+#ifndef _OF_LIVE_H
+#define _OF_LIVE_H
+
+struct device_node;
+
+/**
+ * of_live_build() - build a live (hierarchical) tree from a flat DT
+ *
+ * @fdt_blob: Input tree to convert
+ * @rootp: Returns live tree that was created
+ * @return 0 if OK, -ve on error
+ */
+int of_live_build(const void *fdt_blob, struct device_node **rootp);
+
+#endif
diff --git a/lib/Makefile b/lib/Makefile
index 23e9f1ef11..bc2fb0a361 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_ZLIB) += zlib/
 obj-$(CONFIG_BZIP2) += bzip2/
 obj-$(CONFIG_TIZEN) += tizen/
 obj-$(CONFIG_FIT) += libfdt/
+obj-$(CONFIG_OF_LIVE) += of_live.o
 obj-$(CONFIG_CMD_DHRYSTONE) += dhry/
 
 obj-$(CONFIG_AES) += aes.o
diff --git a/lib/of_live.c b/lib/of_live.c
new file mode 100644
index 0000000000..51927f9e91
--- /dev/null
+++ b/lib/of_live.c
@@ -0,0 +1,333 @@
+/*
+ * Copyright 2009 Benjamin Herrenschmidt, IBM Corp
+ * benh at kernel.crashing.org
+ *
+ * Based on parts of drivers/of/fdt.c from Linux v4.9
+ * Modifications for U-Boot
+ * Copyright (c) 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <of_live.h>
+#include <malloc.h>
+#include <dm/of_access.h>
+#include <linux/err.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void *unflatten_dt_alloc(void **mem, unsigned long size,
+				unsigned long align)
+{
+	void *res;
+
+	*mem = PTR_ALIGN(*mem, align);
+	res = *mem;
+	*mem += size;
+
+	return res;
+}
+
+/**
+ * unflatten_dt_node() - Alloc and populate a device_node from the flat tree
+ * @blob: The parent device tree blob
+ * @mem: Memory chunk to use for allocating device nodes and properties
+ * @poffset: pointer to node in flat tree
+ * @dad: Parent struct device_node
+ * @nodepp: The device_node tree created by the call
+ * @fpsize: Size of the node path up at t05he current depth.
+ * @dryrun: If true, do not allocate device nodes but still calculate needed
+ * memory size
+ */
+static void *unflatten_dt_node(const void *blob, void *mem, int *poffset,
+			       struct device_node *dad,
+			       struct device_node **nodepp,
+			       unsigned long fpsize, bool dryrun)
+{
+	const __be32 *p;
+	struct device_node *np;
+	struct property *pp, **prev_pp = NULL;
+	const char *pathp;
+	int l;
+	unsigned int allocl;
+	static int depth;
+	int old_depth;
+	int offset;
+	int has_name = 0;
+	int new_format = 0;
+
+	pathp = fdt_get_name(blob, *poffset, &l);
+	if (!pathp)
+		return mem;
+
+	allocl = ++l;
+
+	/*
+	 * version 0x10 has a more compact unit name here instead of the full
+	 * path. we accumulate the full path size using "fpsize", we'll rebuild
+	 * it later. We detect this because the first character of the name is
+	 * not '/'.
+	 */
+	if ((*pathp) != '/') {
+		new_format = 1;
+		if (fpsize == 0) {
+			/*
+			 * root node: special case. fpsize accounts for path
+			 * plus terminating zero. root node only has '/', so
+			 * fpsize should be 2, but we want to avoid the first
+			 * level nodes to have two '/' so we use fpsize 1 here
+			 */
+			fpsize = 1;
+			allocl = 2;
+			l = 1;
+			pathp = "";
+		} else {
+			/*
+			 * account for '/' and path size minus terminal 0
+			 * already in 'l'
+			 */
+			fpsize += l;
+			allocl = fpsize;
+		}
+	}
+
+	np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
+				__alignof__(struct device_node));
+	if (!dryrun) {
+		char *fn;
+
+		fn = (char *)np + sizeof(*np);
+		np->full_name = fn;
+		if (new_format) {
+			/* rebuild full path for new format */
+			if (dad && dad->parent) {
+				strcpy(fn, dad->full_name);
+#ifdef DEBUG
+				if ((strlen(fn) + l + 1) != allocl) {
+					debug("%s: p: %d, l: %d, a: %d\n",
+					      pathp, (int)strlen(fn), l,
+					      allocl);
+				}
+#endif
+				fn += strlen(fn);
+			}
+			*(fn++) = '/';
+		}
+		memcpy(fn, pathp, l);
+
+		prev_pp = &np->properties;
+		if (dad != NULL) {
+			np->parent = dad;
+			np->sibling = dad->child;
+			dad->child = np;
+		}
+	}
+	/* process properties */
+	for (offset = fdt_first_property_offset(blob, *poffset);
+	     (offset >= 0);
+	     (offset = fdt_next_property_offset(blob, offset))) {
+		const char *pname;
+		int sz;
+
+		p = fdt_getprop_by_offset(blob, offset, &pname, &sz);
+		if (!p) {
+			offset = -FDT_ERR_INTERNAL;
+			break;
+		}
+
+		if (pname == NULL) {
+			debug("Can't find property name in list !\n");
+			break;
+		}
+		if (strcmp(pname, "name") == 0)
+			has_name = 1;
+		pp = unflatten_dt_alloc(&mem, sizeof(struct property),
+					__alignof__(struct property));
+		if (!dryrun) {
+			/*
+			 * We accept flattened tree phandles either in
+			 * ePAPR-style "phandle" properties, or the
+			 * legacy "linux,phandle" properties.  If both
+			 * appear and have different values, things
+			 * will get weird.  Don't do that. */
+			if ((strcmp(pname, "phandle") == 0) ||
+			    (strcmp(pname, "linux,phandle") == 0)) {
+				if (np->phandle == 0)
+					np->phandle = be32_to_cpup(p);
+			}
+			/*
+			 * And we process the "ibm,phandle" property
+			 * used in pSeries dynamic device tree
+			 * stuff */
+			if (strcmp(pname, "ibm,phandle") == 0)
+				np->phandle = be32_to_cpup(p);
+			pp->name = (char *)pname;
+			pp->length = sz;
+			pp->value = (__be32 *)p;
+			*prev_pp = pp;
+			prev_pp = &pp->next;
+		}
+	}
+	/*
+	 * with version 0x10 we may not have the name property, recreate
+	 * it here from the unit name if absent
+	 */
+	if (!has_name) {
+		const char *p1 = pathp, *ps = pathp, *pa = NULL;
+		int sz;
+
+		while (*p1) {
+			if ((*p1) == '@')
+				pa = p1;
+			if ((*p1) == '/')
+				ps = p1 + 1;
+			p1++;
+		}
+		if (pa < ps)
+			pa = p1;
+		sz = (pa - ps) + 1;
+		pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
+					__alignof__(struct property));
+		if (!dryrun) {
+			pp->name = "name";
+			pp->length = sz;
+			pp->value = pp + 1;
+			*prev_pp = pp;
+			prev_pp = &pp->next;
+			memcpy(pp->value, ps, sz - 1);
+			((char *)pp->value)[sz - 1] = 0;
+			debug("fixed up name for %s -> %s\n", pathp,
+			      (char *)pp->value);
+		}
+	}
+	if (!dryrun) {
+		*prev_pp = NULL;
+		np->name = of_get_property(np, "name", NULL);
+		np->type = of_get_property(np, "device_type", NULL);
+
+		if (!np->name)
+			np->name = "<NULL>";
+		if (!np->type)
+			np->type = "<NULL>";	}
+
+	old_depth = depth;
+	*poffset = fdt_next_node(blob, *poffset, &depth);
+	if (depth < 0)
+		depth = 0;
+	while (*poffset > 0 && depth > old_depth)
+		mem = unflatten_dt_node(blob, mem, poffset, np, NULL,
+					fpsize, dryrun);
+
+	if (*poffset < 0 && *poffset != -FDT_ERR_NOTFOUND) {
+		debug("unflatten: error %d processing FDT\n", *poffset);
+		return NULL;
+	}
+
+	/*
+	 * Reverse the child list. Some drivers assumes node order matches .dts
+	 * node order
+	 */
+	if (!dryrun && np->child) {
+		struct device_node *child = np->child;
+		np->child = NULL;
+		while (child) {
+			struct device_node *next = child->sibling;
+
+			child->sibling = np->child;
+			np->child = child;
+			child = next;
+		}
+	}
+
+	if (nodepp)
+		*nodepp = np;
+
+	return mem;
+}
+
+/**
+ * unflatten_device_tree() - create tree of device_nodes from flat blob
+ *
+ * unflattens a device-tree, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used.
+ * @blob: The blob to expand
+ * @mynodes: The device_node tree created by the call
+ * @return 0 if OK, -ve on error
+ */
+static int unflatten_device_tree(const void *blob,
+				 struct device_node **mynodes)
+{
+	unsigned long size;
+	int start;
+	void *mem;
+
+	debug(" -> unflatten_device_tree()\n");
+
+	if (!blob) {
+		debug("No device tree pointer\n");
+		return -EINVAL;
+	}
+
+	debug("Unflattening device tree:\n");
+	debug("magic: %08x\n", fdt_magic(blob));
+	debug("size: %08x\n", fdt_totalsize(blob));
+	debug("version: %08x\n", fdt_version(blob));
+
+	if (fdt_check_header(blob)) {
+		debug("Invalid device tree blob header\n");
+		return -EINVAL;
+	}
+
+	/* First pass, scan for size */
+	start = 0;
+	size = (unsigned long)unflatten_dt_node(blob, NULL, &start, NULL, NULL,
+						0, true);
+	size = ALIGN(size, 4);
+
+	debug("  size is %lx, allocating...\n", size);
+
+	/* Allocate memory for the expanded device tree */
+	mem = malloc(size + 4);
+	memset(mem, '\0', size);
+
+	*(__be32 *)(mem + size) = cpu_to_be32(0xdeadbeef);
+
+	debug("  unflattening %p...\n", mem);
+
+	/* Second pass, do actual unflattening */
+	start = 0;
+	unflatten_dt_node(blob, mem, &start, NULL, mynodes, 0, false);
+	if (be32_to_cpup(mem + size) != 0xdeadbeef) {
+		debug("End of tree marker overwritten: %08x\n",
+		      be32_to_cpup(mem + size));
+		return -ENOSPC;
+	}
+
+	debug(" <- unflatten_device_tree()\n");
+
+	return 0;
+}
+
+int of_live_build(const void *fdt_blob, struct device_node **rootp)
+{
+	int ret;
+
+	debug("%s: start\n", __func__);
+	ret = unflatten_device_tree(fdt_blob, rootp);
+	if (ret) {
+		debug("Failed to create live tree: err=%d\n", ret);
+		return ret;
+	}
+	ret = of_alias_scan();
+	if (ret) {
+		debug("Failed to scan live tree aliases: err=%d\n", ret);
+		return ret;
+	}
+	debug("%s: stop\n", __func__);
+
+	return ret;
+}
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 06/71] dm: Build a live tree after relocation
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (4 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 05/71] dm: Add a function to create a 'live' device tree Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 07/71] dm: core: Rename of_device_is_compatible() Simon Glass
                   ` (64 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

If enabled, build a live device tree after relocation. This can then be
used by driver model.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/board_r.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/common/board_r.c b/common/board_r.c
index d69a33c4a3..47bf00dde7 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -42,6 +42,7 @@
 #endif
 #include <mmc.h>
 #include <nand.h>
+#include <of_live.h>
 #include <onenand_uboot.h>
 #include <scsi.h>
 #include <serial.h>
@@ -294,6 +295,14 @@ static int initr_noncached(void)
 }
 #endif
 
+#ifdef CONFIG_OF_LIVE
+static int initr_of_live(void)
+{
+	return of_live_build(gd->fdt_blob,
+			      (struct device_node **)&gd->of_root);
+}
+#endif
+
 #ifdef CONFIG_DM
 static int initr_dm(void)
 {
@@ -741,6 +750,9 @@ static init_fnc_t init_sequence_r[] = {
 	initr_noncached,
 #endif
 	bootstage_relocate,
+#ifdef CONFIG_OF_LIVE
+	initr_of_live,
+#endif
 #ifdef CONFIG_DM
 	initr_dm,
 #endif
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 07/71] dm: core: Rename of_device_is_compatible()
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (5 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 06/71] dm: Build a live tree after relocation Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 08/71] dm: core: Add operations on device tree references Simon Glass
                   ` (63 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

The of_ prefix conflicts with the livetree version of this function.
Rename it to avoid problems when we add livetree support.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/device.c             | 2 +-
 drivers/firmware/psci.c           | 4 ++--
 drivers/mmc/xenon_sdhci.c         | 2 +-
 drivers/net/cpsw-common.c         | 4 ++--
 drivers/net/mvneta.c              | 2 +-
 drivers/phy/marvell/comphy_core.c | 4 ++--
 drivers/usb/host/ehci-marvell.c   | 2 +-
 drivers/usb/host/xhci-rockchip.c  | 2 +-
 include/dm/device.h               | 4 ++--
 9 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 363c1833e9..f5e85413f7 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -701,7 +701,7 @@ int device_set_name(struct udevice *dev, const char *name)
 	return 0;
 }
 
-bool of_device_is_compatible(struct udevice *dev, const char *compat)
+bool device_is_compatible(struct udevice *dev, const char *compat)
 {
 	const void *fdt = gd->fdt_blob;
 
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index 7652cc27aa..451fbdebba 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -40,8 +40,8 @@ static unsigned long __invoke_psci_fn_smc(unsigned long function_id,
 static int psci_bind(struct udevice *dev)
 {
 	/* No SYSTEM_RESET support for PSCI 0.1 */
-	if (of_device_is_compatible(dev, "arm,psci-0.2") ||
-	    of_device_is_compatible(dev, "arm,psci-1.0")) {
+	if (device_is_compatible(dev, "arm,psci-0.2") ||
+	    device_is_compatible(dev, "arm,psci-1.0")) {
 		int ret;
 
 		/* bind psci-sysreset optionally */
diff --git a/drivers/mmc/xenon_sdhci.c b/drivers/mmc/xenon_sdhci.c
index 6cd176f9f8..2b7cb7f6b6 100644
--- a/drivers/mmc/xenon_sdhci.c
+++ b/drivers/mmc/xenon_sdhci.c
@@ -454,7 +454,7 @@ static int xenon_sdhci_ofdata_to_platdata(struct udevice *dev)
 	host->name = dev->name;
 	host->ioaddr = (void *)devfdt_get_addr(dev);
 
-	if (of_device_is_compatible(dev, "marvell,armada-3700-sdhci"))
+	if (device_is_compatible(dev, "marvell,armada-3700-sdhci"))
 		priv->pad_ctrl_reg = (void *)devfdt_get_addr_index(dev, 1);
 
 	name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "marvell,pad-type",
diff --git a/drivers/net/cpsw-common.c b/drivers/net/cpsw-common.c
index 55f56d9555..8970ee00af 100644
--- a/drivers/net/cpsw-common.c
+++ b/drivers/net/cpsw-common.c
@@ -104,10 +104,10 @@ int ti_cm_get_macid(struct udevice *dev, int slave, u8 *mac_addr)
 	if (of_machine_is_compatible("ti,am33xx"))
 		return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr);
 
-	if (of_device_is_compatible(dev, "ti,am3517-emac"))
+	if (device_is_compatible(dev, "ti,am3517-emac"))
 		return davinci_emac_3517_get_macid(dev, 0x110, slave, mac_addr);
 
-	if (of_device_is_compatible(dev, "ti,dm816-emac"))
+	if (device_is_compatible(dev, "ti,dm816-emac"))
 		return cpsw_am33xx_cm_get_macid(dev, 0x30, slave, mac_addr);
 
 	if (of_machine_is_compatible("ti,am43"))
diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c
index af07b281e8..50577d7f07 100644
--- a/drivers/net/mvneta.c
+++ b/drivers/net/mvneta.c
@@ -1695,7 +1695,7 @@ static int mvneta_probe(struct udevice *dev)
 	pp->base = (void __iomem *)pdata->iobase;
 
 	/* Configure MBUS address windows */
-	if (of_device_is_compatible(dev, "marvell,armada-3700-neta"))
+	if (device_is_compatible(dev, "marvell,armada-3700-neta"))
 		mvneta_bypass_mbus_windows(pp);
 	else
 		mvneta_conf_mbus_windows(pp);
diff --git a/drivers/phy/marvell/comphy_core.c b/drivers/phy/marvell/comphy_core.c
index 81dfbe4dda..140c112aa0 100644
--- a/drivers/phy/marvell/comphy_core.c
+++ b/drivers/phy/marvell/comphy_core.c
@@ -137,10 +137,10 @@ static int comphy_probe(struct udevice *dev)
 		return -EINVAL;
 	}
 
-	if (of_device_is_compatible(dev, "marvell,comphy-armada-3700"))
+	if (device_is_compatible(dev, "marvell,comphy-armada-3700"))
 		chip_cfg->ptr_comphy_chip_init = comphy_a3700_init;
 
-	if (of_device_is_compatible(dev, "marvell,comphy-cp110"))
+	if (device_is_compatible(dev, "marvell,comphy-cp110"))
 		chip_cfg->ptr_comphy_chip_init = comphy_cp110_init;
 
 	/*
diff --git a/drivers/usb/host/ehci-marvell.c b/drivers/usb/host/ehci-marvell.c
index 56409df26e..7a0f2083ad 100644
--- a/drivers/usb/host/ehci-marvell.c
+++ b/drivers/usb/host/ehci-marvell.c
@@ -121,7 +121,7 @@ static int ehci_mvebu_probe(struct udevice *dev)
 	 * Also, the address decoder doesn't need to get setup with this
 	 * SoC, so don't call usb_brg_adrdec_setup().
 	 */
-	if (of_device_is_compatible(dev, "marvell,armada3700-ehci"))
+	if (device_is_compatible(dev, "marvell,armada3700-ehci"))
 		marvell_ehci_ops.powerup_fixup = marvell_ehci_powerup_fixup;
 	else
 		usb_brg_adrdec_setup((void *)priv->hcd_base);
diff --git a/drivers/usb/host/xhci-rockchip.c b/drivers/usb/host/xhci-rockchip.c
index 5e7130f0e1..38e1c68db7 100644
--- a/drivers/usb/host/xhci-rockchip.c
+++ b/drivers/usb/host/xhci-rockchip.c
@@ -55,7 +55,7 @@ static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
 	/* Get the base address for usbphy from the device node */
 	for (device_find_first_child(dev, &child); child;
 	     device_find_next_child(&child)) {
-		if (!of_device_is_compatible(child, "rockchip,rk3399-usb3-phy"))
+		if (!device_is_compatible(child, "rockchip,rk3399-usb3-phy"))
 			continue;
 		plat->phy_base = devfdt_get_addr(child);
 		break;
diff --git a/include/dm/device.h b/include/dm/device.h
index 89f9f53c43..99537fd1cb 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -554,7 +554,7 @@ int device_set_name(struct udevice *dev, const char *name);
 void device_set_name_alloced(struct udevice *dev);
 
 /**
- * of_device_is_compatible() - check if the device is compatible with the compat
+ * device_is_compatible() - check if the device is compatible with the compat
  *
  * This allows to check whether the device is comaptible with the compat.
  *
@@ -563,7 +563,7 @@ void device_set_name_alloced(struct udevice *dev);
  *		device
  * @return true if OK, false if the compatible is not found
  */
-bool of_device_is_compatible(struct udevice *dev, const char *compat);
+bool device_is_compatible(struct udevice *dev, const char *compat);
 
 /**
  * of_machine_is_compatible() - check if the machine is compatible with
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 08/71] dm: core: Add operations on device tree references
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (6 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 07/71] dm: core: Rename of_device_is_compatible() Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 09/71] dm: core: Add livetree address functions Simon Glass
                   ` (62 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

Since U-Boot supports both a live tree and a flat tree, we need an easy
way to access the tree without worrying about which is currently active.
To support this, U-Boot has the concept of an ofnode, which can refer
either to a live tree node or a flat tree node.

For the live tree, the reference contains a pointer to the node (struct
device_node *) or NULL if the node is invalid. For the flat tree, the
reference contains the node offset or -1 if the node is invalid.

Add a basic set of operations using ofnodes. These are implemented by
using either libfdt functions (in the case of a flat DT reference) or
the live-tree of_...() functions.

Note that it is not possible to have both live and flat references active
at the same time. As soon as the live tree is available, everything in
U-Boot should switch to using that. This avoids confusion and allows us to
assume that the type of a reference is simply based on whether we have a
live tree yet, or not.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/Makefile |   1 +
 drivers/core/ofnode.c | 552 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/dm/ofnode.h   | 466 +++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 1016 insertions(+), 3 deletions(-)
 create mode 100644 drivers/core/ofnode.c

diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index 4211fd1e22..c25288e464 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_DM)	+= dump.o
 obj-$(CONFIG_$(SPL_)REGMAP)	+= regmap.o
 obj-$(CONFIG_$(SPL_)SYSCON)	+= syscon-uclass.o
 obj-$(CONFIG_OF_LIVE) += of_access.o
+obj-$(CONFIG_OF_CONTROL) += ofnode.o
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
new file mode 100644
index 0000000000..e6c9a28bae
--- /dev/null
+++ b/drivers/core/ofnode.c
@@ -0,0 +1,552 @@
+/*
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <fdt_support.h>
+#include <libfdt.h>
+#include <dm/of_access.h>
+#include <dm/ofnode.h>
+#include <linux/err.h>
+
+int ofnode_read_u32(ofnode node, const char *propname, u32 *outp)
+{
+	assert(ofnode_valid(node));
+	debug("%s: %s: ", __func__, propname);
+
+	if (ofnode_is_np(node)) {
+		return of_read_u32(ofnode_to_np(node), propname, outp);
+	} else {
+		const int *cell;
+		int len;
+
+		cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
+				   propname, &len);
+		if (!cell || len < sizeof(int)) {
+			debug("(not found)\n");
+			return -EINVAL;
+		}
+		*outp = fdt32_to_cpu(cell[0]);
+	}
+	debug("%#x (%d)\n", *outp, *outp);
+
+	return 0;
+}
+
+int ofnode_read_u32_default(ofnode node, const char *propname, u32 def)
+{
+	assert(ofnode_valid(node));
+	ofnode_read_u32(node, propname, &def);
+
+	return def;
+}
+
+int ofnode_read_s32_default(ofnode node, const char *propname, s32 def)
+{
+	assert(ofnode_valid(node));
+	ofnode_read_u32(node, propname, (u32 *)&def);
+
+	return def;
+}
+
+bool ofnode_read_bool(ofnode node, const char *propname)
+{
+	bool val;
+
+	assert(ofnode_valid(node));
+	debug("%s: %s: ", __func__, propname);
+
+	if (ofnode_is_np(node)) {
+		val = !!of_find_property(ofnode_to_np(node), propname, NULL);
+	} else {
+		val = !!fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
+				    propname, NULL);
+	}
+	debug("%s\n", val ? "true" : "false");
+
+	return val;
+}
+
+const char *ofnode_read_string(ofnode node, const char *propname)
+{
+	const char *str = NULL;
+	int len = -1;
+
+	assert(ofnode_valid(node));
+	debug("%s: %s: ", __func__, propname);
+
+	if (ofnode_is_np(node)) {
+		struct property *prop = of_find_property(
+				ofnode_to_np(node), propname, NULL);
+
+		if (prop) {
+			str = prop->value;
+			len = prop->length;
+		}
+	} else {
+		str = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
+				  propname, &len);
+	}
+	if (!str) {
+		debug("<not found>\n");
+		return NULL;
+	}
+	if (strnlen(str, len) >= len) {
+		debug("<invalid>\n");
+		return NULL;
+	}
+	debug("%s\n", str);
+
+	return str;
+}
+
+ofnode ofnode_find_subnode(ofnode node, const char *subnode_name)
+{
+	ofnode subnode;
+
+	assert(ofnode_valid(node));
+	debug("%s: %s: ", __func__, subnode_name);
+
+	if (ofnode_is_np(node)) {
+		const struct device_node *np = ofnode_to_np(node);
+
+		for (np = np->child; np; np = np->sibling) {
+			if (!strcmp(subnode_name, np->name))
+				break;
+		}
+		subnode = np_to_ofnode(np);
+	} else {
+		int ooffset = fdt_subnode_offset(gd->fdt_blob,
+				ofnode_to_offset(node), subnode_name);
+		subnode = offset_to_ofnode(ooffset);
+	}
+	debug("%s\n", ofnode_valid(subnode) ?
+	      ofnode_get_name(subnode) : "<none>");
+
+	return subnode;
+}
+
+int ofnode_read_u32_array(ofnode node, const char *propname,
+			  u32 *out_values, size_t sz)
+{
+	assert(ofnode_valid(node));
+	debug("%s: %s: ", __func__, propname);
+
+	if (ofnode_is_np(node)) {
+		return of_read_u32_array(ofnode_to_np(node), propname,
+					 out_values, sz);
+	} else {
+		return fdtdec_get_int_array(gd->fdt_blob,
+					    ofnode_to_offset(node), propname,
+					    out_values, sz);
+	}
+}
+
+ofnode ofnode_first_subnode(ofnode node)
+{
+	assert(ofnode_valid(node));
+	if (ofnode_is_np(node))
+		return np_to_ofnode(node.np->child);
+
+	return offset_to_ofnode(
+		fdt_first_subnode(gd->fdt_blob, ofnode_to_offset(node)));
+}
+
+ofnode ofnode_next_subnode(ofnode node)
+{
+	assert(ofnode_valid(node));
+	if (ofnode_is_np(node))
+		return np_to_ofnode(node.np->sibling);
+
+	return offset_to_ofnode(
+		fdt_next_subnode(gd->fdt_blob, ofnode_to_offset(node)));
+}
+
+const char *ofnode_get_name(ofnode node)
+{
+	assert(ofnode_valid(node));
+	if (ofnode_is_np(node))
+		return strrchr(node.np->full_name, '/') + 1;
+
+	return fdt_get_name(gd->fdt_blob, ofnode_to_offset(node), NULL);
+}
+
+int ofnode_read_size(ofnode node, const char *propname)
+{
+	int len;
+
+	if (ofnode_is_np(node)) {
+		struct property *prop = of_find_property(
+				ofnode_to_np(node), propname, NULL);
+
+		if (prop)
+			return prop->length;
+	} else {
+		if (fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname,
+				&len))
+			return len;
+	}
+
+	return -EINVAL;
+}
+
+int ofnode_stringlist_search(ofnode node, const char *property,
+			     const char *string)
+{
+	if (ofnode_is_np(node)) {
+		return of_property_match_string(ofnode_to_np(node),
+						property, string);
+	} else {
+		int ret;
+
+		ret = fdt_stringlist_search(gd->fdt_blob,
+					    ofnode_to_offset(node), property,
+					    string);
+		if (ret == -FDT_ERR_NOTFOUND)
+			return -ENODATA;
+		else if (ret < 0)
+			return -EINVAL;
+
+		return ret;
+	}
+}
+
+int ofnode_read_string_index(ofnode node, const char *property, int index,
+			     const char **outp)
+{
+	if (ofnode_is_np(node)) {
+		return of_property_read_string_index(ofnode_to_np(node),
+						     property, index, outp);
+	} else {
+		int len;
+
+		*outp = fdt_stringlist_get(gd->fdt_blob, ofnode_to_offset(node),
+					   property, index, &len);
+		if (len < 0)
+			return -EINVAL;
+		return 0;
+	}
+}
+
+static void ofnode_from_fdtdec_phandle_args(struct fdtdec_phandle_args *in,
+					    struct ofnode_phandle_args *out)
+{
+	assert(OF_MAX_PHANDLE_ARGS == MAX_PHANDLE_ARGS);
+	out->node = offset_to_ofnode(in->node);
+	out->args_count = in->args_count;
+	memcpy(out->args, in->args, sizeof(out->args));
+}
+
+static void ofnode_from_of_phandle_args(struct of_phandle_args *in,
+					struct ofnode_phandle_args *out)
+{
+	assert(OF_MAX_PHANDLE_ARGS == MAX_PHANDLE_ARGS);
+	out->node = np_to_ofnode(in->np);
+	out->args_count = in->args_count;
+	memcpy(out->args, in->args, sizeof(out->args));
+}
+
+int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
+				   const char *cells_name, int cell_count,
+				   int index,
+				   struct ofnode_phandle_args *out_args)
+{
+	if (ofnode_is_np(node)) {
+		struct of_phandle_args args;
+		int ret;
+
+		ret = of_parse_phandle_with_args(ofnode_to_np(node),
+				list_name, cells_name, index, &args);
+		if (ret)
+			return ret;
+		ofnode_from_of_phandle_args(&args, out_args);
+	} else {
+		struct fdtdec_phandle_args args;
+		int ret;
+
+		ret = fdtdec_parse_phandle_with_args(gd->fdt_blob,
+				ofnode_to_offset(node), list_name, cells_name,
+				cell_count, index, &args);
+		if (ret)
+			return ret;
+		ofnode_from_fdtdec_phandle_args(&args, out_args);
+	}
+
+	return 0;
+}
+
+ofnode ofnode_path(const char *path)
+{
+	if (of_live_active())
+		return np_to_ofnode(of_find_node_by_path(path));
+	else
+		return offset_to_ofnode(fdt_path_offset(gd->fdt_blob, path));
+}
+
+const char *ofnode_get_chosen_prop(const char *name)
+{
+	ofnode chosen_node;
+
+	chosen_node = ofnode_path("/chosen");
+
+	return ofnode_read_string(chosen_node, name);
+}
+
+ofnode ofnode_get_chosen_node(const char *name)
+{
+	const char *prop;
+
+	prop = ofnode_get_chosen_prop(name);
+	if (!prop)
+		return ofnode_null();
+
+	return ofnode_path(prop);
+}
+
+static int decode_timing_property(ofnode node, const char *name,
+				  struct timing_entry *result)
+{
+	int length, ret = 0;
+
+	length = ofnode_read_size(node, name);
+	if (length < 0) {
+		debug("%s: could not find property %s\n",
+		      ofnode_get_name(node), name);
+		return length;
+	}
+
+	if (length == sizeof(u32)) {
+		result->typ = ofnode_read_u32_default(node, name, 0);
+		result->min = result->typ;
+		result->max = result->typ;
+	} else {
+		ret = ofnode_read_u32_array(node, name, &result->min, 3);
+	}
+
+	return ret;
+}
+
+int ofnode_decode_display_timing(ofnode parent, int index,
+				 struct display_timing *dt)
+{
+	int i;
+	ofnode timings, node;
+	u32 val = 0;
+	int ret = 0;
+
+	timings = ofnode_find_subnode(parent, "display-timings");
+	if (!ofnode_valid(timings))
+		return -EINVAL;
+
+	for (i = 0, node = ofnode_first_subnode(timings);
+	     ofnode_valid(node) && i != index;
+	     node = ofnode_first_subnode(node))
+		i++;
+
+	if (!ofnode_valid(node))
+		return -EINVAL;
+
+	memset(dt, 0, sizeof(*dt));
+
+	ret |= decode_timing_property(node, "hback-porch", &dt->hback_porch);
+	ret |= decode_timing_property(node, "hfront-porch", &dt->hfront_porch);
+	ret |= decode_timing_property(node, "hactive", &dt->hactive);
+	ret |= decode_timing_property(node, "hsync-len", &dt->hsync_len);
+	ret |= decode_timing_property(node, "vback-porch", &dt->vback_porch);
+	ret |= decode_timing_property(node, "vfront-porch", &dt->vfront_porch);
+	ret |= decode_timing_property(node, "vactive", &dt->vactive);
+	ret |= decode_timing_property(node, "vsync-len", &dt->vsync_len);
+	ret |= decode_timing_property(node, "clock-frequency", &dt->pixelclock);
+
+	dt->flags = 0;
+	val = ofnode_read_u32_default(node, "vsync-active", -1);
+	if (val != -1) {
+		dt->flags |= val ? DISPLAY_FLAGS_VSYNC_HIGH :
+				DISPLAY_FLAGS_VSYNC_LOW;
+	}
+	val = ofnode_read_u32_default(node, "hsync-active", -1);
+	if (val != -1) {
+		dt->flags |= val ? DISPLAY_FLAGS_HSYNC_HIGH :
+				DISPLAY_FLAGS_HSYNC_LOW;
+	}
+	val = ofnode_read_u32_default(node, "de-active", -1);
+	if (val != -1) {
+		dt->flags |= val ? DISPLAY_FLAGS_DE_HIGH :
+				DISPLAY_FLAGS_DE_LOW;
+	}
+	val = ofnode_read_u32_default(node, "pixelclk-active", -1);
+	if (val != -1) {
+		dt->flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE :
+				DISPLAY_FLAGS_PIXDATA_NEGEDGE;
+	}
+
+	if (ofnode_read_bool(node, "interlaced"))
+		dt->flags |= DISPLAY_FLAGS_INTERLACED;
+	if (ofnode_read_bool(node, "doublescan"))
+		dt->flags |= DISPLAY_FLAGS_DOUBLESCAN;
+	if (ofnode_read_bool(node, "doubleclk"))
+		dt->flags |= DISPLAY_FLAGS_DOUBLECLK;
+
+	return ret;
+}
+
+const u32 *ofnode_read_prop(ofnode node, const char *propname, int *lenp)
+{
+	if (ofnode_is_np(node)) {
+		struct property *prop;
+
+		prop = of_find_property(ofnode_to_np(node), propname, lenp);
+		if (!prop)
+			return NULL;
+		return prop->value;
+	} else {
+		return fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
+				   propname, lenp);
+	}
+}
+
+bool ofnode_is_available(ofnode node)
+{
+	if (ofnode_is_np(node))
+		return of_device_is_available(ofnode_to_np(node));
+	else
+		return fdtdec_get_is_enabled(gd->fdt_blob,
+					     ofnode_to_offset(node));
+}
+
+fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property,
+				fdt_size_t *sizep)
+{
+	if (ofnode_is_np(node)) {
+		int na, ns;
+		int psize;
+		const struct device_node *np = ofnode_to_np(node);
+		const __be32 *prop = of_get_property(np, "reg", &psize);
+
+		na = of_n_addr_cells(np);
+		ns = of_n_addr_cells(np);
+		*sizep = of_read_number(prop + na, ns);
+		return of_read_number(prop, na);
+	} else {
+		return fdtdec_get_addr_size(gd->fdt_blob,
+					    ofnode_to_offset(node), property,
+					    sizep);
+	}
+}
+
+const uint8_t *ofnode_read_u8_array_ptr(ofnode node, const char *propname,
+					size_t sz)
+{
+	if (ofnode_is_np(node)) {
+		const struct device_node *np = ofnode_to_np(node);
+		int psize;
+		const __be32 *prop = of_get_property(np, propname, &psize);
+
+		if (!prop || sz != psize)
+			return NULL;
+		return (uint8_t *)prop;
+
+	} else {
+		return fdtdec_locate_byte_array(gd->fdt_blob,
+				ofnode_to_offset(node), propname, sz);
+	}
+}
+
+int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
+			 const char *propname, struct fdt_pci_addr *addr)
+{
+	const u32 *cell;
+	int len;
+	int ret = -ENOENT;
+
+	debug("%s: %s: ", __func__, propname);
+
+	/*
+	 * If we follow the pci bus bindings strictly, we should check
+	 * the value of the node's parent node's #address-cells and
+	 * #size-cells. They need to be 3 and 2 accordingly. However,
+	 * for simplicity we skip the check here.
+	 */
+	cell = ofnode_read_prop(node, propname, &len);
+	if (!cell)
+		goto fail;
+
+	if ((len % FDT_PCI_REG_SIZE) == 0) {
+		int num = len / FDT_PCI_REG_SIZE;
+		int i;
+
+		for (i = 0; i < num; i++) {
+			debug("pci address #%d: %08lx %08lx %08lx\n", i,
+			      (ulong)fdt32_to_cpu(cell[0]),
+			      (ulong)fdt32_to_cpu(cell[1]),
+			      (ulong)fdt32_to_cpu(cell[2]));
+			if ((fdt32_to_cpu(*cell) & type) == type) {
+				addr->phys_hi = fdt32_to_cpu(cell[0]);
+				addr->phys_mid = fdt32_to_cpu(cell[1]);
+				addr->phys_lo = fdt32_to_cpu(cell[1]);
+				break;
+			} else {
+				cell += (FDT_PCI_ADDR_CELLS +
+					 FDT_PCI_SIZE_CELLS);
+			}
+		}
+
+		if (i == num) {
+			ret = -ENXIO;
+			goto fail;
+		}
+
+		return 0;
+	} else {
+		ret = -EINVAL;
+	}
+
+fail:
+	debug("(not found)\n");
+	return ret;
+}
+
+int ofnode_read_addr_cells(ofnode node)
+{
+	if (ofnode_is_np(node))
+		return of_n_addr_cells(ofnode_to_np(node));
+	else
+		return fdt_address_cells(gd->fdt_blob, ofnode_to_offset(node));
+}
+
+int ofnode_read_size_cells(ofnode node)
+{
+	if (ofnode_is_np(node))
+		return of_n_size_cells(ofnode_to_np(node));
+	else
+		return fdt_size_cells(gd->fdt_blob, ofnode_to_offset(node));
+}
+
+bool ofnode_pre_reloc(ofnode node)
+{
+	if (ofnode_read_prop(node, "u-boot,dm-pre-reloc", NULL))
+		return true;
+
+#ifdef CONFIG_TPL_BUILD
+	if (ofnode_read_prop(node, "u-boot,dm-tpl", NULL))
+		return true;
+#elif defined(CONFIG_SPL_BUILD)
+	if (ofnode_read_prop(node, "u-boot,dm-spl", NULL))
+		return true;
+#else
+	/*
+	 * In regular builds individual spl and tpl handling both
+	 * count as handled pre-relocation for later second init.
+	 */
+	if (ofnode_read_prop(node, "u-boot,dm-spl", NULL) ||
+	    ofnode_read_prop(node, "u-boot,dm-tpl", NULL))
+		return true;
+#endif
+
+	return false;
+}
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index f952c989d2..b4090128d4 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -10,6 +10,12 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#include <fdtdec.h>
+#include <dm/of.h>
+
+/* Enable checks to protect against invalid calls */
+#undef OF_CHECKS
+
 struct fdtdec_phandle_args;
 
 /**
@@ -24,7 +30,7 @@ struct fdtdec_phandle_args;
  * ofnode and either an offset or a struct device_node *.
  *
  * The reference can also hold a null offset, in which case the pointer value
- * here is (void *)-1. This corresponds to a struct device_node * value of
+ * here is NULL. This corresponds to a struct device_node * value of
  * NULL, or an offset of -1.
  *
  * There is no ambiguity as to whether ofnode holds an offset or a node
@@ -48,6 +54,29 @@ typedef union ofnode_union {
 	long of_offset;
 } ofnode;
 
+struct ofnode_phandle_args {
+	ofnode node;
+	int args_count;
+	uint32_t args[OF_MAX_PHANDLE_ARGS];
+};
+
+/**
+ * _ofnode_to_np() - convert an ofnode to a live DT node pointer
+ *
+ * This cannot be called if the reference contains an offset.
+ *
+ * @node: Reference containing struct device_node * (possibly invalid)
+ * @return pointer to device node (can be NULL)
+ */
+static inline const struct device_node *ofnode_to_np(ofnode node)
+{
+#ifdef OF_CHECKS
+	if (!of_live_active())
+		return NULL;
+#endif
+	return node.np;
+}
+
 /**
  * ofnode_to_offset() - convert an ofnode to a flat DT offset
  *
@@ -58,6 +87,10 @@ typedef union ofnode_union {
  */
 static inline int ofnode_to_offset(ofnode node)
 {
+#ifdef OF_CHECKS
+	if (of_live_active())
+		return -1;
+#endif
 	return node.of_offset;
 }
 
@@ -68,7 +101,10 @@ static inline int ofnode_to_offset(ofnode node)
  */
 static inline bool ofnode_valid(ofnode node)
 {
-	return node.of_offset != -1;
+	if (of_live_active())
+		return node.np != NULL;
+	else
+		return node.of_offset != -1;
 }
 
 /**
@@ -81,11 +117,54 @@ static inline ofnode offset_to_ofnode(int of_offset)
 {
 	ofnode node;
 
-	node.of_offset = of_offset;
+	if (of_live_active())
+		node.np = NULL;
+	else
+		node.of_offset = of_offset;
+
+	return node;
+}
+
+/**
+ * np_to_ofnode() - convert a node pointer to an ofnode
+ *
+ * @np: Live node pointer (can be NULL)
+ * @return reference to the associated node pointer
+ */
+static inline ofnode np_to_ofnode(const struct device_node *np)
+{
+	ofnode node;
+
+	node.np = np;
 
 	return node;
 }
 
+/**
+ * ofnode_is_np() - check if a reference is a node pointer
+ *
+ * This function associated that if there is a valid live tree then all
+ * references will use it. This is because using the flat DT when the live tree
+ * is valid is not permitted.
+ *
+ * @node: reference to check (possibly invalid)
+ * @return true if the reference is a live node pointer, false if it is a DT
+ * offset
+ */
+static inline bool ofnode_is_np(ofnode node)
+{
+#ifdef OF_CHECKS
+	/*
+	 * Check our assumption that flat tree offsets are not used when a
+	 * live tree is in use.
+	 */
+	assert(!ofnode_valid(node) ||
+	       (of_live_active() ? _ofnode_to_np(node)
+				  : _ofnode_to_np(node)));
+#endif
+	return of_live_active() && ofnode_valid(node);
+}
+
 /**
  * ofnode_equal() - check if two references are equal
  *
@@ -97,4 +176,385 @@ static inline bool ofnode_equal(ofnode ref1, ofnode ref2)
 	return ref1.of_offset == ref2.of_offset;
 }
 
+/**
+ * ofnode_null() - Obtain a null ofnode
+ *
+ * This returns an ofnode which points to no node. It works both with the flat
+ * tree and livetree.
+ */
+static inline ofnode ofnode_null(void)
+{
+	ofnode node;
+
+	if (of_live_active())
+		node.np = NULL;
+	else
+		node.of_offset = -1;
+
+	return node;
+}
+
+/**
+ * ofnode_read_u32() - Read a 32-bit integer from a property
+ *
+ * @ref:	valid node reference to read property from
+ * @propname:	name of the property to read from
+ * @outp:	place to put value (if found)
+ * @return 0 if OK, -ve on error
+ */
+int ofnode_read_u32(ofnode node, const char *propname, u32 *outp);
+
+/**
+ * ofnode_read_s32() - Read a 32-bit integer from a property
+ *
+ * @ref:	valid node reference to read property from
+ * @propname:	name of the property to read from
+ * @outp:	place to put value (if found)
+ * @return 0 if OK, -ve on error
+ */
+static inline int ofnode_read_s32(ofnode node, const char *propname,
+				  s32 *out_value)
+{
+	return ofnode_read_u32(node, propname, (u32 *)out_value);
+}
+
+/**
+ * ofnode_read_u32_default() - Read a 32-bit integer from a property
+ *
+ * @ref:	valid node reference to read property from
+ * @propname:	name of the property to read from
+ * @def:	default value to return if the property has no value
+ * @return property value, or @def if not found
+ */
+int ofnode_read_u32_default(ofnode ref, const char *propname, u32 def);
+
+/**
+ * ofnode_read_s32_default() - Read a 32-bit integer from a property
+ *
+ * @ref:	valid node reference to read property from
+ * @propname:	name of the property to read from
+ * @def:	default value to return if the property has no value
+ * @return property value, or @def if not found
+ */
+int ofnode_read_s32_default(ofnode node, const char *propname, s32 def);
+
+/**
+ * ofnode_read_string() - Read a string from a property
+ *
+ * @ref:	valid node reference to read property from
+ * @propname:	name of the property to read
+ * @return string from property value, or NULL if there is no such property
+ */
+const char *ofnode_read_string(ofnode node, const char *propname);
+
+/**
+ * ofnode_read_u32_array - Find and read an array of 32 bit integers
+ *
+ * @node:	valid node reference to read property from
+ * @propname:	name of the property to read
+ * @out_values:	pointer to return value, modified only if return value is 0
+ * @sz:		number of array elements to read
+ *
+ * Search for a property in a device node and read 32-bit value(s) from
+ * it. Returns 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ *
+ * The out_values is modified only if a valid u32 value can be decoded.
+ */
+int ofnode_read_u32_array(ofnode node, const char *propname,
+			  u32 *out_values, size_t sz);
+
+/**
+ * ofnode_read_bool() - read a boolean value from a property
+ *
+ * @node:	valid node reference to read property from
+ * @propname:	name of property to read
+ * @return true if property is present (meaning true), false if not present
+ */
+bool ofnode_read_bool(ofnode node, const char *propname);
+
+/**
+ * ofnode_find_subnode() - find a named subnode of a parent node
+ *
+ * @node:	valid reference to parent node
+ * @subnode_name: name of subnode to find
+ * @return reference to subnode (which can be invalid if there is no such
+ * subnode)
+ */
+ofnode ofnode_find_subnode(ofnode node, const char *subnode_name);
+
+/**
+ * ofnode_first_subnode() - find the first subnode of a parent node
+ *
+ * @node:	valid reference to a valid parent node
+ * @return reference to the first subnode (which can be invalid if the parent
+ * node has no subnodes)
+ */
+ofnode ofnode_first_subnode(ofnode node);
+
+/**
+ * ofnode_next_subnode() - find the next sibling of a subnode
+ *
+ * @node:	valid reference to previous node (sibling)
+ * @return reference to the next subnode (which can be invalid if the node
+ * has no more siblings)
+ */
+ofnode ofnode_next_subnode(ofnode node);
+
+/**
+ * ofnode_get_name() - get the name of a node
+ *
+ * @node: valid node to look up
+ * @return name or node
+ */
+const char *ofnode_get_name(ofnode node);
+
+/**
+ * ofnode_read_size() - read the size of a property
+ *
+ * @node: node to check
+ * @propname: property to check
+ * @return size of property if present, or -EINVAL if not
+ */
+int ofnode_read_size(ofnode node, const char *propname);
+
+/**
+ * ofnode_stringlist_search() - find a string in a string list and return index
+ *
+ * Note that it is possible for this function to succeed on property values
+ * that are not NUL-terminated. That's because the function will stop after
+ * finding the first occurrence of @string. This can for example happen with
+ * small-valued cell properties, such as #address-cells, when searching for
+ * the empty string.
+ *
+ * @node: node to check
+ * @propname: name of the property containing the string list
+ * @string: string to look up in the string list
+ *
+ * @return:
+ *   the index of the string in the list of strings
+ *   -ENODATA if the property is not found
+ *   -EINVAL on some other error
+ */
+int ofnode_stringlist_search(ofnode node, const char *propname,
+			     const char *string);
+
+/**
+ * fdt_stringlist_get() - obtain the string at a given index in a string list
+ *
+ * Note that this will successfully extract strings from properties with
+ * non-NUL-terminated values. For example on small-valued cell properties
+ * this function will return the empty string.
+ *
+ * If non-NULL, the length of the string (on success) or a negative error-code
+ * (on failure) will be stored in the integer pointer to by lenp.
+ *
+ * @node: node to check
+ * @propname: name of the property containing the string list
+ * @index: index of the string to return
+ * @lenp: return location for the string length or an error code on failure
+ *
+ * @return:
+ *   length of string, if found or -ve error value if not found
+ */
+int ofnode_read_string_index(ofnode node, const char *propname, int index,
+			     const char **outp);
+
+/**
+ * ofnode_parse_phandle_with_args() - Find a node pointed by phandle in a list
+ *
+ * This function is useful to parse lists of phandles and their arguments.
+ * Returns 0 on success and fills out_args, on error returns appropriate
+ * errno value.
+ *
+ * Caller is responsible to call of_node_put() on the returned out_args->np
+ * pointer.
+ *
+ * Example:
+ *
+ * phandle1: node1 {
+ *	#list-cells = <2>;
+ * }
+ *
+ * phandle2: node2 {
+ *	#list-cells = <1>;
+ * }
+ *
+ * node3 {
+ *	list = <&phandle1 1 2 &phandle2 3>;
+ * }
+ *
+ * To get a device_node of the `node2' node you may call this:
+ * ofnode_parse_phandle_with_args(node3, "list", "#list-cells", 0, 1, &args);
+ *
+ * @node:	device tree node containing a list
+ * @list_name:	property name that contains a list
+ * @cells_name:	property name that specifies phandles' arguments count
+ * @cells_count: Cell count to use if @cells_name is NULL
+ * @index:	index of a phandle to parse out
+ * @out_args:	optional pointer to output arguments structure (will be filled)
+ * @return 0 on success (with @out_args filled out if not NULL), -ENOENT if
+ *	@list_name does not exist, -EINVAL if a phandle was not found,
+ *	@cells_name could not be found, the arguments were truncated or there
+ *	were too many arguments.
+ */
+int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
+				   const char *cells_name, int cell_count,
+				   int index,
+				   struct ofnode_phandle_args *out_args);
+
+/**
+ * ofnode_path() - find a node by full path
+ *
+ * @path: Full path to node, e.g. "/bus/spi at 1"
+ * @return reference to the node found. Use ofnode_valid() to check if it exists
+ */
+ofnode ofnode_path(const char *path);
+
+/**
+ * ofnode_get_chosen_prop() - get the value of a chosen property
+ *
+ * This looks for a property within the /chosen node and returns its value
+ *
+ * @propname: Property name to look for
+ */
+const char *ofnode_get_chosen_prop(const char *propname);
+
+/**
+ * ofnode_get_chosen_node() - get the chosen node
+ *
+ * @return the chosen node if present, else ofnode_null()
+ */
+ofnode ofnode_get_chosen_node(const char *name);
+
+struct display_timing;
+/**
+ * ofnode_decode_display_timing() - decode display timings
+ *
+ * Decode display timings from the supplied 'display-timings' node.
+ * See doc/device-tree-bindings/video/display-timing.txt for binding
+ * information.
+ *
+ * @node	'display-timing' node containing the timing subnodes
+ * @index	Index number to read (0=first timing subnode)
+ * @config	Place to put timings
+ * @return 0 if OK, -FDT_ERR_NOTFOUND if not found
+ */
+int ofnode_decode_display_timing(ofnode node, int index,
+				 struct display_timing *config);
+
+/**
+ * ofnode_read_prop()- - read a node property
+ *
+ * @node: node to read
+ * @propname: property to read
+ * @lenp: place to put length on success
+ * @return pointer to property, or NULL if not found
+ */
+const u32 *ofnode_read_prop(ofnode node, const char *propname, int *lenp);
+
+/**
+ * ofnode_is_available() - check if a node is marked available
+ *
+ * @node: node to check
+ * @return true if node's 'status' property is "okay" (or is missing)
+ */
+bool ofnode_is_available(ofnode node);
+
+/**
+ * ofnode_get_addr_size() - get address and size from a property
+ *
+ * This does no address translation. It simply reads an property that contains
+ * an address and a size value, one after the other.
+ *
+ * @node: node to read from
+ * @propname: property to read
+ * @sizep: place to put size value (on success)
+ * @return address value, or FDT_ADDR_T_NONE on error
+ */
+phys_addr_t ofnode_get_addr_size(ofnode node, const char *propname,
+				 phys_size_t *sizep);
+
+/**
+ * ofnode_read_u8_array_ptr() - find an 8-bit array
+ *
+ * Look up a property in a node and return a pointer to its contents as a
+ * byte array of given length. The property must have at least enough data
+ * for the array (count bytes). It may have more, but this will be ignored.
+ * The data is not copied.
+ *
+ * @node	node to examine
+ * @propname	name of property to find
+ * @sz		number of array elements
+ * @return pointer to byte array if found, or NULL if the property is not
+ *		found or there is not enough data
+ */
+const uint8_t *ofnode_read_u8_array_ptr(ofnode node, const char *propname,
+					size_t sz);
+
+/**
+ * ofnode_read_pci_addr() - look up a PCI address
+ *
+ * Look at an address property in a node and return the PCI address which
+ * corresponds to the given type in the form of fdt_pci_addr.
+ * The property must hold one fdt_pci_addr with a lengh.
+ *
+ * @node	node to examine
+ * @type	pci address type (FDT_PCI_SPACE_xxx)
+ * @propname	name of property to find
+ * @addr	returns pci address in the form of fdt_pci_addr
+ * @return 0 if ok, -ENOENT if the property did not exist, -EINVAL if the
+ *		format of the property was invalid, -ENXIO if the requested
+ *		address type was not found
+ */
+int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
+			 const char *propname, struct fdt_pci_addr *addr);
+
+/**
+ * ofnode_read_addr_cells() - Get the number of address cells for a node
+ *
+ * This walks back up the tree to find the closest #address-cells property
+ * which controls the given node.
+ *
+ * @node: Node to check
+ * @return number of address cells this node uses
+ */
+int ofnode_read_addr_cells(ofnode node);
+
+/**
+ * ofnode_read_size_cells() - Get the number of size cells for a node
+ *
+ * This walks back up the tree to find the closest #size-cells property
+ * which controls the given node.
+ *
+ * @node: Node to check
+ * @return number of size cells this node uses
+ */
+int ofnode_read_size_cells(ofnode node);
+
+/**
+ * ofnode_pre_reloc() - check if a node should be bound before relocation
+ *
+ * Device tree nodes can be marked as needing-to-be-bound in the loader stages
+ * via special device tree properties.
+ *
+ * Before relocation this function can be used to check if nodes are required
+ * in either SPL or TPL stages.
+ *
+ * After relocation and jumping into the real U-Boot binary it is possible to
+ * determine if a node was bound in one of SPL/TPL stages.
+ *
+ * There are 3 settings currently in use
+ * -
+ * - u-boot,dm-pre-reloc: legacy and indicates any of TPL or SPL
+ *   Existing platforms only use it to indicate nodes needed in
+ *   SPL. Should probably be replaced by u-boot,dm-spl for
+ *   new platforms.
+ *
+ * @node: node to check
+ * @eturns true if node is needed in SPL/TL, false otherwise
+ */
+bool ofnode_pre_reloc(ofnode node);
+
 #endif
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 09/71] dm: core: Add livetree address functions
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (7 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 08/71] dm: core: Add operations on device tree references Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 10/71] fdt: Update fdt_get_base_address() to use const Simon Glass
                   ` (61 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

Add functions to access addresses in the device tree. These are brought
in from Linux 4.10.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/Makefile  |   2 +-
 drivers/core/of_addr.c | 359 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/dm/of_addr.h   |  64 +++++++++
 3 files changed, 424 insertions(+), 1 deletion(-)
 create mode 100644 drivers/core/of_addr.c
 create mode 100644 include/dm/of_addr.h

diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index c25288e464..1c6795af13 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -11,5 +11,5 @@ obj-$(CONFIG_$(SPL_)SIMPLE_BUS)	+= simple-bus.o
 obj-$(CONFIG_DM)	+= dump.o
 obj-$(CONFIG_$(SPL_)REGMAP)	+= regmap.o
 obj-$(CONFIG_$(SPL_)SYSCON)	+= syscon-uclass.o
-obj-$(CONFIG_OF_LIVE) += of_access.o
+obj-$(CONFIG_OF_LIVE) += of_access.o of_addr.o
 obj-$(CONFIG_OF_CONTROL) += ofnode.o
diff --git a/drivers/core/of_addr.c b/drivers/core/of_addr.c
new file mode 100644
index 0000000000..4757066967
--- /dev/null
+++ b/drivers/core/of_addr.c
@@ -0,0 +1,359 @@
+/*
+ * Taken from Linux v4.9 drivers/of/address.c
+ *
+ * Modified for U-Boot
+ * Copyright (c) 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <dm/of_access.h>
+#include <dm/of_addr.h>
+#include <linux/err.h>
+#include <linux/ioport.h>
+
+/* Max address size we deal with */
+#define OF_MAX_ADDR_CELLS	4
+#define OF_CHECK_ADDR_COUNT(na)	((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
+#define OF_CHECK_COUNTS(na, ns)	(OF_CHECK_ADDR_COUNT(na) && (ns) > 0)
+
+static struct of_bus *of_match_bus(struct device_node *np);
+
+/* Debug utility */
+#ifdef DEBUG
+static void of_dump_addr(const char *s, const __be32 *addr, int na)
+{
+	debug("%s", s);
+	while (na--)
+		pr_cont(" %08x", be32_to_cpu(*(addr++)));
+	pr_cont("\n");
+}
+#else
+static void of_dump_addr(const char *s, const __be32 *addr, int na) { }
+#endif
+
+/* Callbacks for bus specific translators */
+struct of_bus {
+	const char *name;
+	const char *addresses;
+	int (*match)(struct device_node *parent);
+	void (*count_cells)(const struct device_node *child, int *addrc,
+			    int *sizec);
+	u64 (*map)(__be32 *addr, const __be32 *range, int na, int ns, int pna);
+	int (*translate)(__be32 *addr, u64 offset, int na);
+	unsigned int (*get_flags)(const __be32 *addr);
+};
+
+static void of_bus_default_count_cells(const struct device_node *np,
+				       int *addrc, int *sizec)
+{
+	if (addrc)
+		*addrc = of_n_addr_cells(np);
+	if (sizec)
+		*sizec = of_n_size_cells(np);
+}
+
+static u64 of_bus_default_map(__be32 *addr, const __be32 *range,
+		int na, int ns, int pna)
+{
+	u64 cp, s, da;
+
+	cp = of_read_number(range, na);
+	s  = of_read_number(range + na + pna, ns);
+	da = of_read_number(addr, na);
+
+	debug("default map, cp=%llx, s=%llx, da=%llx\n",
+	      (unsigned long long)cp, (unsigned long long)s,
+	      (unsigned long long)da);
+
+	if (da < cp || da >= (cp + s))
+		return OF_BAD_ADDR;
+	return da - cp;
+}
+
+static int of_bus_default_translate(__be32 *addr, u64 offset, int na)
+{
+	u64 a = of_read_number(addr, na);
+	memset(addr, 0, na * 4);
+	a += offset;
+	if (na > 1)
+		addr[na - 2] = cpu_to_be32(a >> 32);
+	addr[na - 1] = cpu_to_be32(a & 0xffffffffu);
+
+	return 0;
+}
+
+static unsigned int of_bus_default_get_flags(const __be32 *addr)
+{
+	return IORESOURCE_MEM;
+}
+
+/*
+ * Array of bus-specific translators
+ */
+static struct of_bus of_busses[] = {
+	/* Default */
+	{
+		.name = "default",
+		.addresses = "reg",
+		.match = NULL,
+		.count_cells = of_bus_default_count_cells,
+		.map = of_bus_default_map,
+		.translate = of_bus_default_translate,
+		.get_flags = of_bus_default_get_flags,
+	},
+};
+
+static struct of_bus *of_match_bus(struct device_node *np)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(of_busses); i++)
+		if (!of_busses[i].match || of_busses[i].match(np))
+			return &of_busses[i];
+	BUG();
+	return NULL;
+}
+
+static void dev_count_cells(const struct device_node *np, int *nap, int *nsp)
+{
+	of_bus_default_count_cells(np, nap, nsp);
+}
+
+const __be32 *of_get_address(const struct device_node *dev, int index,
+			     u64 *size, unsigned int *flags)
+{
+	const __be32 *prop;
+	int psize;
+	struct device_node *parent;
+	struct of_bus *bus;
+	int onesize, i, na, ns;
+
+	/* Get parent & match bus type */
+	parent = of_get_parent(dev);
+	if (parent == NULL)
+		return NULL;
+	dev_count_cells(dev, &na, &ns);
+	bus = of_match_bus(parent);
+	bus->count_cells(dev, &na, &ns);
+	of_node_put(parent);
+	if (!OF_CHECK_ADDR_COUNT(na))
+		return NULL;
+
+	/* Get "reg" or "assigned-addresses" property */
+	prop = of_get_property(dev, "reg", &psize);
+	if (prop == NULL)
+		return NULL;
+	psize /= 4;
+
+	onesize = na + ns;
+	for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+		if (i == index) {
+			if (size)
+				*size = of_read_number(prop + na, ns);
+			if (flags)
+				*flags = bus->get_flags(prop);
+			return prop;
+		}
+	return NULL;
+}
+EXPORT_SYMBOL(of_get_address);
+
+static int of_empty_ranges_quirk(const struct device_node *np)
+{
+	return false;
+}
+
+static int of_translate_one(const struct device_node *parent,
+			    struct of_bus *bus, struct of_bus *pbus,
+			    __be32 *addr, int na, int ns, int pna,
+			    const char *rprop)
+{
+	const __be32 *ranges;
+	int rlen;
+	int rone;
+	u64 offset = OF_BAD_ADDR;
+
+	/*
+	 * Normally, an absence of a "ranges" property means we are
+	 * crossing a non-translatable boundary, and thus the addresses
+	 * below the current cannot be converted to CPU physical ones.
+	 * Unfortunately, while this is very clear in the spec, it's not
+	 * what Apple understood, and they do have things like /uni-n or
+	 * /ht nodes with no "ranges" property and a lot of perfectly
+	 * useable mapped devices below them. Thus we treat the absence of
+	 * "ranges" as equivalent to an empty "ranges" property which means
+	 * a 1:1 translation at that level. It's up to the caller not to try
+	 * to translate addresses that aren't supposed to be translated in
+	 * the first place. --BenH.
+	 *
+	 * As far as we know, this damage only exists on Apple machines, so
+	 * This code is only enabled on powerpc. --gcl
+	 */
+	ranges = of_get_property(parent, rprop, &rlen);
+	if (ranges == NULL && !of_empty_ranges_quirk(parent)) {
+		debug("no ranges; cannot translate\n");
+		return 1;
+	}
+	if (ranges == NULL || rlen == 0) {
+		offset = of_read_number(addr, na);
+		memset(addr, 0, pna * 4);
+		debug("empty ranges; 1:1 translation\n");
+		goto finish;
+	}
+
+	debug("walking ranges...\n");
+
+	/* Now walk through the ranges */
+	rlen /= 4;
+	rone = na + pna + ns;
+	for (; rlen >= rone; rlen -= rone, ranges += rone) {
+		offset = bus->map(addr, ranges, na, ns, pna);
+		if (offset != OF_BAD_ADDR)
+			break;
+	}
+	if (offset == OF_BAD_ADDR) {
+		debug("not found !\n");
+		return 1;
+	}
+	memcpy(addr, ranges + na, 4 * pna);
+
+ finish:
+	of_dump_addr("parent translation for:", addr, pna);
+	debug("with offset: %llx\n", (unsigned long long)offset);
+
+	/* Translate it into parent bus space */
+	return pbus->translate(addr, offset, pna);
+}
+
+/*
+ * Translate an address from the device-tree into a CPU physical address,
+ * this walks up the tree and applies the various bus mappings on the
+ * way.
+ *
+ * Note: We consider that crossing any level with #size-cells == 0 to mean
+ * that translation is impossible (that is we are not dealing with a value
+ * that can be mapped to a cpu physical address). This is not really specified
+ * that way, but this is traditionally the way IBM at least do things
+ */
+static u64 __of_translate_address(const struct device_node *dev,
+				  const __be32 *in_addr, const char *rprop)
+{
+	struct device_node *parent = NULL;
+	struct of_bus *bus, *pbus;
+	__be32 addr[OF_MAX_ADDR_CELLS];
+	int na, ns, pna, pns;
+	u64 result = OF_BAD_ADDR;
+
+	debug("** translation for device %s **\n", of_node_full_name(dev));
+
+	/* Increase refcount at current level */
+	(void)of_node_get(dev);
+
+	/* Get parent & match bus type */
+	parent = of_get_parent(dev);
+	if (parent == NULL)
+		goto bail;
+	bus = of_match_bus(parent);
+
+	/* Count address cells & copy address locally */
+	bus->count_cells(dev, &na, &ns);
+	if (!OF_CHECK_COUNTS(na, ns)) {
+		debug("Bad cell count for %s\n", of_node_full_name(dev));
+		goto bail;
+	}
+	memcpy(addr, in_addr, na * 4);
+
+	debug("bus is %s (na=%d, ns=%d) on %s\n", bus->name, na, ns,
+	      of_node_full_name(parent));
+	of_dump_addr("translating address:", addr, na);
+
+	/* Translate */
+	for (;;) {
+		/* Switch to parent bus */
+		of_node_put(dev);
+		dev = parent;
+		parent = of_get_parent(dev);
+
+		/* If root, we have finished */
+		if (parent == NULL) {
+			debug("reached root node\n");
+			result = of_read_number(addr, na);
+			break;
+		}
+
+		/* Get new parent bus and counts */
+		pbus = of_match_bus(parent);
+		pbus->count_cells(dev, &pna, &pns);
+		if (!OF_CHECK_COUNTS(pna, pns)) {
+			debug("Bad cell count for %s\n",
+			      of_node_full_name(dev));
+			break;
+		}
+
+		debug("parent bus is %s (na=%d, ns=%d) on %s\n", pbus->name,
+		      pna, pns, of_node_full_name(parent));
+
+		/* Apply bus translation */
+		if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
+			break;
+
+		/* Complete the move up one level */
+		na = pna;
+		ns = pns;
+		bus = pbus;
+
+		of_dump_addr("one level translation:", addr, na);
+	}
+ bail:
+	of_node_put(parent);
+	of_node_put(dev);
+
+	return result;
+}
+
+u64 of_translate_address(const struct device_node *dev, const __be32 *in_addr)
+{
+	return __of_translate_address(dev, in_addr, "ranges");
+}
+
+
+static int __of_address_to_resource(const struct device_node *dev,
+		const __be32 *addrp, u64 size, unsigned int flags,
+		const char *name, struct resource *r)
+{
+	u64 taddr;
+
+	if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+		return -EINVAL;
+	taddr = of_translate_address(dev, addrp);
+	if (taddr == OF_BAD_ADDR)
+		return -EINVAL;
+	memset(r, 0, sizeof(struct resource));
+	r->start = taddr;
+	r->end = taddr + size - 1;
+	r->flags = flags;
+	r->name = name ? name : dev->full_name;
+
+	return 0;
+}
+
+int of_address_to_resource(const struct device_node *dev, int index,
+			   struct resource *r)
+{
+	const __be32	*addrp;
+	u64		size;
+	unsigned int	flags;
+	const char	*name = NULL;
+
+	addrp = of_get_address(dev, index, &size, &flags);
+	if (addrp == NULL)
+		return -EINVAL;
+
+	/* Get optional "reg-names" property to add a name to a resource */
+	of_property_read_string_index(dev, "reg-names", index, &name);
+
+	return __of_address_to_resource(dev, addrp, size, flags, name, r);
+}
diff --git a/include/dm/of_addr.h b/include/dm/of_addr.h
new file mode 100644
index 0000000000..25ca05b315
--- /dev/null
+++ b/include/dm/of_addr.h
@@ -0,0 +1,64 @@
+/*
+ * Taken from Linux v4.9 drivers/of/address.c
+ *
+ * Modified for U-Boot
+ * Copyright (c) 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _DM_OF_ADDR_H
+#define _DM_OF_ADDR_H
+
+/**
+ * of_translate_address() - translate a device-tree address to a CPU address
+ *
+ * Translate an address from the device-tree into a CPU physical address,
+ * this walks up the tree and applies the various bus mappings on the  way.
+ *
+ * Note: We consider that crossing any level with #size-cells == 0 to mean
+ * that translation is impossible (that is we are not dealing with a value
+ * that can be mapped to a cpu physical address). This is not really specified
+ * that way, but this is traditionally the way IBM at least do things
+ *
+ * @np: node to check
+ * @in_addr: pointer to input address
+ * @return translated address or OF_BAD_ADDR on error
+ */
+u64 of_translate_address(const struct device_node *no, const __be32 *in_addr);
+
+/**
+ * of_get_address() - obtain an address from a node
+ *
+ * Extract an address from a node, returns the region size and the address
+ * space flags too. The PCI version uses a BAR number instead of an absolute
+ * index.
+ *
+ * @np: Node to check
+ * @index: Index of address to read (0 = first)
+ * @size: place to put size on success
+ * @flags: place to put flags on success
+ * @return pointer to address which can be read
+ */
+const __be32 *of_get_address(const struct device_node *no, int index,
+			     u64 *size, unsigned int *flags);
+
+struct resource;
+
+/**
+ * of_address_to_resource() - translate device tree address to resource
+ *
+ * Note that if your address is a PIO address, the conversion will fail if
+ * the physical address can't be internally converted to an IO token with
+ * pci_address_to_pio(), that is because it's either called to early or it
+ * can't be matched to any host bridge IO space
+ *
+ * @np: node to check
+ * @index: index of address to read (0 = first)
+ * @r: place to put resource information
+ * @return 0 if OK, -ve on error
+ */
+int of_address_to_resource(const struct device_node *no, int index,
+			   struct resource *r);
+
+#endif
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 10/71] fdt: Update fdt_get_base_address() to use const
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (8 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 09/71] dm: core: Add livetree address functions Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 11/71] dm: core: Add address operations on device tree references Simon Glass
                   ` (60 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

This function does not change the device tree so adjust it to use const
for this parameter.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/fdt_support.c  | 2 +-
 include/fdt_support.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/common/fdt_support.c b/common/fdt_support.c
index c6a76b7ad2..c63b27bbb6 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -1539,7 +1539,7 @@ int fdt_verify_alias_address(void *fdt, int anode, const char *alias, u64 addr)
 /*
  * Returns the base address of an SOC or PCI node
  */
-u64 fdt_get_base_address(void *fdt, int node)
+u64 fdt_get_base_address(const void *fdt, int node)
 {
 	int size;
 	u32 naddr;
diff --git a/include/fdt_support.h b/include/fdt_support.h
index 955c121713..6fea5c7da0 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -207,7 +207,7 @@ int fdt_add_edid(void *blob, const char *compat, unsigned char *buf);
 
 int fdt_verify_alias_address(void *fdt, int anode, const char *alias,
 			      u64 addr);
-u64 fdt_get_base_address(void *fdt, int node);
+u64 fdt_get_base_address(const void *fdt, int node);
 int fdt_read_range(void *fdt, int node, int n, uint64_t *child_addr,
 		   uint64_t *addr, uint64_t *len);
 
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 11/71] dm: core: Add address operations on device tree references
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (9 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 10/71] fdt: Update fdt_get_base_address() to use const Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 12/71] dm: core: Add a place to put extra device-tree reading functions Simon Glass
                   ` (59 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

Add functions to add addresses in the device tree using ofnode references.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/ofnode.c | 27 +++++++++++++++++++++++++++
 include/dm/ofnode.h   | 21 +++++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index e6c9a28bae..ac312d6546 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -11,6 +11,7 @@
 #include <fdt_support.h>
 #include <libfdt.h>
 #include <dm/of_access.h>
+#include <dm/of_addr.h>
 #include <dm/ofnode.h>
 #include <linux/err.h>
 
@@ -195,6 +196,32 @@ int ofnode_read_size(ofnode node, const char *propname)
 	return -EINVAL;
 }
 
+fdt_addr_t ofnode_get_addr_index(ofnode node, int index)
+{
+	if (ofnode_is_np(node)) {
+		const __be32 *prop_val;
+		uint flags;
+		u64 size;
+
+		prop_val = of_get_address(
+			(struct device_node *)ofnode_to_np(node), index,
+			&size, &flags);
+		if (!prop_val)
+			return FDT_ADDR_T_NONE;
+		return  be32_to_cpup(prop_val);
+	} else {
+		return fdt_get_base_address(gd->fdt_blob,
+					    ofnode_to_offset(node));
+	}
+
+	return FDT_ADDR_T_NONE;
+}
+
+fdt_addr_t ofnode_get_addr(ofnode node)
+{
+	return ofnode_get_addr_index(node, 0);
+}
+
 int ofnode_stringlist_search(ofnode node, const char *property,
 			     const char *string)
 {
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index b4090128d4..96cfc11db4 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -319,6 +319,27 @@ const char *ofnode_get_name(ofnode node);
  */
 int ofnode_read_size(ofnode node, const char *propname);
 
+/**
+ * ofnode_get_addr_index() - get an address from a node
+ *
+ * This reads the register address from a node
+ *
+ * @node: node to read from
+ * @index: Index of address to read (0 for first)
+ * @return address, or FDT_ADDR_T_NONE if not present or invalid
+ */
+phys_addr_t ofnode_get_addr_index(ofnode node, int index);
+
+/**
+ * ofnode_get_addr() - get an address from a node
+ *
+ * This reads the register address from a node
+ *
+ * @node: node to read from
+ * @return address, or FDT_ADDR_T_NONE if not present or invalid
+ */
+phys_addr_t ofnode_get_addr(ofnode node);
+
 /**
  * ofnode_stringlist_search() - find a string in a string list and return index
  *
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 12/71] dm: core: Add a place to put extra device-tree reading functions
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (10 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 11/71] dm: core: Add address operations on device tree references Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 13/71] dm: core: Add device-based 'read' functions to access DT Simon Glass
                   ` (58 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

Some functions deal with structured data rather than simple data types.
It makes sense to have these in their own file. For now this just has a
function to read a flashmap entry. Move the data types also.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/Makefile   |  2 +-
 drivers/core/of_extra.c | 37 +++++++++++++++++++++++++++++++++++++
 include/cros_ec.h       |  1 +
 include/dm/of_extra.h   | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 include/fdtdec.h        | 23 +----------------------
 lib/fdtdec.c            |  1 +
 6 files changed, 87 insertions(+), 23 deletions(-)
 create mode 100644 drivers/core/of_extra.c
 create mode 100644 include/dm/of_extra.h

diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index 1c6795af13..d74b065a07 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -12,4 +12,4 @@ obj-$(CONFIG_DM)	+= dump.o
 obj-$(CONFIG_$(SPL_)REGMAP)	+= regmap.o
 obj-$(CONFIG_$(SPL_)SYSCON)	+= syscon-uclass.o
 obj-$(CONFIG_OF_LIVE) += of_access.o of_addr.o
-obj-$(CONFIG_OF_CONTROL) += ofnode.o
+obj-$(CONFIG_OF_CONTROL) += of_extra.o ofnode.o
diff --git a/drivers/core/of_extra.c b/drivers/core/of_extra.c
new file mode 100644
index 0000000000..0381909848
--- /dev/null
+++ b/drivers/core/of_extra.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <dm/of_access.h>
+#include <dm/of_extra.h>
+#include <dm/ofnode.h>
+
+int of_read_fmap_entry(ofnode node, const char *name,
+		       struct fmap_entry *entry)
+{
+	const char *prop;
+	u32 reg[2];
+
+	if (ofnode_read_u32_array(node, "reg", reg, 2)) {
+		debug("Node '%s' has bad/missing 'reg' property\n", name);
+		return -FDT_ERR_NOTFOUND;
+	}
+	entry->offset = reg[0];
+	entry->length = reg[1];
+	entry->used = ofnode_read_s32_default(node, "used", entry->length);
+	prop = ofnode_read_string(node, "compress");
+	entry->compress_algo = prop && !strcmp(prop, "lzo") ?
+		FMAP_COMPRESS_LZO : FMAP_COMPRESS_NONE;
+	prop = ofnode_read_string(node, "hash");
+	if (prop)
+		entry->hash_size = strlen(prop);
+	entry->hash_algo = prop ? FMAP_HASH_SHA256 : FMAP_HASH_NONE;
+	entry->hash = (uint8_t *)prop;
+
+	return 0;
+}
diff --git a/include/cros_ec.h b/include/cros_ec.h
index 0271f2b827..2bd9f2251f 100644
--- a/include/cros_ec.h
+++ b/include/cros_ec.h
@@ -14,6 +14,7 @@
 #include <fdtdec.h>
 #include <cros_ec_message.h>
 #include <asm/gpio.h>
+#include <dm/of_extra.h>
 
 /* Our configuration information */
 struct cros_ec_dev {
diff --git a/include/dm/of_extra.h b/include/dm/of_extra.h
new file mode 100644
index 0000000000..01b6ebedff
--- /dev/null
+++ b/include/dm/of_extra.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _DM_OF_EXTRA_H
+#define _DM_OF_EXTRA_H
+
+#include <dm/ofnode.h>
+
+enum fmap_compress_t {
+	FMAP_COMPRESS_NONE,
+	FMAP_COMPRESS_LZO,
+};
+
+enum fmap_hash_t {
+	FMAP_HASH_NONE,
+	FMAP_HASH_SHA1,
+	FMAP_HASH_SHA256,
+};
+
+/* A flash map entry, containing an offset and length */
+struct fmap_entry {
+	uint32_t offset;
+	uint32_t length;
+	uint32_t used;			/* Number of bytes used in region */
+	enum fmap_compress_t compress_algo;	/* Compression type */
+	enum fmap_hash_t hash_algo;		/* Hash algorithm */
+	const uint8_t *hash;			/* Hash value */
+	int hash_size;				/* Hash size */
+};
+
+/**
+ * Read a flash entry from the fdt
+ *
+ * @param node	Reference to node to read
+ * @param name		Name of node being read
+ * @param entry		Place to put offset and size of this node
+ * @return 0 if ok, -ve on error
+ */
+int of_read_fmap_entry(ofnode node, const char *name,
+		       struct fmap_entry *entry);
+
+#endif
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 2134701c54..bcdf9fa420 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -815,28 +815,7 @@ const u8 *fdtdec_locate_byte_array(const void *blob, int node,
 int fdtdec_decode_region(const void *blob, int node, const char *prop_name,
 			 fdt_addr_t *basep, fdt_size_t *sizep);
 
-enum fmap_compress_t {
-	FMAP_COMPRESS_NONE,
-	FMAP_COMPRESS_LZO,
-};
-
-enum fmap_hash_t {
-	FMAP_HASH_NONE,
-	FMAP_HASH_SHA1,
-	FMAP_HASH_SHA256,
-};
-
-/* A flash map entry, containing an offset and length */
-struct fmap_entry {
-	uint32_t offset;
-	uint32_t length;
-	uint32_t used;			/* Number of bytes used in region */
-	enum fmap_compress_t compress_algo;	/* Compression type */
-	enum fmap_hash_t hash_algo;		/* Hash algorithm */
-	const uint8_t *hash;			/* Hash value */
-	int hash_size;				/* Hash size */
-};
-
+struct fmap_entry;
 /**
  * Read a flash entry from the fdt
  *
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 6f2588c0c4..90b8946fa2 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -12,6 +12,7 @@
 #include <fdt_support.h>
 #include <fdtdec.h>
 #include <asm/sections.h>
+#include <dm/of_extra.h>
 #include <linux/ctype.h>
 
 DECLARE_GLOBAL_DATA_PTR;
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 13/71] dm: core: Add device-based 'read' functions to access DT
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (11 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 12/71] dm: core: Add a place to put extra device-tree reading functions Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 14/71] dm: core: Implement live tree 'read' functions Simon Glass
                   ` (57 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

It is common to read a device-tree property from the node associated with
a device. Add convenience functions to do this so that drivers do not need
to deal with accessing the ofnode from the device.

These functions all start with 'dev_read_' to provide consistent naming
for all functions which read information from a device's device tree node.

These are inlined when using the flat DT to save code size. The live tree
implementation is added in a later commit.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/Kconfig |   4 +
 include/dm/ofnode.h  |   2 +-
 include/dm/read.h    | 383 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 388 insertions(+), 1 deletion(-)
 create mode 100644 include/dm/read.h

diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index 405e9ad8ef..fb5c4e834d 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -215,4 +215,8 @@ config OF_ISA_BUS
 	  mistranslation of device addresses, so ensure that this is
 	  enabled if your board does include an ISA bus.
 
+config DM_DEV_READ_INLINE
+	bool
+	default y if !OF_LIVE
+
 endmenu
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 96cfc11db4..cd8292a7a5 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -248,7 +248,7 @@ int ofnode_read_s32_default(ofnode node, const char *propname, s32 def);
 const char *ofnode_read_string(ofnode node, const char *propname);
 
 /**
- * ofnode_read_u32_array - Find and read an array of 32 bit integers
+ * ofnode_read_u32_array() - Find and read an array of 32 bit integers
  *
  * @node:	valid node reference to read property from
  * @propname:	name of the property to read
diff --git a/include/dm/read.h b/include/dm/read.h
new file mode 100644
index 0000000000..4ce2bc2d6e
--- /dev/null
+++ b/include/dm/read.h
@@ -0,0 +1,383 @@
+/*
+ * Function to read values from the device tree node attached to a udevice.
+ *
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _DM_READ_H
+#define _DM_READ_H
+
+#include <dm/fdtaddr.h>
+#include <dm/ofnode.h>
+#include <dm/uclass.h>
+
+#if CONFIG_IS_ENABLED(OF_LIVE)
+static inline const struct device_node *dev_np(struct udevice *dev)
+{
+	return ofnode_to_np(dev->node);
+}
+#else
+static inline const struct device_node *dev_np(struct udevice *dev)
+{
+	return NULL;
+}
+#endif
+
+/**
+ * dev_ofnode() - get the DT node reference associated with a udevice
+ *
+ * @dev:	device to check
+ * @return reference of the the device's DT node
+ */
+static inline ofnode dev_ofnode(struct udevice *dev)
+{
+	return dev->node;
+}
+
+static inline bool dev_of_valid(struct udevice *dev)
+{
+	return ofnode_valid(dev_ofnode(dev));
+}
+
+#ifdef CONFIG_DM_DEV_READ_INLINE
+
+static inline int dev_read_u32_default(struct udevice *dev,
+				       const char *propname, int def)
+{
+	return ofnode_read_u32_default(dev_ofnode(dev), propname, def);
+}
+
+/**
+ * dev_read_string() - Read a string from a device's DT property
+ *
+ * @dev:	device to read DT property from
+ * @propname:	name of the property to read
+ * @return string from property value, or NULL if there is no such property
+ */
+static inline const char *dev_read_string(struct udevice *dev,
+					  const char *propname)
+{
+	return ofnode_read_string(dev_ofnode(dev), propname);
+}
+
+/**
+ * dev_read_bool() - read a boolean value from a device's DT property
+ *
+ * @dev:	device to read DT property from
+ * @propname:	name of property to read
+ * @return true if property is present (meaning true), false if not present
+ */
+static inline bool dev_read_bool(struct udevice *dev, const char *propname)
+{
+	return ofnode_read_bool(dev_ofnode(dev), propname);
+}
+
+/**
+ * dev_read_subnode() - find a named subnode of a device
+ *
+ * @dev:	device whose DT node contains the subnode
+ * @subnode_name: name of subnode to find
+ * @return reference to subnode (which can be invalid if there is no such
+ * subnode)
+ */
+static inline ofnode dev_read_subnode(struct udevice *dev,
+				      const char *subbnode_name)
+{
+	return ofnode_find_subnode(dev_ofnode(dev), subbnode_name);
+}
+
+/**
+ * dev_read_size() - read the size of a property
+ *
+ * @dev: device to check
+ * @propname: property to check
+ * @return size of property if present, or -EINVAL if not
+ */
+static inline int dev_read_size(struct udevice *dev, const char *propname)
+{
+	return ofnode_read_size(dev_ofnode(dev), propname);
+}
+
+/**
+ * dev_read_addr_index() - Get the indexed reg property of a device
+ *
+ * @dev: Device to read from
+ * @index: the 'reg' property can hold a list of <addr, size> pairs
+ *	   and @index is used to select which one is required
+ *
+ * @return address or FDT_ADDR_T_NONE if not found
+ */
+static inline fdt_addr_t dev_read_addr_index(struct udevice *dev, int index)
+{
+	return devfdt_get_addr_index(dev, index);
+}
+
+/**
+ * dev_read_addr() - Get the reg property of a device
+ *
+ * @dev: Device to read from
+ *
+ * @return address or FDT_ADDR_T_NONE if not found
+ */
+static inline fdt_addr_t dev_read_addr(struct udevice *dev)
+{
+	return devfdt_get_addr(dev);
+}
+
+/**
+ * dev_read_addr_size() - get address and size from a device property
+ *
+ * This does no address translation. It simply reads an property that contains
+ * an address and a size value, one after the other.
+ *
+ * @dev: Device to read from
+ * @propname: property to read
+ * @sizep: place to put size value (on success)
+ * @return address value, or FDT_ADDR_T_NONE on error
+ */
+static inline fdt_addr_t dev_read_addr_size(struct udevice *dev,
+					    const char *propname,
+					    fdt_size_t *sizep)
+{
+	return ofnode_get_addr_size(dev_ofnode(dev), propname, sizep);
+}
+
+/**
+ * dev_read_name() - get the name of a device's node
+ *
+ * @node: valid node to look up
+ * @return name of node
+ */
+static inline const char *dev_read_name(struct udevice *dev)
+{
+	return ofnode_get_name(dev_ofnode(dev));
+}
+
+/**
+ * dev_read_stringlist_search() - find string in a string list and return index
+ *
+ * Note that it is possible for this function to succeed on property values
+ * that are not NUL-terminated. That's because the function will stop after
+ * finding the first occurrence of @string. This can for example happen with
+ * small-valued cell properties, such as #address-cells, when searching for
+ * the empty string.
+ *
+ * @dev: device to check
+ * @propname: name of the property containing the string list
+ * @string: string to look up in the string list
+ *
+ * @return:
+ *   the index of the string in the list of strings
+ *   -ENODATA if the property is not found
+ *   -EINVAL on some other error
+ */
+static inline int dev_read_stringlist_search(struct udevice *dev,
+					     const char *propname,
+					     const char *string)
+{
+	return ofnode_stringlist_search(dev_ofnode(dev), propname, string);
+}
+
+/**
+ * dev_read_phandle_with_args() - Find a node pointed by phandle in a list
+ *
+ * This function is useful to parse lists of phandles and their arguments.
+ * Returns 0 on success and fills out_args, on error returns appropriate
+ * errno value.
+ *
+ * Caller is responsible to call of_node_put() on the returned out_args->np
+ * pointer.
+ *
+ * Example:
+ *
+ * phandle1: node1 {
+ *	#list-cells = <2>;
+ * }
+ *
+ * phandle2: node2 {
+ *	#list-cells = <1>;
+ * }
+ *
+ * node3 {
+ *	list = <&phandle1 1 2 &phandle2 3>;
+ * }
+ *
+ * To get a device_node of the `node2' node you may call this:
+ * dev_read_phandle_with_args(dev, "list", "#list-cells", 0, 1, &args);
+ *
+ * @dev:	device whose node containing a list
+ * @list_name:	property name that contains a list
+ * @cells_name:	property name that specifies phandles' arguments count
+ * @cells_count: Cell count to use if @cells_name is NULL
+ * @index:	index of a phandle to parse out
+ * @out_args:	optional pointer to output arguments structure (will be filled)
+ * @return 0 on success (with @out_args filled out if not NULL), -ENOENT if
+ *	@list_name does not exist, -EINVAL if a phandle was not found,
+ *	@cells_name could not be found, the arguments were truncated or there
+ *	were too many arguments.
+ */
+static inline int dev_read_phandle_with_args(struct udevice *dev,
+		const char *list_name, const char *cells_name, int cell_count,
+		int index, struct ofnode_phandle_args *out_args)
+{
+	return ofnode_parse_phandle_with_args(dev_ofnode(dev), list_name,
+					      cells_name, cell_count, index,
+					      out_args);
+}
+
+/**
+ * dev_read_addr_cells() - Get the number of address cells for a device's node
+ *
+ * This walks back up the tree to find the closest #address-cells property
+ * which controls the given node.
+ *
+ * @dev: devioe to check
+ * @return number of address cells this node uses
+ */
+static inline int dev_read_addr_cells(struct udevice *dev)
+{
+	return fdt_address_cells(gd->fdt_blob, dev_of_offset(dev));
+}
+
+/**
+ * dev_read_size_cells() - Get the number of size cells for a device's node
+ *
+ * This walks back up the tree to find the closest #size-cells property
+ * which controls the given node.
+ *
+ * @dev: devioe to check
+ * @return number of size cells this node uses
+ */
+static inline int dev_read_size_cells(struct udevice *dev)
+{
+	return fdt_size_cells(gd->fdt_blob, dev_of_offset(dev));
+}
+
+/**
+ * dev_read_phandle() - Get the phandle from a device
+ *
+ * @dev: device to check
+ * @return phandle (1 or greater), or 0 if no phandle or other error
+ */
+static inline int dev_read_phandle(struct udevice *dev)
+{
+	return fdt_get_phandle(gd->fdt_blob, dev_of_offset(dev));
+}
+
+/**
+ * dev_read_prop()- - read a property from a device's node
+ *
+ * @dev: device to check
+ * @propname: property to read
+ * @lenp: place to put length on success
+ * @return pointer to property, or NULL if not found
+ */
+static inline const u32 *dev_read_prop(struct udevice *dev,
+				       const char *propname, int *lenp)
+{
+	return ofnode_read_prop(dev_ofnode(dev), propname, lenp);
+}
+
+/**
+ * dev_read_alias_seq() - Get the alias sequence number of a node
+ *
+ * This works out whether a node is pointed to by an alias, and if so, the
+ * sequence number of that alias. Aliases are of the form <base><num> where
+ * <num> is the sequence number. For example spi2 would be sequence number 2.
+ *
+ * @dev: device to look up
+ * @devnump: set to the sequence number if one is found
+ * @return 0 if a sequence was found, -ve if not
+ */
+static inline int dev_read_alias_seq(struct udevice *dev, int *devnump)
+{
+	return fdtdec_get_alias_seq(gd->fdt_blob, dev->uclass->uc_drv->name,
+				    dev_of_offset(dev), devnump);
+}
+
+/**
+ * dev_read_u32_array() - Find and read an array of 32 bit integers
+ *
+ * Search for a property in a device node and read 32-bit value(s) from
+ * it.
+ *
+ * The out_values is modified only if a valid u32 value can be decoded.
+ *
+ * @dev: device to look up
+ * @propname:	name of the property to read
+ * @out_values:	pointer to return value, modified only if return value is 0
+ * @sz:		number of array elements to read
+ * @return 0 on success, -EINVAL if the property does not exist, -ENODATA if
+ * property does not have a value, and -EOVERFLOW if the property data isn't
+ * large enough.
+ */
+static inline int dev_read_u32_array(struct udevice *dev, const char *propname,
+				     u32 *out_values, size_t sz)
+{
+	return ofnode_read_u32_array(dev_ofnode(dev), propname, out_values, sz);
+}
+
+/**
+ * dev_read_first_subnode() - find the first subnode of a device's node
+ *
+ * @dev: device to look up
+ * @return reference to the first subnode (which can be invalid if the device's
+ * node has no subnodes)
+ */
+static inline ofnode dev_read_first_subnode(struct udevice *dev)
+{
+	return ofnode_first_subnode(dev_ofnode(dev));
+}
+
+/**
+ * ofnode_next_subnode() - find the next sibling of a subnode
+ *
+ * @node:	valid reference to previous node (sibling)
+ * @return reference to the next subnode (which can be invalid if the node
+ * has no more siblings)
+ */
+static inline ofnode dev_read_next_subnode(ofnode node)
+{
+	return ofnode_next_subnode(node);
+}
+
+/**
+ * dev_read_u8_array_ptr() - find an 8-bit array
+ *
+ * Look up a device's node property and return a pointer to its contents as a
+ * byte array of given length. The property must have at least enough data
+ * for the array (count bytes). It may have more, but this will be ignored.
+ * The data is not copied.
+ *
+ * @dev: device to look up
+ * @propname: name of property to find
+ * @sz: number of array elements
+ * @return pointer to byte array if found, or NULL if the property is not
+ *		found or there is not enough data
+ */
+static inline const uint8_t *dev_read_u8_array_ptr(struct udevice *dev,
+					const char *propname, size_t sz)
+{
+	return ofnode_read_u8_array_ptr(dev_ofnode(dev), propname, sz);
+}
+
+#endif /* CONFIG_DM_DEV_READ_INLINE */
+
+/**
+ * dev_for_each_subnode() - Helper function to iterate through subnodes
+ *
+ * This creates a for() loop which works through the subnodes in a device's
+ * device-tree node.
+ *
+ * @subnode: ofnode holding the current subnode
+ * @dev: device to use for interation (struct udevice *)
+ */
+#define dev_for_each_subnode(subnode, dev) \
+	for (subnode = dev_read_first_subnode(dev); \
+	     ofnode_valid(subnode); \
+	     subnode = ofnode_next_subnode(subnode))
+
+#endif
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 14/71] dm: core: Implement live tree 'read' functions
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (12 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 13/71] dm: core: Add device-based 'read' functions to access DT Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 15/71] dm: core: Allow binding a device from a live tree Simon Glass
                   ` (56 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

When the live tree is supported some functions need to change a little.
Add an implementation which is used when not inlining these functions.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/Makefile |   3 +
 drivers/core/read.c   | 140 +++++++++++++++++++++++++++++
 include/dm/read.h     | 240 +++++++++++++++++++++++++++++++-------------------
 3 files changed, 291 insertions(+), 92 deletions(-)
 create mode 100644 drivers/core/read.c

diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index d74b065a07..435cf98ae1 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -12,4 +12,7 @@ obj-$(CONFIG_DM)	+= dump.o
 obj-$(CONFIG_$(SPL_)REGMAP)	+= regmap.o
 obj-$(CONFIG_$(SPL_)SYSCON)	+= syscon-uclass.o
 obj-$(CONFIG_OF_LIVE) += of_access.o of_addr.o
+ifndef CONFIG_DM_DEV_READ_INLINE
+obj-$(CONFIG_OF_CONTROL) += read.o
+endif
 obj-$(CONFIG_OF_CONTROL) += of_extra.o ofnode.o
diff --git a/drivers/core/read.c b/drivers/core/read.c
new file mode 100644
index 0000000000..3131e5379c
--- /dev/null
+++ b/drivers/core/read.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/of_access.h>
+
+int dev_read_u32_default(struct udevice *dev, const char *propname, int def)
+{
+	return ofnode_read_u32_default(dev_ofnode(dev), propname, def);
+}
+
+const char *dev_read_string(struct udevice *dev, const char *propname)
+{
+	return ofnode_read_string(dev_ofnode(dev), propname);
+}
+
+bool dev_read_bool(struct udevice *dev, const char *propname)
+{
+	return ofnode_read_bool(dev_ofnode(dev), propname);
+}
+
+ofnode dev_read_subnode(struct udevice *dev, const char *subnode_name)
+{
+	return ofnode_find_subnode(dev_ofnode(dev), subnode_name);
+}
+
+ofnode dev_read_first_subnode(struct udevice *dev)
+{
+	return ofnode_first_subnode(dev_ofnode(dev));
+}
+
+ofnode dev_read_next_subnode(ofnode node)
+{
+	return ofnode_next_subnode(node);
+}
+
+int dev_read_size(struct udevice *dev, const char *propname)
+{
+	return ofnode_read_size(dev_ofnode(dev), propname);
+}
+
+fdt_addr_t dev_read_addr_index(struct udevice *dev, int index)
+{
+	if (ofnode_is_np(dev_ofnode(dev)))
+		return ofnode_get_addr_index(dev_ofnode(dev), index);
+	else
+		return devfdt_get_addr_index(dev, index);
+}
+
+fdt_addr_t dev_read_addr(struct udevice *dev)
+{
+	return dev_read_addr_index(dev, 0);
+}
+
+fdt_addr_t dev_read_addr_size(struct udevice *dev, const char *property,
+				fdt_size_t *sizep)
+{
+	return ofnode_get_addr_size(dev_ofnode(dev), property, sizep);
+}
+
+const char *dev_read_name(struct udevice *dev)
+{
+	return ofnode_get_name(dev_ofnode(dev));
+}
+
+int dev_read_stringlist_search(struct udevice *dev, const char *property,
+			  const char *string)
+{
+	return ofnode_stringlist_search(dev_ofnode(dev), property, string);
+}
+
+int dev_read_phandle_with_args(struct udevice *dev, const char *list_name,
+				const char *cells_name, int cell_count,
+				int index,
+				struct ofnode_phandle_args *out_args)
+{
+	return ofnode_parse_phandle_with_args(dev_ofnode(dev), list_name,
+					      cells_name, cell_count, index,
+					      out_args);
+}
+
+int dev_read_addr_cells(struct udevice *dev)
+{
+	return ofnode_read_addr_cells(dev_ofnode(dev));
+}
+
+int dev_read_size_cells(struct udevice *dev)
+{
+	return ofnode_read_size_cells(dev_ofnode(dev));
+}
+
+int dev_read_phandle(struct udevice *dev)
+{
+	ofnode node = dev_ofnode(dev);
+
+	if (ofnode_is_np(node))
+		return ofnode_to_np(node)->phandle;
+	else
+		return fdt_get_phandle(gd->fdt_blob, ofnode_to_offset(node));
+}
+
+const u32 *dev_read_prop(struct udevice *dev, const char *propname, int *lenp)
+{
+	return ofnode_read_prop(dev_ofnode(dev), propname, lenp);
+}
+
+int dev_read_alias_seq(struct udevice *dev, int *devnump)
+{
+	ofnode node = dev_ofnode(dev);
+	const char *uc_name = dev->uclass->uc_drv->name;
+	int ret;
+
+	if (ofnode_is_np(node)) {
+		ret = of_alias_get_id(ofnode_to_np(node), uc_name);
+		if (ret >= 0)
+			*devnump = ret;
+	} else {
+		ret = fdtdec_get_alias_seq(gd->fdt_blob, uc_name,
+					   ofnode_to_offset(node), devnump);
+	}
+
+	return ret;
+}
+
+int dev_read_u32_array(struct udevice *dev, const char *propname,
+		       u32 *out_values, size_t sz)
+{
+	return ofnode_read_u32_array(dev_ofnode(dev), propname, out_values, sz);
+}
+
+const uint8_t *dev_read_u8_array_ptr(struct udevice *dev, const char *propname,
+				     size_t sz)
+{
+	return ofnode_read_u8_array_ptr(dev_ofnode(dev), propname, sz);
+}
diff --git a/include/dm/read.h b/include/dm/read.h
index 4ce2bc2d6e..8c9846eaf2 100644
--- a/include/dm/read.h
+++ b/include/dm/read.h
@@ -42,13 +42,16 @@ static inline bool dev_of_valid(struct udevice *dev)
 	return ofnode_valid(dev_ofnode(dev));
 }
 
-#ifdef CONFIG_DM_DEV_READ_INLINE
-
-static inline int dev_read_u32_default(struct udevice *dev,
-				       const char *propname, int def)
-{
-	return ofnode_read_u32_default(dev_ofnode(dev), propname, def);
-}
+#ifndef CONFIG_DM_DEV_READ_INLINE
+/**
+ * dev_read_u32_default() - read a 32-bit integer from a device's DT property
+ *
+ * @dev:	device to read DT property from
+ * @propname:	name of the property to read from
+ * @def:	default value to return if the property has no value
+ * @return property value, or @def if not found
+ */
+int dev_read_u32_default(struct udevice *dev, const char *propname, int def);
 
 /**
  * dev_read_string() - Read a string from a device's DT property
@@ -57,11 +60,7 @@ static inline int dev_read_u32_default(struct udevice *dev,
  * @propname:	name of the property to read
  * @return string from property value, or NULL if there is no such property
  */
-static inline const char *dev_read_string(struct udevice *dev,
-					  const char *propname)
-{
-	return ofnode_read_string(dev_ofnode(dev), propname);
-}
+const char *dev_read_string(struct udevice *dev, const char *propname);
 
 /**
  * dev_read_bool() - read a boolean value from a device's DT property
@@ -70,10 +69,7 @@ static inline const char *dev_read_string(struct udevice *dev,
  * @propname:	name of property to read
  * @return true if property is present (meaning true), false if not present
  */
-static inline bool dev_read_bool(struct udevice *dev, const char *propname)
-{
-	return ofnode_read_bool(dev_ofnode(dev), propname);
-}
+bool dev_read_bool(struct udevice *dev, const char *propname);
 
 /**
  * dev_read_subnode() - find a named subnode of a device
@@ -83,11 +79,7 @@ static inline bool dev_read_bool(struct udevice *dev, const char *propname)
  * @return reference to subnode (which can be invalid if there is no such
  * subnode)
  */
-static inline ofnode dev_read_subnode(struct udevice *dev,
-				      const char *subbnode_name)
-{
-	return ofnode_find_subnode(dev_ofnode(dev), subbnode_name);
-}
+ofnode dev_read_subnode(struct udevice *dev, const char *subbnode_name);
 
 /**
  * dev_read_size() - read the size of a property
@@ -96,10 +88,7 @@ static inline ofnode dev_read_subnode(struct udevice *dev,
  * @propname: property to check
  * @return size of property if present, or -EINVAL if not
  */
-static inline int dev_read_size(struct udevice *dev, const char *propname)
-{
-	return ofnode_read_size(dev_ofnode(dev), propname);
-}
+int dev_read_size(struct udevice *dev, const char *propname);
 
 /**
  * dev_read_addr_index() - Get the indexed reg property of a device
@@ -110,10 +99,7 @@ static inline int dev_read_size(struct udevice *dev, const char *propname)
  *
  * @return address or FDT_ADDR_T_NONE if not found
  */
-static inline fdt_addr_t dev_read_addr_index(struct udevice *dev, int index)
-{
-	return devfdt_get_addr_index(dev, index);
-}
+fdt_addr_t dev_read_addr_index(struct udevice *dev, int index);
 
 /**
  * dev_read_addr() - Get the reg property of a device
@@ -122,10 +108,7 @@ static inline fdt_addr_t dev_read_addr_index(struct udevice *dev, int index)
  *
  * @return address or FDT_ADDR_T_NONE if not found
  */
-static inline fdt_addr_t dev_read_addr(struct udevice *dev)
-{
-	return devfdt_get_addr(dev);
-}
+fdt_addr_t dev_read_addr(struct udevice *dev);
 
 /**
  * dev_read_addr_size() - get address and size from a device property
@@ -138,12 +121,8 @@ static inline fdt_addr_t dev_read_addr(struct udevice *dev)
  * @sizep: place to put size value (on success)
  * @return address value, or FDT_ADDR_T_NONE on error
  */
-static inline fdt_addr_t dev_read_addr_size(struct udevice *dev,
-					    const char *propname,
-					    fdt_size_t *sizep)
-{
-	return ofnode_get_addr_size(dev_ofnode(dev), propname, sizep);
-}
+fdt_addr_t dev_read_addr_size(struct udevice *dev, const char *propname,
+				fdt_size_t *sizep);
 
 /**
  * dev_read_name() - get the name of a device's node
@@ -151,10 +130,7 @@ static inline fdt_addr_t dev_read_addr_size(struct udevice *dev,
  * @node: valid node to look up
  * @return name of node
  */
-static inline const char *dev_read_name(struct udevice *dev)
-{
-	return ofnode_get_name(dev_ofnode(dev));
-}
+const char *dev_read_name(struct udevice *dev);
 
 /**
  * dev_read_stringlist_search() - find string in a string list and return index
@@ -174,12 +150,8 @@ static inline const char *dev_read_name(struct udevice *dev)
  *   -ENODATA if the property is not found
  *   -EINVAL on some other error
  */
-static inline int dev_read_stringlist_search(struct udevice *dev,
-					     const char *propname,
-					     const char *string)
-{
-	return ofnode_stringlist_search(dev_ofnode(dev), propname, string);
-}
+int dev_read_stringlist_search(struct udevice *dev, const char *property,
+			  const char *string);
 
 /**
  * dev_read_phandle_with_args() - Find a node pointed by phandle in a list
@@ -219,14 +191,10 @@ static inline int dev_read_stringlist_search(struct udevice *dev,
  *	@cells_name could not be found, the arguments were truncated or there
  *	were too many arguments.
  */
-static inline int dev_read_phandle_with_args(struct udevice *dev,
-		const char *list_name, const char *cells_name, int cell_count,
-		int index, struct ofnode_phandle_args *out_args)
-{
-	return ofnode_parse_phandle_with_args(dev_ofnode(dev), list_name,
-					      cells_name, cell_count, index,
-					      out_args);
-}
+int dev_read_phandle_with_args(struct udevice *dev, const char *list_name,
+				const char *cells_name, int cell_count,
+				int index,
+				struct ofnode_phandle_args *out_args);
 
 /**
  * dev_read_addr_cells() - Get the number of address cells for a device's node
@@ -237,10 +205,7 @@ static inline int dev_read_phandle_with_args(struct udevice *dev,
  * @dev: devioe to check
  * @return number of address cells this node uses
  */
-static inline int dev_read_addr_cells(struct udevice *dev)
-{
-	return fdt_address_cells(gd->fdt_blob, dev_of_offset(dev));
-}
+int dev_read_addr_cells(struct udevice *dev);
 
 /**
  * dev_read_size_cells() - Get the number of size cells for a device's node
@@ -251,10 +216,7 @@ static inline int dev_read_addr_cells(struct udevice *dev)
  * @dev: devioe to check
  * @return number of size cells this node uses
  */
-static inline int dev_read_size_cells(struct udevice *dev)
-{
-	return fdt_size_cells(gd->fdt_blob, dev_of_offset(dev));
-}
+int dev_read_size_cells(struct udevice *dev);
 
 /**
  * dev_read_phandle() - Get the phandle from a device
@@ -262,10 +224,7 @@ static inline int dev_read_size_cells(struct udevice *dev)
  * @dev: device to check
  * @return phandle (1 or greater), or 0 if no phandle or other error
  */
-static inline int dev_read_phandle(struct udevice *dev)
-{
-	return fdt_get_phandle(gd->fdt_blob, dev_of_offset(dev));
-}
+int dev_read_phandle(struct udevice *dev);
 
 /**
  * dev_read_prop()- - read a property from a device's node
@@ -275,11 +234,7 @@ static inline int dev_read_phandle(struct udevice *dev)
  * @lenp: place to put length on success
  * @return pointer to property, or NULL if not found
  */
-static inline const u32 *dev_read_prop(struct udevice *dev,
-				       const char *propname, int *lenp)
-{
-	return ofnode_read_prop(dev_ofnode(dev), propname, lenp);
-}
+const u32 *dev_read_prop(struct udevice *dev, const char *propname, int *lenp);
 
 /**
  * dev_read_alias_seq() - Get the alias sequence number of a node
@@ -292,11 +247,7 @@ static inline const u32 *dev_read_prop(struct udevice *dev,
  * @devnump: set to the sequence number if one is found
  * @return 0 if a sequence was found, -ve if not
  */
-static inline int dev_read_alias_seq(struct udevice *dev, int *devnump)
-{
-	return fdtdec_get_alias_seq(gd->fdt_blob, dev->uclass->uc_drv->name,
-				    dev_of_offset(dev), devnump);
-}
+int dev_read_alias_seq(struct udevice *dev, int *devnump);
 
 /**
  * dev_read_u32_array() - Find and read an array of 32 bit integers
@@ -314,11 +265,8 @@ static inline int dev_read_alias_seq(struct udevice *dev, int *devnump)
  * property does not have a value, and -EOVERFLOW if the property data isn't
  * large enough.
  */
-static inline int dev_read_u32_array(struct udevice *dev, const char *propname,
-				     u32 *out_values, size_t sz)
-{
-	return ofnode_read_u32_array(dev_ofnode(dev), propname, out_values, sz);
-}
+int dev_read_u32_array(struct udevice *dev, const char *propname,
+		       u32 *out_values, size_t sz);
 
 /**
  * dev_read_first_subnode() - find the first subnode of a device's node
@@ -327,10 +275,7 @@ static inline int dev_read_u32_array(struct udevice *dev, const char *propname,
  * @return reference to the first subnode (which can be invalid if the device's
  * node has no subnodes)
  */
-static inline ofnode dev_read_first_subnode(struct udevice *dev)
-{
-	return ofnode_first_subnode(dev_ofnode(dev));
-}
+ofnode dev_read_first_subnode(struct udevice *dev);
 
 /**
  * ofnode_next_subnode() - find the next sibling of a subnode
@@ -339,10 +284,7 @@ static inline ofnode dev_read_first_subnode(struct udevice *dev)
  * @return reference to the next subnode (which can be invalid if the node
  * has no more siblings)
  */
-static inline ofnode dev_read_next_subnode(ofnode node)
-{
-	return ofnode_next_subnode(node);
-}
+ofnode dev_read_next_subnode(ofnode node);
 
 /**
  * dev_read_u8_array_ptr() - find an 8-bit array
@@ -358,6 +300,120 @@ static inline ofnode dev_read_next_subnode(ofnode node)
  * @return pointer to byte array if found, or NULL if the property is not
  *		found or there is not enough data
  */
+const uint8_t *dev_read_u8_array_ptr(struct udevice *dev, const char *propname,
+				     size_t sz);
+
+#else /* CONFIG_DM_DEV_READ_INLINE is enabled */
+
+static inline int dev_read_u32_default(struct udevice *dev,
+				       const char *propname, int def)
+{
+	return ofnode_read_u32_default(dev_ofnode(dev), propname, def);
+}
+
+static inline const char *dev_read_string(struct udevice *dev,
+					  const char *propname)
+{
+	return ofnode_read_string(dev_ofnode(dev), propname);
+}
+
+static inline bool dev_read_bool(struct udevice *dev, const char *propname)
+{
+	return ofnode_read_bool(dev_ofnode(dev), propname);
+}
+
+static inline ofnode dev_read_subnode(struct udevice *dev,
+				      const char *subbnode_name)
+{
+	return ofnode_find_subnode(dev_ofnode(dev), subbnode_name);
+}
+
+static inline int dev_read_size(struct udevice *dev, const char *propname)
+{
+	return ofnode_read_size(dev_ofnode(dev), propname);
+}
+
+static inline fdt_addr_t dev_read_addr_index(struct udevice *dev, int index)
+{
+	return devfdt_get_addr_index(dev, index);
+}
+
+static inline fdt_addr_t dev_read_addr(struct udevice *dev)
+{
+	return devfdt_get_addr(dev);
+}
+
+static inline fdt_addr_t dev_read_addr_size(struct udevice *dev,
+					    const char *propname,
+					    fdt_size_t *sizep)
+{
+	return ofnode_get_addr_size(dev_ofnode(dev), propname, sizep);
+}
+
+static inline const char *dev_read_name(struct udevice *dev)
+{
+	return ofnode_get_name(dev_ofnode(dev));
+}
+
+static inline int dev_read_stringlist_search(struct udevice *dev,
+					     const char *propname,
+					     const char *string)
+{
+	return ofnode_stringlist_search(dev_ofnode(dev), propname, string);
+}
+
+static inline int dev_read_phandle_with_args(struct udevice *dev,
+		const char *list_name, const char *cells_name, int cell_count,
+		int index, struct ofnode_phandle_args *out_args)
+{
+	return ofnode_parse_phandle_with_args(dev_ofnode(dev), list_name,
+					      cells_name, cell_count, index,
+					      out_args);
+}
+
+static inline int dev_read_addr_cells(struct udevice *dev)
+{
+	return fdt_address_cells(gd->fdt_blob, dev_of_offset(dev));
+}
+
+static inline int dev_read_size_cells(struct udevice *dev)
+{
+	return fdt_size_cells(gd->fdt_blob, dev_of_offset(dev));
+}
+
+static inline int dev_read_phandle(struct udevice *dev)
+{
+	return fdt_get_phandle(gd->fdt_blob, dev_of_offset(dev));
+}
+
+static inline const u32 *dev_read_prop(struct udevice *dev,
+				       const char *propname, int *lenp)
+{
+	return ofnode_read_prop(dev_ofnode(dev), propname, lenp);
+}
+
+static inline int dev_read_alias_seq(struct udevice *dev, int *devnump)
+{
+	return fdtdec_get_alias_seq(gd->fdt_blob, dev->uclass->uc_drv->name,
+				    dev_of_offset(dev), devnump);
+}
+
+static inline int dev_read_u32_array(struct udevice *dev, const char *propname,
+				     u32 *out_values, size_t sz)
+{
+	return ofnode_read_u32_array(dev_ofnode(dev), propname, out_values, sz);
+}
+
+static inline ofnode dev_read_first_subnode(struct udevice *dev)
+{
+	return ofnode_first_subnode(dev_ofnode(dev));
+}
+
+static inline ofnode dev_read_next_subnode(ofnode node)
+{
+	return ofnode_next_subnode(node);
+}
+
 static inline const uint8_t *dev_read_u8_array_ptr(struct udevice *dev,
 					const char *propname, size_t sz)
 {
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 15/71] dm: core: Allow binding a device from a live tree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (13 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 14/71] dm: core: Implement live tree 'read' functions Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 16/71] dm: core: Update lists_bind_fdt() to use ofnode Simon Glass
                   ` (55 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

When a live tree is being used we need to record the node that was used to
create the device. Update device_bind_with_driver_data() to support this.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/device.c        | 18 ++++++++----------
 drivers/core/lists.c         |  2 +-
 include/dm/device-internal.h | 10 ++++++----
 3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index f5e85413f7..5463d1ffa5 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -19,6 +19,7 @@
 #include <dm/lists.h>
 #include <dm/pinctrl.h>
 #include <dm/platdata.h>
+#include <dm/read.h>
 #include <dm/uclass.h>
 #include <dm/uclass-internal.h>
 #include <dm/util.h>
@@ -77,10 +78,7 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
 		 */
 		if (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS) {
 			if (uc->uc_drv->name && ofnode_valid(node)) {
-				fdtdec_get_alias_seq(gd->fdt_blob,
-						uc->uc_drv->name,
-						ofnode_to_offset(node),
-						&dev->req_seq);
+				dev_read_alias_seq(dev, &dev->req_seq);
 			}
 		}
 	}
@@ -216,11 +214,11 @@ fail_alloc1:
 
 int device_bind_with_driver_data(struct udevice *parent,
 				 const struct driver *drv, const char *name,
-				 ulong driver_data, int of_offset,
+				 ulong driver_data, ofnode node,
 				 struct udevice **devp)
 {
-	return device_bind_common(parent, drv, name, NULL, driver_data,
-				  offset_to_ofnode(of_offset), 0, devp);
+	return device_bind_common(parent, drv, name, NULL, driver_data, node,
+				  0, devp);
 }
 
 int device_bind(struct udevice *parent, const struct driver *drv,
@@ -247,8 +245,8 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
 	platdata_size = info->platdata_size;
 #endif
 	return device_bind_common(parent, drv, info->name,
-			(void *)info->platdata, 0, offset_to_ofnode(-1),
-			platdata_size, devp);
+			(void *)info->platdata, 0, ofnode_null(), platdata_size,
+			devp);
 }
 
 static void *alloc_priv(int size, uint flags)
@@ -385,7 +383,7 @@ int device_probe(struct udevice *dev)
 			goto fail;
 	}
 
-	if (drv->ofdata_to_platdata && dev_of_offset(dev) >= 0) {
+	if (drv->ofdata_to_platdata && dev_has_of_node(dev)) {
 		ret = drv->ofdata_to_platdata(dev);
 		if (ret)
 			goto fail;
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index 72c55e205f..9adfa758bc 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -177,7 +177,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
 
 		dm_dbg("   - found match at '%s'\n", entry->name);
 		ret = device_bind_with_driver_data(parent, entry, name,
-						   id->data, offset, &dev);
+				id->data, offset_to_ofnode(offset), &dev);
 		if (ret == -ENODEV) {
 			dm_dbg("Driver '%s' refuses to bind\n", entry->name);
 			continue;
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h
index 2cabc87338..81ab893b60 100644
--- a/include/dm/device-internal.h
+++ b/include/dm/device-internal.h
@@ -11,6 +11,9 @@
 #ifndef _DM_DEVICE_INTERNAL_H
 #define _DM_DEVICE_INTERNAL_H
 
+#include <dm/ofnode.h>
+
+struct device_node;
 struct udevice;
 
 /**
@@ -52,16 +55,15 @@ int device_bind(struct udevice *parent, const struct driver *drv,
  * @drv: Device's driver
  * @name: Name of device (e.g. device tree node name)
  * @driver_data: The driver_data field from the driver's match table.
- * @of_offset: Offset of device tree node for this device. This is -1 for
- * devices which don't use device tree.
+ * @node: Device tree node for this device. This is invalid for devices which
+ * don't use device tree.
  * @devp: if non-NULL, returns a pointer to the bound device
  * @return 0 if OK, -ve on error
  */
 int device_bind_with_driver_data(struct udevice *parent,
 				 const struct driver *drv, const char *name,
-				 ulong driver_data, int of_offset,
+				 ulong driver_data, ofnode node,
 				 struct udevice **devp);
-
 /**
  * device_bind_by_name: Create a device and bind it to a driver
  *
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 16/71] dm: core: Update lists_bind_fdt() to use ofnode
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (14 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 15/71] dm: core: Allow binding a device from a live tree Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 17/71] dm: core: Update device_bind_driver_to_node() " Simon Glass
                   ` (54 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

Adjust this function to use an ofnode instead of an offset, so it can be
used with livetree. This involves updating all callers.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/lists.c           | 12 ++++++------
 drivers/core/root.c            |  2 +-
 drivers/serial/serial-uclass.c |  3 ++-
 drivers/timer/timer-uclass.c   |  3 ++-
 include/dm/lists.h             |  7 +++----
 5 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index 9adfa758bc..facf276474 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -126,8 +126,7 @@ static int driver_check_compatible(const struct udevice_id *of_match,
 	return -ENOENT;
 }
 
-int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
-		   struct udevice **devp)
+int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp)
 {
 	struct driver *driver = ll_entry_start(struct driver, driver);
 	const int n_ents = ll_entry_count(struct driver, driver);
@@ -142,17 +141,18 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
 
 	if (devp)
 		*devp = NULL;
-	name = fdt_get_name(blob, offset, NULL);
+	name = ofnode_get_name(node);
 	dm_dbg("bind node %s\n", name);
 
-	compat_list = fdt_getprop(blob, offset, "compatible", &compat_length);
+	compat_list = (const char *)ofnode_read_prop(node, "compatible",
+						     &compat_length);
 	if (!compat_list) {
 		if (compat_length == -FDT_ERR_NOTFOUND) {
 			dm_dbg("Device '%s' has no compatible string\n", name);
 			return 0;
 		}
 
-		dm_warn("Device tree error at offset %d\n", offset);
+		dm_warn("Device tree error at node '%s'\n", name);
 		return compat_length;
 	}
 
@@ -177,7 +177,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
 
 		dm_dbg("   - found match at '%s'\n", entry->name);
 		ret = device_bind_with_driver_data(parent, entry, name,
-				id->data, offset_to_ofnode(offset), &dev);
+						   id->data, node, &dev);
 		if (ret == -ENODEV) {
 			dm_dbg("Driver '%s' refuses to bind\n", entry->name);
 			continue;
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 570b4d855f..0c00a4e051 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -235,7 +235,7 @@ static int dm_scan_fdt_node(struct udevice *parent, const void *blob,
 			dm_dbg("   - ignoring disabled device\n");
 			continue;
 		}
-		err = lists_bind_fdt(parent, blob, offset, NULL);
+		err = lists_bind_fdt(parent, offset_to_ofnode(offset), NULL);
 		if (err && !ret) {
 			ret = err;
 			debug("%s: ret=%d\n", fdt_get_name(blob, offset, NULL),
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 43c028ebe6..877398ebcd 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -74,7 +74,8 @@ static void serial_find_console_or_panic(void)
 		 * bind it anyway.
 		 */
 		if (node > 0 &&
-		    !lists_bind_fdt(gd->dm_root, blob, node, &dev)) {
+		    !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
+				    &dev)) {
 			if (!device_probe(dev)) {
 				gd->cur_serial_dev = dev;
 				return;
diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c
index 1caf3cd288..ec10b28288 100644
--- a/drivers/timer/timer-uclass.c
+++ b/drivers/timer/timer-uclass.c
@@ -103,7 +103,8 @@ int notrace dm_timer_init(void)
 			 * relocation, bind it anyway.
 			 */
 			if (node > 0 &&
-			    !lists_bind_fdt(gd->dm_root, blob, node, &dev)) {
+			    !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
+					    &dev)) {
 				ret = device_probe(dev);
 				if (ret)
 					return ret;
diff --git a/include/dm/lists.h b/include/dm/lists.h
index 4513d6a311..f55c41991b 100644
--- a/include/dm/lists.h
+++ b/include/dm/lists.h
@@ -10,6 +10,7 @@
 #ifndef _DM_LISTS_H_
 #define _DM_LISTS_H_
 
+#include <dm/ofnode.h>
 #include <dm/uclass-id.h>
 
 /**
@@ -51,14 +52,12 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only);
  * @parent as its parent.
  *
  * @parent: parent device (root)
- * @blob: device tree blob
- * @offset: offset of this device tree node
+ * @node: device tree node to bind
  * @devp: if non-NULL, returns a pointer to the bound device
  * @return 0 if device was bound, -EINVAL if the device tree is invalid,
  * other -ve value on error
  */
-int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
-		   struct udevice **devp);
+int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp);
 
 /**
  * device_bind_driver() - bind a device to a driver
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 17/71] dm: core: Update device_bind_driver_to_node() to use ofnode
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (15 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 16/71] dm: core: Update lists_bind_fdt() to use ofnode Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 18/71] dm: core: Scan the live tree when setting up driver model Simon Glass
                   ` (53 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

Adjust this function to us an ofnode instead of an offset, so it can be
used with livetree. This involves updating all callers.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/clk/at91/pmc.c             |  2 +-
 drivers/core/lists.c               | 15 ++++++---------
 drivers/cpu/cpu-uclass.c           |  6 +++---
 drivers/i2c/muxes/i2c-mux-uclass.c | 11 ++++-------
 drivers/led/led_gpio.c             | 13 +++++--------
 drivers/misc/tegra186_bpmp.c       |  6 +++---
 drivers/misc/tegra_car.c           |  4 ++--
 drivers/net/keystone_net.c         |  6 +++---
 drivers/pinctrl/pinctrl-uclass.c   | 15 ++++++---------
 drivers/usb/musb-new/ti-musb.c     |  2 +-
 include/dm.h                       |  2 ++
 include/dm/lists.h                 |  2 +-
 12 files changed, 37 insertions(+), 47 deletions(-)

diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index c552c75562..f4ec5fcb5e 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -79,7 +79,7 @@ int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name)
 		if (!name)
 			return -EINVAL;
 		ret = device_bind_driver_to_node(dev, drv_name, name,
-						 offset, NULL);
+					offset_to_ofnode(offset), NULL);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index facf276474..b79f26dbe6 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -74,11 +74,12 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)
 int device_bind_driver(struct udevice *parent, const char *drv_name,
 		       const char *dev_name, struct udevice **devp)
 {
-	return device_bind_driver_to_node(parent, drv_name, dev_name, -1, devp);
+	return device_bind_driver_to_node(parent, drv_name, dev_name,
+					  ofnode_null(), devp);
 }
 
 int device_bind_driver_to_node(struct udevice *parent, const char *drv_name,
-			       const char *dev_name, int node,
+			       const char *dev_name, ofnode node,
 			       struct udevice **devp)
 {
 	struct driver *drv;
@@ -89,14 +90,10 @@ int device_bind_driver_to_node(struct udevice *parent, const char *drv_name,
 		debug("Cannot find driver '%s'\n", drv_name);
 		return -ENOENT;
 	}
-	ret = device_bind(parent, drv, dev_name, NULL, node, devp);
-	if (ret) {
-		debug("Cannot create device named '%s' (err=%d)\n",
-		      dev_name, ret);
-		return ret;
-	}
+	ret = device_bind_with_driver_data(parent, drv, dev_name, 0 /* data */,
+					   node, devp);
 
-	return 0;
+	return ret;
 }
 
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c
index c57ac16b3a..73e4853939 100644
--- a/drivers/cpu/cpu-uclass.c
+++ b/drivers/cpu/cpu-uclass.c
@@ -63,11 +63,11 @@ U_BOOT_DRIVER(cpu_bus) = {
 static int uclass_cpu_init(struct uclass *uc)
 {
 	struct udevice *dev;
-	int node;
+	ofnode node;
 	int ret;
 
-	node = fdt_path_offset(gd->fdt_blob, "/cpus");
-	if (node < 0)
+	node = ofnode_path("/cpus");
+	if (!ofnode_valid(node))
 		return 0;
 
 	ret = device_bind_driver_to_node(dm_root(), "cpu_bus", "cpus", node,
diff --git a/drivers/i2c/muxes/i2c-mux-uclass.c b/drivers/i2c/muxes/i2c-mux-uclass.c
index d243b8e32d..187e8a7c91 100644
--- a/drivers/i2c/muxes/i2c-mux-uclass.c
+++ b/drivers/i2c/muxes/i2c-mux-uclass.c
@@ -51,24 +51,21 @@ static int i2c_mux_child_post_bind(struct udevice *dev)
 /* Find the I2C buses selected by this mux */
 static int i2c_mux_post_bind(struct udevice *mux)
 {
-	const void *blob = gd->fdt_blob;
+	ofnode node;
 	int ret;
-	int offset;
 
 	debug("%s: %s\n", __func__, mux->name);
 	/*
 	 * There is no compatible string in the sub-nodes, so we must manually
 	 * bind these
 	 */
-	for (offset = fdt_first_subnode(blob, dev_of_offset(mux));
-	     offset > 0;
-	     offset = fdt_next_subnode(blob, offset)) {
+	dev_for_each_subnode(node, mux) {
 		struct udevice *dev;
 		const char *name;
 
-		name = fdt_get_name(blob, offset, NULL);
+		name = ofnode_get_name(node);
 		ret = device_bind_driver_to_node(mux, "i2c_mux_bus_drv", name,
-						 offset, &dev);
+						 node, &dev);
 		debug("   - bind ret=%d, %s\n", ret, dev ? dev->name : NULL);
 		if (ret)
 			return ret;
diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c
index 4106ecb679..9976635887 100644
--- a/drivers/led/led_gpio.c
+++ b/drivers/led/led_gpio.c
@@ -85,25 +85,22 @@ static int led_gpio_remove(struct udevice *dev)
 
 static int led_gpio_bind(struct udevice *parent)
 {
-	const void *blob = gd->fdt_blob;
 	struct udevice *dev;
-	int node;
+	ofnode node;
 	int ret;
 
-	for (node = fdt_first_subnode(blob, dev_of_offset(parent));
-	     node > 0;
-	     node = fdt_next_subnode(blob, node)) {
+	dev_for_each_subnode(node, parent) {
 		struct led_uc_plat *uc_plat;
 		const char *label;
 
-		label = fdt_getprop(blob, node, "label", NULL);
+		label = ofnode_read_string(node, "label");
 		if (!label) {
 			debug("%s: node %s has no label\n", __func__,
-			      fdt_get_name(blob, node, NULL));
+			      ofnode_get_name(node));
 			return -EINVAL;
 		}
 		ret = device_bind_driver_to_node(parent, "gpio_led",
-						 fdt_get_name(blob, node, NULL),
+						 ofnode_get_name(node),
 						 node, &dev);
 		if (ret)
 			return ret;
diff --git a/drivers/misc/tegra186_bpmp.c b/drivers/misc/tegra186_bpmp.c
index bd8b9602e0..d61bacfc44 100644
--- a/drivers/misc/tegra186_bpmp.c
+++ b/drivers/misc/tegra186_bpmp.c
@@ -112,19 +112,19 @@ static int tegra186_bpmp_bind(struct udevice *dev)
 	debug("%s(dev=%p)\n", __func__, dev);
 
 	ret = device_bind_driver_to_node(dev, "tegra186_clk", "tegra186_clk",
-					 dev_of_offset(dev), &child);
+					 dev_ofnode(dev), &child);
 	if (ret)
 		return ret;
 
 	ret = device_bind_driver_to_node(dev, "tegra186_reset",
-					 "tegra186_reset", dev_of_offset(dev),
+					 "tegra186_reset", dev_ofnode(dev),
 					 &child);
 	if (ret)
 		return ret;
 
 	ret = device_bind_driver_to_node(dev, "tegra186_power_domain",
 					 "tegra186_power_domain",
-					 dev_of_offset(dev), &child);
+					 dev_ofnode(dev), &child);
 	if (ret)
 		return ret;
 
diff --git a/drivers/misc/tegra_car.c b/drivers/misc/tegra_car.c
index 5db3c374ce..93639e1989 100644
--- a/drivers/misc/tegra_car.c
+++ b/drivers/misc/tegra_car.c
@@ -22,12 +22,12 @@ static int tegra_car_bpmp_bind(struct udevice *dev)
 	debug("%s(dev=%p)\n", __func__, dev);
 
 	ret = device_bind_driver_to_node(dev, "tegra_car_clk", "tegra_car_clk",
-					 dev_of_offset(dev), &child);
+					 dev_ofnode(dev), &child);
 	if (ret)
 		return ret;
 
 	ret = device_bind_driver_to_node(dev, "tegra_car_reset",
-					 "tegra_car_reset", dev_of_offset(dev),
+					 "tegra_car_reset", dev_ofnode(dev),
 					 &child);
 	if (ret)
 		return ret;
diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c
index f9ffd6d725..72ef42cca8 100644
--- a/drivers/net/keystone_net.c
+++ b/drivers/net/keystone_net.c
@@ -1008,8 +1008,8 @@ static int ks2_eth_bind_slaves(struct udevice *dev, int gbe, int *gbe_0)
 			slave_name = malloc(20);
 			snprintf(slave_name, 20, "netcp at slave-%d", slave_no);
 			ret = device_bind_driver_to_node(dev, "eth_ks2_sl",
-							 slave_name, slave,
-							 &sl_dev);
+					slave_name, offset_to_ofnode(slave),
+					&sl_dev);
 			if (ret) {
 				error("ks2_net - not able to bind slave interfaces\n");
 				return ret;
@@ -1029,7 +1029,7 @@ static int ks2_eth_bind_slaves(struct udevice *dev, int gbe, int *gbe_0)
 		slave_name = malloc(20);
 		snprintf(slave_name, 20, "netcp at slave-%d", slave_no);
 		ret = device_bind_driver_to_node(dev, "eth_ks2_sl", slave_name,
-						 slave, &sl_dev);
+					offset_to_ofnode(slave), &sl_dev);
 		if (ret) {
 			error("ks2_net - not able to bind slave interfaces\n");
 			return ret;
diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c
index 0633b69bbe..02e269020d 100644
--- a/drivers/pinctrl/pinctrl-uclass.c
+++ b/drivers/pinctrl/pinctrl-uclass.c
@@ -121,34 +121,31 @@ static int pinctrl_select_state_full(struct udevice *dev, const char *statename)
  */
 static int pinconfig_post_bind(struct udevice *dev)
 {
-	const void *fdt = gd->fdt_blob;
-	int offset = dev_of_offset(dev);
 	bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
 	const char *name;
+	ofnode node;
 	int ret;
 
-	for (offset = fdt_first_subnode(fdt, offset);
-	     offset > 0;
-	     offset = fdt_next_subnode(fdt, offset)) {
+	dev_for_each_subnode(node, dev) {
 		if (pre_reloc_only &&
-		    !dm_fdt_pre_reloc(fdt, offset))
+		    !ofnode_pre_reloc(node))
 			continue;
 		/*
 		 * If this node has "compatible" property, this is not
 		 * a pin configuration node, but a normal device. skip.
 		 */
-		fdt_get_property(fdt, offset, "compatible", &ret);
+		ofnode_read_prop(node, "compatible", &ret);
 		if (ret >= 0)
 			continue;
 
 		if (ret != -FDT_ERR_NOTFOUND)
 			return ret;
 
-		name = fdt_get_name(fdt, offset, NULL);
+		name = ofnode_get_name(node);
 		if (!name)
 			return -EINVAL;
 		ret = device_bind_driver_to_node(dev, "pinconfig", name,
-						 offset, NULL);
+						 node, NULL);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/usb/musb-new/ti-musb.c b/drivers/usb/musb-new/ti-musb.c
index 27018c73b6..de101319cd 100644
--- a/drivers/usb/musb-new/ti-musb.c
+++ b/drivers/usb/musb-new/ti-musb.c
@@ -227,7 +227,7 @@ static int ti_musb_wrapper_bind(struct udevice *parent)
 		case USB_DR_MODE_HOST:
 			/* Bind MUSB host */
 			ret = device_bind_driver_to_node(parent, "ti-musb-host",
-							 name, node, &dev);
+					name, offset_to_ofnode(node), &dev);
 			if (ret) {
 				error("musb - not able to bind usb host node\n");
 				return ret;
diff --git a/include/dm.h b/include/dm.h
index e634814d74..f752792c92 100644
--- a/include/dm.h
+++ b/include/dm.h
@@ -10,6 +10,8 @@
 #include <dm/ofnode.h>
 #include <dm/device.h>
 #include <dm/fdtaddr.h>
+#include <dm/ofnode.h>
+#include <dm/read.h>
 #include <dm/platdata.h>
 #include <dm/uclass.h>
 
diff --git a/include/dm/lists.h b/include/dm/lists.h
index f55c41991b..d4d82d2fc4 100644
--- a/include/dm/lists.h
+++ b/include/dm/lists.h
@@ -85,7 +85,7 @@ int device_bind_driver(struct udevice *parent, const char *drv_name,
  * @devp:	If non-NULL, returns the newly bound device
  */
 int device_bind_driver_to_node(struct udevice *parent, const char *drv_name,
-			       const char *dev_name, int node,
+			       const char *dev_name, ofnode node,
 			       struct udevice **devp);
 
 #endif
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 18/71] dm: core: Scan the live tree when setting up driver model
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (16 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 17/71] dm: core: Update device_bind_driver_to_node() " Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 19/71] dm: core: Add a way to find a device by ofnode Simon Glass
                   ` (52 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

When starting up driver model with a live tree we need to scan the tree
for devices. Add code to handle this.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/root.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++----
 include/dm/root.h   |  3 ++-
 test/dm/test-main.c |  4 ++--
 3 files changed, 58 insertions(+), 7 deletions(-)

diff --git a/drivers/core/root.c b/drivers/core/root.c
index 0c00a4e051..d691d6ff94 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -15,7 +15,10 @@
 #include <dm/device.h>
 #include <dm/device-internal.h>
 #include <dm/lists.h>
+#include <dm/of.h>
+#include <dm/of_access.h>
 #include <dm/platdata.h>
+#include <dm/read.h>
 #include <dm/root.h>
 #include <dm/uclass.h>
 #include <dm/util.h>
@@ -147,7 +150,7 @@ void fix_devices(void)
 
 #endif
 
-int dm_init(void)
+int dm_init(bool of_live)
 {
 	int ret;
 
@@ -167,7 +170,12 @@ int dm_init(void)
 	if (ret)
 		return ret;
 #if CONFIG_IS_ENABLED(OF_CONTROL)
-	DM_ROOT_NON_CONST->node = offset_to_ofnode(0);
+# if CONFIG_IS_ENABLED(OF_LIVE)
+	if (of_live)
+		DM_ROOT_NON_CONST->node = np_to_ofnode(gd->of_root);
+	else
+#endif
+		DM_ROOT_NON_CONST->node = offset_to_ofnode(0);
 #endif
 	ret = device_probe(DM_ROOT_NON_CONST);
 	if (ret)
@@ -206,6 +214,36 @@ int dm_scan_platdata(bool pre_reloc_only)
 	return ret;
 }
 
+#if CONFIG_IS_ENABLED(OF_LIVE)
+static int dm_scan_fdt_live(struct udevice *parent,
+			    const struct device_node *node_parent,
+			    bool pre_reloc_only)
+{
+	struct device_node *np;
+	int ret = 0, err;
+
+	for (np = node_parent->child; np; np = np->sibling) {
+		if (pre_reloc_only &&
+		    !of_find_property(np, "u-boot,dm-pre-reloc", NULL))
+			continue;
+		if (!of_device_is_available(np)) {
+			dm_dbg("   - ignoring disabled device\n");
+			continue;
+		}
+		err = lists_bind_fdt(parent, np_to_ofnode(np), NULL);
+		if (err && !ret) {
+			ret = err;
+			debug("%s: ret=%d\n", np->name, ret);
+		}
+	}
+
+	if (ret)
+		dm_warn("Some drivers failed to bind\n");
+
+	return ret;
+}
+#endif /* CONFIG_IS_ENABLED(OF_LIVE) */
+
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 /**
  * dm_scan_fdt_node() - Scan the device tree and bind drivers for a node
@@ -251,15 +289,27 @@ static int dm_scan_fdt_node(struct udevice *parent, const void *blob,
 
 int dm_scan_fdt_dev(struct udevice *dev)
 {
-	if (dev_of_offset(dev) == -1)
+	if (!dev_of_valid(dev))
 		return 0;
 
+#if CONFIG_IS_ENABLED(OF_LIVE)
+	if (of_live_active())
+		return dm_scan_fdt_live(dev, dev_np(dev),
+				gd->flags & GD_FLG_RELOC ? false : true);
+	else
+#endif
 	return dm_scan_fdt_node(dev, gd->fdt_blob, dev_of_offset(dev),
 				gd->flags & GD_FLG_RELOC ? false : true);
 }
 
 int dm_scan_fdt(const void *blob, bool pre_reloc_only)
 {
+#if CONFIG_IS_ENABLED(OF_LIVE)
+	if (of_live_active())
+		return dm_scan_fdt_live(gd->dm_root, gd->of_root,
+					pre_reloc_only);
+	else
+#endif
 	return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only);
 }
 #endif
@@ -273,7 +323,7 @@ int dm_init_and_scan(bool pre_reloc_only)
 {
 	int ret;
 
-	ret = dm_init();
+	ret = dm_init(IS_ENABLED(CONFIG_OF_LIVE));
 	if (ret) {
 		debug("dm_init() failed: %d\n", ret);
 		return ret;
diff --git a/include/dm/root.h b/include/dm/root.h
index 186cf8ba1c..50a6011644 100644
--- a/include/dm/root.h
+++ b/include/dm/root.h
@@ -87,9 +87,10 @@ int dm_init_and_scan(bool pre_reloc_only);
  * This function will initialize roots of driver tree and class tree.
  * This needs to be called before anything uses the DM
  *
+ * @of_live:	Enable live device tree
  * @return 0 if OK, -ve on error
  */
-int dm_init(void);
+int dm_init(bool of_live);
 
 /**
  * dm_uninit - Uninitialise Driver Model structures
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index f2e0048143..67c0082fb8 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -30,7 +30,7 @@ static int dm_test_init(struct unit_test_state *uts)
 	gd->dm_root = NULL;
 	memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count));
 
-	ut_assertok(dm_init());
+	ut_assertok(dm_init(false));
 	dms->root = dm_root();
 
 	return 0;
@@ -137,7 +137,7 @@ static int dm_test_main(const char *test_name)
 		printf("Failures: %d\n", uts->fail_count);
 
 	gd->dm_root = NULL;
-	ut_assertok(dm_init());
+	ut_assertok(dm_init(false));
 	dm_scan_platdata(false);
 	dm_scan_fdt(gd->fdt_blob, false);
 
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 19/71] dm: core: Add a way to find a device by ofnode
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (17 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 18/71] dm: core: Scan the live tree when setting up driver model Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 20/71] dm: regmap: Add support for livetree Simon Glass
                   ` (51 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

Add a function which looks up a device by its node (either in live tree
or flat tree).

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/uclass.c        | 37 +++++++++++++++++++++++++++++++++++++
 include/dm/uclass-internal.h | 16 ++++++++++++++++
 include/dm/uclass.h          | 16 ++++++++++++++++
 3 files changed, 69 insertions(+)

diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 04fb45b01a..630b2e7336 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -8,6 +8,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <errno.h>
 #include <malloc.h>
 #include <dm/device.h>
@@ -287,6 +288,30 @@ int uclass_find_device_by_of_offset(enum uclass_id id, int node,
 	return -ENODEV;
 }
 
+int uclass_find_device_by_ofnode(enum uclass_id id, ofnode node,
+				 struct udevice **devp)
+{
+	struct uclass *uc;
+	struct udevice *dev;
+	int ret;
+
+	*devp = NULL;
+	if (!ofnode_valid(node))
+		return -ENODEV;
+	ret = uclass_get(id, &uc);
+	if (ret)
+		return ret;
+
+	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
+		if (ofnode_equal(dev_ofnode(dev), node)) {
+			*devp = dev;
+			return 0;
+		}
+	}
+
+	return -ENODEV;
+}
+
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 static int uclass_find_device_by_phandle(enum uclass_id id,
 					 struct udevice *parent,
@@ -407,6 +432,18 @@ int uclass_get_device_by_of_offset(enum uclass_id id, int node,
 	return uclass_get_device_tail(dev, ret, devp);
 }
 
+int uclass_get_device_by_ofnode(enum uclass_id id, ofnode node,
+				struct udevice **devp)
+{
+	struct udevice *dev;
+	int ret;
+
+	*devp = NULL;
+	ret = uclass_find_device_by_ofnode(id, node, &dev);
+
+	return uclass_get_device_tail(dev, ret, devp);
+}
+
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent,
 				 const char *name, struct udevice **devp)
diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h
index ad284b8445..4474cef29e 100644
--- a/include/dm/uclass-internal.h
+++ b/include/dm/uclass-internal.h
@@ -114,6 +114,22 @@ int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
 int uclass_find_device_by_of_offset(enum uclass_id id, int node,
 				    struct udevice **devp);
 
+/**
+ * uclass_find_device_by_of_node() - Find a uclass device by device tree node
+ *
+ * This searches the devices in the uclass for one attached to the given
+ * device tree node.
+ *
+ * The device is NOT probed, it is merely returned.
+ *
+ * @id: ID to look up
+ * @node: Device tree offset to search for (if NULL then -ENODEV is returned)
+ * @devp: Returns pointer to device (there is only one for each node)
+ * @return 0 if OK, -ve on error
+ */
+int uclass_find_device_by_ofnode(enum uclass_id id, ofnode node,
+				 struct udevice **devp);
+
 /**
  * uclass_bind_device() - Associate device with a uclass
  *
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index b583aa869b..89d1f4467c 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -185,6 +185,22 @@ int uclass_get_device_by_seq(enum uclass_id id, int seq, struct udevice **devp);
 int uclass_get_device_by_of_offset(enum uclass_id id, int node,
 				   struct udevice **devp);
 
+/**
+ * uclass_get_device_by_ofnode() - Get a uclass device by device tree node
+ *
+ * This searches the devices in the uclass for one attached to the given
+ * device tree node.
+ *
+ * The device is probed to activate it ready for use.
+ *
+ * @id: ID to look up
+ * @np: Device tree node to search for (if NULL then -ENODEV is returned)
+ * @devp: Returns pointer to device (there is only one for each node)
+ * @return 0 if OK, -ve on error
+ */
+int uclass_get_device_by_ofnode(enum uclass_id id, ofnode node,
+				struct udevice **devp);
+
 /**
  * uclass_get_device_by_phandle() - Get a uclass device by phandle
  *
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 20/71] dm: regmap: Add support for livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (18 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 19/71] dm: core: Add a way to find a device by ofnode Simon Glass
@ 2017-05-10 14:20 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 21/71] dm: simple-bus: " Simon Glass
                   ` (50 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:20 UTC (permalink / raw)
  To: u-boot

Modify regmap to support livetree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/regmap.c | 37 ++++++++++++++++++++++---------------
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
index 7f21dee7e4..749d913372 100644
--- a/drivers/core/regmap.c
+++ b/drivers/core/regmap.c
@@ -12,8 +12,9 @@
 #include <malloc.h>
 #include <mapmem.h>
 #include <regmap.h>
-
 #include <asm/io.h>
+#include <dm/of_addr.h>
+#include <linux/ioport.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -62,25 +63,25 @@ int regmap_init_mem_platdata(struct udevice *dev, u32 *reg, int count,
 #else
 int regmap_init_mem(struct udevice *dev, struct regmap **mapp)
 {
-	const void *blob = gd->fdt_blob;
 	struct regmap_range *range;
-	const fdt32_t *cell;
 	struct regmap *map;
 	int count;
 	int addr_len, size_len, both_len;
-	int parent;
 	int len;
 	int index;
+	ofnode node = dev_ofnode(dev);
+	struct resource r;
 
-	parent = dev_of_offset(dev->parent);
-	addr_len = fdt_address_cells(blob, parent);
-	size_len = fdt_size_cells(blob, parent);
+	addr_len = dev_read_addr_cells(dev->parent);
+	size_len = dev_read_size_cells(dev->parent);
 	both_len = addr_len + size_len;
 
-	cell = fdt_getprop(blob, dev_of_offset(dev), "reg", &len);
-	len /= sizeof(*cell);
+	len = dev_read_size(dev, "reg");
+	if (len < 0)
+		return len;
+	len /= sizeof(fdt32_t);
 	count = len / both_len;
-	if (!cell || !count)
+	if (!count)
 		return -EINVAL;
 
 	map = regmap_alloc_count(count);
@@ -88,12 +89,18 @@ int regmap_init_mem(struct udevice *dev, struct regmap **mapp)
 		return -ENOMEM;
 
 	for (range = map->range, index = 0; count > 0;
-	     count--, cell += both_len, range++, index++) {
+	     count--, range++, index++) {
 		fdt_size_t sz;
-		range->start = fdtdec_get_addr_size_fixed(blob,
-				dev_of_offset(dev), "reg", index, addr_len,
-				size_len, &sz, true);
-		range->size = sz;
+		if (of_live_active()) {
+			of_address_to_resource(ofnode_to_np(node), index, &r);
+			range->start = r.start;
+			range->size = r.end - r.start + 1;
+		} else {
+			range->start = fdtdec_get_addr_size_fixed(gd->fdt_blob,
+					dev_of_offset(dev), "reg", index,
+					addr_len, size_len, &sz, true);
+			range->size = sz;
+		}
 	}
 	map->base = map->range[0].start;
 
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 21/71] dm: simple-bus: Add support for livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (19 preceding siblings ...)
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 20/71] dm: regmap: Add support for livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 22/71] dm: core: Update uclass_find_device_by_phandle() " Simon Glass
                   ` (49 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Modify simple-bus to support livetree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/simple-bus.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/core/simple-bus.c b/drivers/core/simple-bus.c
index a300217d39..14803e32b1 100644
--- a/drivers/core/simple-bus.c
+++ b/drivers/core/simple-bus.c
@@ -33,8 +33,7 @@ static int simple_bus_post_bind(struct udevice *dev)
 	u32 cell[3];
 	int ret;
 
-	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev), "ranges",
-				   cell, ARRAY_SIZE(cell));
+	ret = dev_read_u32_array(dev, "ranges", cell, ARRAY_SIZE(cell));
 	if (!ret) {
 		struct simple_bus_plat *plat = dev_get_uclass_platdata(dev);
 
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 22/71] dm: core: Update uclass_find_device_by_phandle() for livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (20 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 21/71] dm: simple-bus: " Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 23/71] sandbox: Add a way to reset sandbox state for tests Simon Glass
                   ` (48 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Adjust this function to work with livetree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/uclass.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 630b2e7336..21dc696da3 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -324,8 +324,7 @@ static int uclass_find_device_by_phandle(enum uclass_id id,
 	int ret;
 
 	*devp = NULL;
-	find_phandle = fdtdec_get_int(gd->fdt_blob, dev_of_offset(parent), name,
-				      -1);
+	find_phandle = dev_read_u32_default(parent, name, -1);
 	if (find_phandle <= 0)
 		return -ENOENT;
 	ret = uclass_get(id, &uc);
@@ -335,7 +334,7 @@ static int uclass_find_device_by_phandle(enum uclass_id id,
 	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
 		uint phandle;
 
-		phandle = fdt_get_phandle(gd->fdt_blob, dev_of_offset(dev));
+		phandle = dev_read_phandle(dev);
 
 		if (phandle == find_phandle) {
 			*devp = dev;
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 23/71] sandbox: Add a way to reset sandbox state for tests
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (21 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 22/71] dm: core: Update uclass_find_device_by_phandle() " Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 24/71] dm: test: Move test running code into a separate function Simon Glass
                   ` (47 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Running a new test should reset the sandbox state to avoid tests
interferring with each other. Move the existing state-reset code into a
function so it can be used from tests.

Also update the code to reset the SPI devices and adjust the test code to
call it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 arch/sandbox/cpu/state.c         | 14 ++++++++++----
 arch/sandbox/include/asm/state.h |  7 +++++++
 test/dm/test-main.c              |  1 +
 3 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index 2b4dbd341f..b58bf39cce 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -351,6 +351,15 @@ bool state_get_skip_delays(void)
 	return state->skip_delays;
 }
 
+void state_reset_for_test(struct sandbox_state *state)
+{
+	/* No reset yet, so mark it as such. Always allow power reset */
+	state->last_sysreset = SYSRESET_COUNT;
+	state->sysreset_allowed[SYSRESET_POWER] = true;
+
+	memset(state->spi, '\0', sizeof(state->spi));
+}
+
 int state_init(void)
 {
 	state = &main_state;
@@ -359,10 +368,7 @@ int state_init(void)
 	state->ram_buf = os_malloc(state->ram_size);
 	assert(state->ram_buf);
 
-	/* No reset yet, so mark it as such. Always allow power reset */
-	state->last_sysreset = SYSRESET_COUNT;
-	state->sysreset_allowed[SYSRESET_POWER] = true;
-
+	state_reset_for_test(state);
 	/*
 	 * Example of how to use GPIOs:
 	 *
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index 149f28d873..3fa8b01dfa 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -204,6 +204,13 @@ void state_set_skip_delays(bool skip_delays);
  */
 bool state_get_skip_delays(void);
 
+/**
+ * state_reset_for_test() - Reset ready to re-run tests
+ *
+ * This clears out any test state ready for another test run.
+ */
+void state_reset_for_test(struct sandbox_state *state);
+
 /**
  * Initialize the test system state
  */
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index 67c0082fb8..9aa9d3a953 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -29,6 +29,7 @@ static int dm_test_init(struct unit_test_state *uts)
 	memset(dms, '\0', sizeof(*dms));
 	gd->dm_root = NULL;
 	memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count));
+	state_reset_for_test(state_get_current());
 
 	ut_assertok(dm_init(false));
 	dms->root = dm_root();
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 24/71] dm: test: Move test running code into a separate function
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (22 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 23/71] sandbox: Add a way to reset sandbox state for tests Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 25/71] dm: test: Show the test filename when running Simon Glass
                   ` (46 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

We want to run the same test on flat and live trees. In preparation for
this, create a new function which handles running a test.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 test/dm/test-main.c | 56 ++++++++++++++++++++++++++++++-----------------------
 1 file changed, 32 insertions(+), 24 deletions(-)

diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index 9aa9d3a953..2848673e06 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -72,12 +72,42 @@ static int dm_test_destroy(struct unit_test_state *uts)
 	return 0;
 }
 
+static int dm_do_test(struct unit_test_state *uts, struct unit_test *test)
+{
+	struct sandbox_state *state = state_get_current();
+
+	printf("Test: %s\n", test->name);
+	ut_assertok(dm_test_init(uts));
+
+	uts->start = mallinfo();
+	if (test->flags & DM_TESTF_SCAN_PDATA)
+		ut_assertok(dm_scan_platdata(false));
+	if (test->flags & DM_TESTF_PROBE_TEST)
+		ut_assertok(do_autoprobe(uts));
+	if (test->flags & DM_TESTF_SCAN_FDT)
+		ut_assertok(dm_scan_fdt(gd->fdt_blob, false));
+
+	/*
+	 * Silence the console and rely on console reocrding to get
+	 * our output.
+	 */
+	console_record_reset();
+	if (!state->show_test_output)
+		gd->flags |= GD_FLG_SILENT;
+	test->func(uts);
+	gd->flags &= ~GD_FLG_SILENT;
+	state_set_skip_delays(false);
+
+	ut_assertok(dm_test_destroy(uts));
+
+	return 0;
+}
+
 static int dm_test_main(const char *test_name)
 {
 	struct unit_test *tests = ll_entry_start(struct unit_test, dm_test);
 	const int n_ents = ll_entry_count(struct unit_test, dm_test);
 	struct unit_test_state *uts = &global_dm_test_state;
-	struct sandbox_state *state = state_get_current();
 	uts->priv = &_global_priv_dm_test_state;
 	struct unit_test *test;
 	int run_count;
@@ -106,30 +136,8 @@ static int dm_test_main(const char *test_name)
 			name += 8;
 		if (test_name && strcmp(test_name, name))
 			continue;
-		printf("Test: %s\n", test->name);
+		ut_assertok(dm_do_test(uts, test));
 		run_count++;
-		ut_assertok(dm_test_init(uts));
-
-		uts->start = mallinfo();
-		if (test->flags & DM_TESTF_SCAN_PDATA)
-			ut_assertok(dm_scan_platdata(false));
-		if (test->flags & DM_TESTF_PROBE_TEST)
-			ut_assertok(do_autoprobe(uts));
-		if (test->flags & DM_TESTF_SCAN_FDT)
-			ut_assertok(dm_scan_fdt(gd->fdt_blob, false));
-
-		/*
-		 * Silence the console and rely on console reocrding to get
-		 * our output.
-		 */
-		console_record_reset();
-		if (!state->show_test_output)
-			gd->flags |= GD_FLG_SILENT;
-		test->func(uts);
-		gd->flags &= ~GD_FLG_SILENT;
-		state_set_skip_delays(false);
-
-		ut_assertok(dm_test_destroy(uts));
 	}
 
 	if (test_name && !run_count)
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 25/71] dm: test: Show the test filename when running
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (23 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 24/71] dm: test: Move test running code into a separate function Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 26/71] dm: test: Add support for running tests with livetree Simon Glass
                   ` (45 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Show the filename of the test being run. Skip the path and show just the
base name.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/test/test.h | 2 ++
 test/dm/test-main.c | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/test/test.h b/include/test/test.h
index b7e1ae2dec..e3e821c6ea 100644
--- a/include/test/test.h
+++ b/include/test/test.h
@@ -30,6 +30,7 @@ struct unit_test_state {
  * @flags: Flags indicated pre-conditions for test
  */
 struct unit_test {
+	const char *file;
 	const char *name;
 	int (*func)(struct unit_test_state *state);
 	int flags;
@@ -38,6 +39,7 @@ struct unit_test {
 /* Declare a new unit test */
 #define UNIT_TEST(_name, _flags, _suite)				\
 	ll_entry_declare(struct unit_test, _name, _suite) = {		\
+		.file = __FILE__,					\
 		.name = #_name,						\
 		.flags = _flags,					\
 		.func = _name,						\
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index 2848673e06..10d2706377 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -75,8 +75,9 @@ static int dm_test_destroy(struct unit_test_state *uts)
 static int dm_do_test(struct unit_test_state *uts, struct unit_test *test)
 {
 	struct sandbox_state *state = state_get_current();
+	const char *fname = strrchr(test->file, '/') + 1;
 
-	printf("Test: %s\n", test->name);
+	printf("Test: %s: %s\n", test->name, fname);
 	ut_assertok(dm_test_init(uts));
 
 	uts->start = mallinfo();
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 26/71] dm: test: Add support for running tests with livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (24 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 25/71] dm: test: Show the test filename when running Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 27/71] dm: core: Run tests with both livetree and flat tree Simon Glass
                   ` (44 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

It is useful to run the driver model tests with both livetree and flat
tree in case something is different between the two. Add this feature to
the test runner.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 test/dm/test-main.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index 10d2706377..88ef267458 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -22,7 +22,7 @@ struct unit_test_state global_dm_test_state;
 static struct dm_test_state _global_priv_dm_test_state;
 
 /* Get ready for testing */
-static int dm_test_init(struct unit_test_state *uts)
+static int dm_test_init(struct unit_test_state *uts, bool of_live)
 {
 	struct dm_test_state *dms = uts->priv;
 
@@ -31,7 +31,11 @@ static int dm_test_init(struct unit_test_state *uts)
 	memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count));
 	state_reset_for_test(state_get_current());
 
-	ut_assertok(dm_init(false));
+#ifdef CONFIG_OF_LIVE
+	/* Determine whether to make the live tree available */
+	gd->of_root = of_live ? uts->of_root : NULL;
+#endif
+	ut_assertok(dm_init(of_live));
 	dms->root = dm_root();
 
 	return 0;
@@ -72,13 +76,15 @@ static int dm_test_destroy(struct unit_test_state *uts)
 	return 0;
 }
 
-static int dm_do_test(struct unit_test_state *uts, struct unit_test *test)
+static int dm_do_test(struct unit_test_state *uts, struct unit_test *test,
+		      bool of_live)
 {
 	struct sandbox_state *state = state_get_current();
 	const char *fname = strrchr(test->file, '/') + 1;
 
-	printf("Test: %s: %s\n", test->name, fname);
-	ut_assertok(dm_test_init(uts));
+	printf("Test: %s: %s%s\n", test->name, fname,
+	       !of_live ? " (flat tree)" : "");
+	ut_assertok(dm_test_init(uts, of_live));
 
 	uts->start = mallinfo();
 	if (test->flags & DM_TESTF_SCAN_PDATA)
@@ -109,10 +115,10 @@ static int dm_test_main(const char *test_name)
 	struct unit_test *tests = ll_entry_start(struct unit_test, dm_test);
 	const int n_ents = ll_entry_count(struct unit_test, dm_test);
 	struct unit_test_state *uts = &global_dm_test_state;
-	uts->priv = &_global_priv_dm_test_state;
 	struct unit_test *test;
 	int run_count;
 
+	uts->priv = &_global_priv_dm_test_state;
 	uts->fail_count = 0;
 
 	/*
@@ -129,6 +135,9 @@ static int dm_test_main(const char *test_name)
 		printf("Running %d driver model tests\n", n_ents);
 
 	run_count = 0;
+#ifdef CONFIG_OF_LIVE
+	uts->of_root = gd->of_root;
+#endif
 	for (test = tests; test < tests + n_ents; test++) {
 		const char *name = test->name;
 
@@ -137,7 +146,7 @@ static int dm_test_main(const char *test_name)
 			name += 8;
 		if (test_name && strcmp(test_name, name))
 			continue;
-		ut_assertok(dm_do_test(uts, test));
+		ut_assertok(dm_do_test(uts, test, false));
 		run_count++;
 	}
 
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 27/71] dm: core: Run tests with both livetree and flat tree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (25 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 26/71] dm: test: Add support for running tests with livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 28/71] dm: gpio: Refactor to prepare for live tree support Simon Glass
                   ` (43 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Some tests require either livetree or flat tree. Add flags to allow the
tests to specify this. Adjust the test runner to run with livetree (if
supported) and then flat tree.

Some video tests are quite slow and running on flat tree adds little extra
test value, so run these on livetree only.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/dm/test.h   |  2 ++
 include/test/test.h |  2 ++
 test/dm/test-main.c | 38 ++++++++++++++++++++++++++++++++++++--
 3 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/include/dm/test.h b/include/dm/test.h
index cba504909a..cecee26f33 100644
--- a/include/dm/test.h
+++ b/include/dm/test.h
@@ -150,6 +150,8 @@ enum {
 	DM_TESTF_SCAN_PDATA	= 1 << 0,	/* test needs platform data */
 	DM_TESTF_PROBE_TEST	= 1 << 1,	/* probe test uclass */
 	DM_TESTF_SCAN_FDT	= 1 << 2,	/* scan device tree */
+	DM_TESTF_FLAT_TREE	= 1 << 3,	/* test needs flat DT */
+	DM_TESTF_LIVE_TREE	= 1 << 4,	/* needs live device tree */
 };
 
 /* Declare a new driver model test */
diff --git a/include/test/test.h b/include/test/test.h
index e3e821c6ea..646dbfd486 100644
--- a/include/test/test.h
+++ b/include/test/test.h
@@ -15,11 +15,13 @@
  * @fail_count: Number of tests that failed
  * @start: Store the starting mallinfo when doing leak test
  * @priv: A pointer to some other info some suites want to track
+ * @of_root: Record of the livetree root node (used for setting up tests)
  */
 struct unit_test_state {
 	int fail_count;
 	struct mallinfo start;
 	void *priv;
+	struct device_node *of_root;
 };
 
 /**
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index 88ef267458..9d88d31467 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -110,6 +110,21 @@ static int dm_do_test(struct unit_test_state *uts, struct unit_test *test,
 	return 0;
 }
 
+/**
+ * dm_test_run_on_flattree() - Check if we should run a test with flat DT
+ *
+ * This skips long/slow tests where there is not much value in running a flat
+ * DT test in addition to a live DT test.
+ *
+ * @return true to run the given test on the flat device tree
+ */
+static bool dm_test_run_on_flattree(struct unit_test *test)
+{
+	const char *fname = strrchr(test->file, '/') + 1;
+
+	return !strstr(fname, "video") || strstr(test->name, "video_base");
+}
+
 static int dm_test_main(const char *test_name)
 {
 	struct unit_test *tests = ll_entry_start(struct unit_test, dm_test);
@@ -140,14 +155,33 @@ static int dm_test_main(const char *test_name)
 #endif
 	for (test = tests; test < tests + n_ents; test++) {
 		const char *name = test->name;
+		int runs;
 
 		/* All tests have this prefix */
 		if (!strncmp(name, "dm_test_", 8))
 			name += 8;
 		if (test_name && strcmp(test_name, name))
 			continue;
-		ut_assertok(dm_do_test(uts, test, false));
-		run_count++;
+
+		/* Run with the live tree if possible */
+		runs = 0;
+		if (IS_ENABLED(CONFIG_OF_LIVE)) {
+			if (!(test->flags & DM_TESTF_FLAT_TREE)) {
+				ut_assertok(dm_do_test(uts, test, true));
+				runs++;
+			}
+		}
+
+		/*
+		 * Run with the flat tree if we couldn't run it with live tree,
+		 * or it is a core test.
+		 */
+		if (!(test->flags & DM_TESTF_LIVE_TREE) &&
+		    (!runs || dm_test_run_on_flattree(test))) {
+			ut_assertok(dm_do_test(uts, test, false));
+			runs++;
+		}
+		run_count += runs;
 	}
 
 	if (test_name && !run_count)
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 28/71] dm: gpio: Refactor to prepare for live tree support
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (26 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 27/71] dm: core: Run tests with both livetree and flat tree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 29/71] dm: gpio: Drop blank line in gpio_xlate_offs_flags() comment Simon Glass
                   ` (42 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Move the main part of the GPIO request function into a separate function
so that it can be used by the live tree function when added. Update the
xlate method to use a node reference.

Update all GPIO drivers to handle the modified xlate() method.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/gpio/74x164_gpio.c   |  2 +-
 drivers/gpio/gpio-uclass.c   | 51 ++++++++++++++++++++++++++------------------
 drivers/gpio/pca953x_gpio.c  |  2 +-
 drivers/gpio/sandbox.c       |  3 ++-
 drivers/gpio/sunxi_gpio.c    |  2 +-
 drivers/gpio/tegra186_gpio.c |  2 +-
 drivers/gpio/tegra_gpio.c    |  2 +-
 include/asm-generic/gpio.h   |  6 ++++--
 8 files changed, 41 insertions(+), 29 deletions(-)

diff --git a/drivers/gpio/74x164_gpio.c b/drivers/gpio/74x164_gpio.c
index 750eedfffd..ad69cb5a65 100644
--- a/drivers/gpio/74x164_gpio.c
+++ b/drivers/gpio/74x164_gpio.c
@@ -106,7 +106,7 @@ static int gen_74x164_get_function(struct udevice *dev, unsigned offset)
 }
 
 static int gen_74x164_xlate(struct udevice *dev, struct gpio_desc *desc,
-			    struct fdtdec_phandle_args *args)
+			    struct ofnode_phandle_args *args)
 {
 	desc->offset = args->args[0];
 	desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 9ab9df4ce7..b6a66b7e8b 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -114,9 +114,8 @@ int gpio_lookup_name(const char *name, struct udevice **devp,
 	return 0;
 }
 
-int gpio_xlate_offs_flags(struct udevice *dev,
-					 struct gpio_desc *desc,
-					 struct fdtdec_phandle_args *args)
+int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
+			  struct ofnode_phandle_args *args)
 {
 	if (args->args_count < 1)
 		return -EINVAL;
@@ -133,7 +132,7 @@ int gpio_xlate_offs_flags(struct udevice *dev,
 }
 
 static int gpio_find_and_xlate(struct gpio_desc *desc,
-			       struct fdtdec_phandle_args *args)
+			       struct ofnode_phandle_args *args)
 {
 	struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
 
@@ -642,37 +641,30 @@ int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count)
 	return vector;
 }
 
-static int _gpio_request_by_name_nodev(const void *blob, int node,
-				       const char *list_name, int index,
-				       struct gpio_desc *desc, int flags,
-				       bool add_index)
+static int gpio_request_tail(int ret, ofnode node,
+			     struct ofnode_phandle_args *args,
+			     const char *list_name, int index,
+			     struct gpio_desc *desc, int flags, bool add_index)
 {
-	struct fdtdec_phandle_args args;
-	int ret;
-
 	desc->dev = NULL;
 	desc->offset = 0;
 	desc->flags = 0;
-	ret = fdtdec_parse_phandle_with_args(blob, node, list_name,
-					     "#gpio-cells", 0, index, &args);
-	if (ret) {
-		debug("%s: fdtdec_parse_phandle_with_args failed\n", __func__);
+	if (ret)
 		goto err;
-	}
 
-	ret = uclass_get_device_by_of_offset(UCLASS_GPIO, args.node,
-					     &desc->dev);
+	ret = uclass_get_device_by_ofnode(UCLASS_GPIO, args->node,
+					  &desc->dev);
 	if (ret) {
 		debug("%s: uclass_get_device_by_of_offset failed\n", __func__);
 		goto err;
 	}
-	ret = gpio_find_and_xlate(desc, &args);
+	ret = gpio_find_and_xlate(desc, args);
 	if (ret) {
 		debug("%s: gpio_find_and_xlate failed\n", __func__);
 		goto err;
 	}
 	ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
-			       fdt_get_name(blob, node, NULL),
+			       ofnode_get_name(node),
 			       list_name, index);
 	if (ret) {
 		debug("%s: dm_gpio_requestf failed\n", __func__);
@@ -687,10 +679,27 @@ static int _gpio_request_by_name_nodev(const void *blob, int node,
 	return 0;
 err:
 	debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
-	      __func__, fdt_get_name(blob, node, NULL), list_name, index, ret);
+	      __func__, ofnode_get_name(node), list_name, index, ret);
 	return ret;
 }
 
+static int _gpio_request_by_name_nodev(const void *blob, int node,
+				       const char *list_name, int index,
+				       struct gpio_desc *desc, int flags,
+				       bool add_index)
+{
+	struct ofnode_phandle_args args;
+	int ret;
+
+	ret = ofnode_parse_phandle_with_args(offset_to_ofnode(node), list_name,
+					     "#gpio-cells", 0, index, &args);
+	if (ret)
+		debug("%s: fdtdec_parse_phandle_with_args failed\n", __func__);
+
+	return gpio_request_tail(ret, offset_to_ofnode(node), &args, list_name,
+				 index, desc, flags, add_index);
+}
+
 int gpio_request_by_name_nodev(const void *blob, int node,
 			       const char *list_name, int index,
 			       struct gpio_desc *desc, int flags)
diff --git a/drivers/gpio/pca953x_gpio.c b/drivers/gpio/pca953x_gpio.c
index b81f0fa90c..4962f25230 100644
--- a/drivers/gpio/pca953x_gpio.c
+++ b/drivers/gpio/pca953x_gpio.c
@@ -228,7 +228,7 @@ static int pca953x_get_function(struct udevice *dev, unsigned offset)
 }
 
 static int pca953x_xlate(struct udevice *dev, struct gpio_desc *desc,
-			 struct fdtdec_phandle_args *args)
+			 struct ofnode_phandle_args *args)
 {
 	desc->offset = args->args[0];
 	desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index ae6d93013f..0f22acb0e6 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -8,6 +8,7 @@
 #include <fdtdec.h>
 #include <malloc.h>
 #include <asm/gpio.h>
+#include <dm/of.h>
 #include <dt-bindings/gpio/gpio.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -165,7 +166,7 @@ static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
 }
 
 static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
-			 struct fdtdec_phandle_args *args)
+			 struct ofnode_phandle_args *args)
 {
 	desc->offset = args->args[0];
 	if (args->args_count < 2)
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index f0c9ea0794..b47cc66c58 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -217,7 +217,7 @@ static int sunxi_gpio_get_function(struct udevice *dev, unsigned offset)
 }
 
 static int sunxi_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
-			    struct fdtdec_phandle_args *args)
+			    struct ofnode_phandle_args *args)
 {
 	int ret;
 
diff --git a/drivers/gpio/tegra186_gpio.c b/drivers/gpio/tegra186_gpio.c
index cb2524e9bf..c5a7e13cce 100644
--- a/drivers/gpio/tegra186_gpio.c
+++ b/drivers/gpio/tegra186_gpio.c
@@ -139,7 +139,7 @@ static int tegra186_gpio_get_function(struct udevice *dev, unsigned offset)
 }
 
 static int tegra186_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
-			    struct fdtdec_phandle_args *args)
+			       struct ofnode_phandle_args *args)
 {
 	int gpio, port, ret;
 
diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
index fb79f7fa58..687cd74fee 100644
--- a/drivers/gpio/tegra_gpio.c
+++ b/drivers/gpio/tegra_gpio.c
@@ -236,7 +236,7 @@ static int tegra_gpio_get_function(struct udevice *dev, unsigned offset)
 }
 
 static int tegra_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
-			    struct fdtdec_phandle_args *args)
+			    struct ofnode_phandle_args *args)
 {
 	int gpio, port, ret;
 
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 4aa0004fab..b073b39138 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -7,6 +7,8 @@
 #ifndef _ASM_GENERIC_GPIO_H_
 #define _ASM_GENERIC_GPIO_H_
 
+struct ofnode_phandle_args;
+
 /*
  * Generic GPIO API for U-Boot
  *
@@ -214,7 +216,7 @@ struct fdtdec_phandle_args;
  *
  */
 int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
-			  struct fdtdec_phandle_args *args);
+			  struct ofnode_phandle_args *args);
 
 /**
  * struct struct dm_gpio_ops - Driver model GPIO operations
@@ -286,7 +288,7 @@ struct dm_gpio_ops {
 	 * @return 0 if OK, -ve on error
 	 */
 	int (*xlate)(struct udevice *dev, struct gpio_desc *desc,
-		     struct fdtdec_phandle_args *args);
+		     struct ofnode_phandle_args *args);
 };
 
 /**
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 29/71] dm: gpio: Drop blank line in gpio_xlate_offs_flags() comment
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (27 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 28/71] dm: gpio: Refactor to prepare for live tree support Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 30/71] dm: gpio: sandbox: Use dev_read...() functions to access DT Simon Glass
                   ` (41 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

This is not needed. Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/asm-generic/gpio.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index b073b39138..d78491dfc2 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -213,7 +213,6 @@ struct fdtdec_phandle_args;
  *
  * This routine sets the offset field to args[0] and the flags field to
  * GPIOD_ACTIVE_LOW if the GPIO_ACTIVE_LOW flag is present in args[1].
- *
  */
 int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
 			  struct ofnode_phandle_args *args);
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 30/71] dm: gpio: sandbox: Use dev_read...() functions to access DT
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (28 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 29/71] dm: gpio: Drop blank line in gpio_xlate_offs_flags() comment Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 31/71] dm: gpio: Add live tree support Simon Glass
                   ` (40 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Use the new dev_read...() functions to access the device tree, so that a
live tree can be used.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/gpio/sandbox.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index 0f22acb0e6..4f7b62eba0 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -198,10 +198,8 @@ static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev)
 {
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
-	uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-					     "num-gpios", 0);
-	uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
-					 "gpio-bank-name", NULL);
+	uc_priv->gpio_count = dev_read_u32_default(dev, "num-gpios", 0);
+	uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
 
 	return 0;
 }
@@ -210,10 +208,9 @@ static int gpio_sandbox_probe(struct udevice *dev)
 {
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
-	if (dev_of_offset(dev) == -1) {
+	if (!dev_of_valid(dev))
 		/* Tell the uclass how many GPIOs we have */
 		uc_priv->gpio_count = CONFIG_SANDBOX_GPIO_COUNT;
-	}
 
 	dev->priv = calloc(sizeof(struct gpio_state), uc_priv->gpio_count);
 
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 31/71] dm: gpio: Add live tree support
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (29 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 30/71] dm: gpio: sandbox: Use dev_read...() functions to access DT Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 32/71] cros_ec: Fix debug() statement in ec_command_inptr() Simon Glass
                   ` (39 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Add support for requesting GPIOs with a live device tree.

This involves adjusting the function signature for the legacy function
gpio_request_by_name_nodev(), so fix up all callers.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 board/qualcomm/dragonboard410c/dragonboard410c.c | 12 +++---
 board/samsung/common/board.c                     |  4 +-
 board/samsung/common/exynos5-dt.c                |  2 +-
 drivers/gpio/gpio-uclass.c                       | 51 +++++++++++-------------
 drivers/i2c/mxc_i2c.c                            | 12 +++---
 drivers/mmc/fsl_esdhc.c                          |  6 +--
 drivers/mmc/s5p_sdhci.c                          |  8 ++--
 drivers/mtd/nand/sunxi_nand.c                    |  2 +-
 drivers/mtd/nand/tegra_nand.c                    |  4 +-
 drivers/net/pic32_eth.c                          |  3 +-
 drivers/sound/max98095.c                         |  2 +
 drivers/sound/wm8994.c                           |  2 +-
 drivers/spi/pic32_spi.c                          |  2 +-
 drivers/usb/host/ehci-tegra.c                    |  7 ++--
 drivers/usb/host/ehci-vf.c                       |  5 ++-
 include/asm-generic/gpio.h                       | 10 ++---
 16 files changed, 65 insertions(+), 67 deletions(-)

diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c
index e923ddc2e2..37d0b85e0e 100644
--- a/board/qualcomm/dragonboard410c/dragonboard410c.c
+++ b/board/qualcomm/dragonboard410c/dragonboard410c.c
@@ -53,8 +53,8 @@ int board_prepare_usb(enum usb_init_type type)
 			printf("Failed to find usb_hub_reset_pm dt node.\n");
 			return node;
 		}
-		ret = gpio_request_by_name_nodev(gd->fdt_blob, node, "gpios", 0,
-						 &hub_reset, 0);
+		ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
+						 "gpios", 0, &hub_reset, 0);
 		if (ret < 0) {
 			printf("Failed to request usb_hub_reset_pm gpio.\n");
 			return ret;
@@ -69,8 +69,8 @@ int board_prepare_usb(enum usb_init_type type)
 			printf("Failed to find usb_sw_sel_pm dt node.\n");
 			return 0;
 		}
-		ret = gpio_request_by_name_nodev(gd->fdt_blob, node, "gpios", 0,
-						 &usb_sel, 0);
+		ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
+						 "gpios", 0, &usb_sel, 0);
 		if (ret < 0) {
 			printf("Failed to request usb_sw_sel_pm gpio.\n");
 			return ret;
@@ -121,8 +121,8 @@ int misc_init_r(void)
 		return 0;
 	}
 
-	if (gpio_request_by_name_nodev(gd->fdt_blob, node, "gpios", 0, &resin,
-				       0)) {
+	if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
+				       &resin, 0)) {
 		printf("Failed to request key_vol_down button.\n");
 		return 0;
 	}
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c
index 49e4db2de9..dda5ac6e43 100644
--- a/board/samsung/common/board.c
+++ b/board/samsung/common/board.c
@@ -351,8 +351,8 @@ void reset_misc(void)
 	if (node < 0)
 		return;
 
-	gpio_request_by_name_nodev(gd->fdt_blob, node, "reset-gpio", 0, &gpio,
-				   GPIOD_IS_OUT);
+	gpio_request_by_name_nodev(offset_to_ofnode(node), "reset-gpio", 0,
+				   &gpio, GPIOD_IS_OUT);
 
 	if (dm_gpio_is_valid(&gpio)) {
 		/*
diff --git a/board/samsung/common/exynos5-dt.c b/board/samsung/common/exynos5-dt.c
index aec1f396b0..44f412db5d 100644
--- a/board/samsung/common/exynos5-dt.c
+++ b/board/samsung/common/exynos5-dt.c
@@ -45,7 +45,7 @@ static void board_enable_audio_codec(void)
 	if (node <= 0)
 		return;
 
-	ret = gpio_request_by_name_nodev(gd->fdt_blob, node,
+	ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
 					 "codec-enable-gpio", 0, &en_gpio,
 					 GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
 	if (ret == -FDT_ERR_NOTFOUND)
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index b6a66b7e8b..12b4b660f6 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -683,45 +683,41 @@ err:
 	return ret;
 }
 
-static int _gpio_request_by_name_nodev(const void *blob, int node,
-				       const char *list_name, int index,
-				       struct gpio_desc *desc, int flags,
-				       bool add_index)
+static int _gpio_request_by_name_nodev(ofnode node, const char *list_name,
+				       int index, struct gpio_desc *desc,
+				       int flags, bool add_index)
 {
 	struct ofnode_phandle_args args;
 	int ret;
 
-	ret = ofnode_parse_phandle_with_args(offset_to_ofnode(node), list_name,
-					     "#gpio-cells", 0, index, &args);
-	if (ret)
-		debug("%s: fdtdec_parse_phandle_with_args failed\n", __func__);
+	ret = ofnode_parse_phandle_with_args(node, list_name, "#gpio-cells", 0,
+					     index, &args);
 
-	return gpio_request_tail(ret, offset_to_ofnode(node), &args, list_name,
-				 index, desc, flags, add_index);
+	return gpio_request_tail(ret, node, &args, list_name, index, desc,
+				 flags, add_index);
 }
 
-int gpio_request_by_name_nodev(const void *blob, int node,
-			       const char *list_name, int index,
+int gpio_request_by_name_nodev(ofnode node, const char *list_name, int index,
 			       struct gpio_desc *desc, int flags)
 {
-	return _gpio_request_by_name_nodev(blob, node, list_name, index, desc,
-					   flags, index > 0);
+	return _gpio_request_by_name_nodev(node, list_name, index, desc, flags,
+					   index > 0);
 }
 
-int gpio_request_by_name(struct udevice *dev,  const char *list_name, int index,
+int gpio_request_by_name(struct udevice *dev, const char *list_name, int index,
 			 struct gpio_desc *desc, int flags)
 {
-	/*
-	 * This isn't ideal since we don't use dev->name in the debug()
-	 * calls in gpio_request_by_name(), but we can do this until
-	 * gpio_request_by_name_nodev() can be dropped.
-	 */
-	return gpio_request_by_name_nodev(gd->fdt_blob, dev_of_offset(dev),
-					  list_name, index, desc, flags);
+	struct ofnode_phandle_args args;
+	int ret;
+
+	ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0,
+					 index, &args);
+
+	return gpio_request_tail(ret, dev_ofnode(dev), &args, list_name,
+				 index, desc, flags, index > 0);
 }
 
-int gpio_request_list_by_name_nodev(const void *blob, int node,
-				    const char *list_name,
+int gpio_request_list_by_name_nodev(ofnode node, const char *list_name,
 				    struct gpio_desc *desc, int max_count,
 				    int flags)
 {
@@ -729,7 +725,7 @@ int gpio_request_list_by_name_nodev(const void *blob, int node,
 	int ret;
 
 	for (count = 0; count < max_count; count++) {
-		ret = _gpio_request_by_name_nodev(blob, node, list_name, count,
+		ret = _gpio_request_by_name_nodev(node, list_name, count,
 						  &desc[count], flags, true);
 		if (ret == -ENOENT)
 			break;
@@ -755,9 +751,8 @@ int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
 	 * calls in gpio_request_by_name(), but we can do this until
 	 * gpio_request_list_by_name_nodev() can be dropped.
 	 */
-	return gpio_request_list_by_name_nodev(gd->fdt_blob, dev_of_offset(dev),
-					       list_name, desc, max_count,
-					       flags);
+	return gpio_request_list_by_name_nodev(dev_ofnode(dev), list_name, desc,
+					       max_count, flags);
 }
 
 int gpio_get_list_count(struct udevice *dev, const char *list_name)
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 6fc11e74aa..69b250b5ae 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -777,12 +777,12 @@ static int mxc_i2c_probe(struct udevice *bus)
 	if (ret < 0) {
 		debug("i2c bus %d@0x%2lx, no gpio pinctrl state.\n", bus->seq, i2c_bus->base);
 	} else {
-		ret = gpio_request_by_name_nodev(fdt, node, "scl-gpios",
-						 0, &i2c_bus->scl_gpio,
-						 GPIOD_IS_OUT);
-		ret2 = gpio_request_by_name_nodev(fdt, node, "sda-gpios",
-						 0, &i2c_bus->sda_gpio,
-						 GPIOD_IS_OUT);
+		ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
+				"scl-gpios", 0, &i2c_bus->scl_gpio,
+				GPIOD_IS_OUT);
+		ret2 = gpio_request_by_name_nodev(offset_to_ofnode(node),
+				"sda-gpios", 0, &i2c_bus->sda_gpio,
+				GPIOD_IS_OUT);
 		if (!dm_gpio_is_valid(&i2c_bus->sda_gpio) |
 		    !dm_gpio_is_valid(&i2c_bus->scl_gpio) |
 		    ret | ret2) {
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 3b3110f58b..5ee712f09b 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -983,15 +983,15 @@ static int fsl_esdhc_probe(struct udevice *dev)
 	 } else {
 		priv->non_removable = 0;
 #ifdef CONFIG_DM_GPIO
-		gpio_request_by_name_nodev(fdt, node, "cd-gpios", 0,
-					   &priv->cd_gpio, GPIOD_IS_IN);
+		gpio_request_by_name_nodev(offset_to_ofnode(node), "cd-gpios",
+					   0, &priv->cd_gpio, GPIOD_IS_IN);
 #endif
 	}
 
 	priv->wp_enable = 1;
 
 #ifdef CONFIG_DM_GPIO
-	ret = gpio_request_by_name_nodev(fdt, node, "wp-gpios", 0,
+	ret = gpio_request_by_name_nodev(offset_to_ofnode(node), "wp-gpios", 0,
 					 &priv->wp_gpio, GPIOD_IS_IN);
 	if (ret)
 		priv->wp_enable = 0;
diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c
index 640ea0261e..62817a0d07 100644
--- a/drivers/mmc/s5p_sdhci.c
+++ b/drivers/mmc/s5p_sdhci.c
@@ -184,10 +184,10 @@ static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host)
 	}
 	host->ioaddr = (void *)base;
 
-	gpio_request_by_name_nodev(blob, node, "pwr-gpios", 0, &host->pwr_gpio,
-				   GPIOD_IS_OUT);
-	gpio_request_by_name_nodev(blob, node, "cd-gpios", 0, &host->cd_gpio,
-				   GPIOD_IS_IN);
+	gpio_request_by_name_nodev(offset_to_ofnode(node), "pwr-gpios", 0,
+				   &host->pwr_gpio, GPIOD_IS_OUT);
+	gpio_request_by_name_nodev(offset_to_ofnode(node), "cd-gpios", 0,
+				   &host->cd_gpio, GPIOD_IS_IN);
 
 	return 0;
 }
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index c4e2cd7f55..8bc3828854 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -1663,7 +1663,7 @@ static int sunxi_nand_chip_init(int node, struct sunxi_nfc *nfc, int devnum)
 			chip->sels[i].rb.type = RB_NATIVE;
 			chip->sels[i].rb.info.nativeid = tmp;
 		} else {
-			ret = gpio_request_by_name_nodev(blob, node,
+			ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
 						"rb-gpios", i,
 						&chip->sels[i].rb.info.gpio,
 						GPIOD_IS_IN);
diff --git a/drivers/mtd/nand/tegra_nand.c b/drivers/mtd/nand/tegra_nand.c
index 5c9b485b08..c03c9cb178 100644
--- a/drivers/mtd/nand/tegra_nand.c
+++ b/drivers/mtd/nand/tegra_nand.c
@@ -894,8 +894,8 @@ static int fdt_decode_nand(const void *blob, int node, struct fdt_nand *config)
 	config->reg = (struct nand_ctlr *)fdtdec_get_addr(blob, node, "reg");
 	config->enabled = fdtdec_get_is_enabled(blob, node);
 	config->width = fdtdec_get_int(blob, node, "nvidia,nand-width", 8);
-	err = gpio_request_by_name_nodev(blob, node, "nvidia,wp-gpios", 0,
-				 &config->wp_gpio, GPIOD_IS_OUT);
+	err = gpio_request_by_name_nodev(offset_to_ofnode(node),
+			"nvidia,wp-gpios", 0, &config->wp_gpio, GPIOD_IS_OUT);
 	if (err)
 		return err;
 	err = fdtdec_get_int_array(blob, node, "nvidia,timing",
diff --git a/drivers/net/pic32_eth.c b/drivers/net/pic32_eth.c
index 385aad5b7e..0b89911f04 100644
--- a/drivers/net/pic32_eth.c
+++ b/drivers/net/pic32_eth.c
@@ -561,8 +561,7 @@ static int pic32_eth_probe(struct udevice *dev)
 		phy_addr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
 
 	/* phy reset gpio */
-	gpio_request_by_name_nodev(gd->fdt_blob, dev_of_offset(dev),
-				   "reset-gpios", 0,
+	gpio_request_by_name_nodev(dev_ofnode(dev), "reset-gpios", 0,
 				   &priv->rst_gpio, GPIOD_IS_OUT);
 
 	priv->phyif	= pdata->phy_interface;
diff --git a/drivers/sound/max98095.c b/drivers/sound/max98095.c
index 35829f88c9..7c37bd0701 100644
--- a/drivers/sound/max98095.c
+++ b/drivers/sound/max98095.c
@@ -9,6 +9,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
+#include <common.h>
 #include <asm/arch/clk.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/power.h>
diff --git a/drivers/sound/wm8994.c b/drivers/sound/wm8994.c
index d378442c50..b8208cdc87 100644
--- a/drivers/sound/wm8994.c
+++ b/drivers/sound/wm8994.c
@@ -4,11 +4,11 @@
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
+#include <common.h>
 #include <asm/arch/clk.h>
 #include <asm/arch/cpu.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
-#include <common.h>
 #include <div64.h>
 #include <fdtdec.h>
 #include <i2c.h>
diff --git a/drivers/spi/pic32_spi.c b/drivers/spi/pic32_spi.c
index 78d78bc54b..15266b048c 100644
--- a/drivers/spi/pic32_spi.c
+++ b/drivers/spi/pic32_spi.c
@@ -414,7 +414,7 @@ static int pic32_spi_probe(struct udevice *bus)
 	 * of the ongoing transfer. To avoid this sort of error we will drive
 	 * /CS manually by toggling cs-gpio pins.
 	 */
-	ret = gpio_request_by_name_nodev(gd->fdt_blob, node, "cs-gpios", 0,
+	ret = gpio_request_by_name_nodev(offset_to_ofnode(node), "cs-gpios", 0,
 					 &priv->cs_gpio, GPIOD_IS_OUT);
 	if (ret) {
 		printf("pic32-spi: error, cs-gpios not found\n");
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index da9e9440b7..7dc37f045d 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -728,9 +728,10 @@ static int fdt_decode_usb(struct udevice *dev, struct fdt_usb *config)
 		debug("%s: Missing/invalid peripheral ID\n", __func__);
 		return -EINVAL;
 	}
-	gpio_request_by_name_nodev(blob, node, "nvidia,vbus-gpio", 0,
-				   &config->vbus_gpio, GPIOD_IS_OUT);
-	gpio_request_by_name_nodev(blob, node, "nvidia,phy-reset-gpio", 0,
+	gpio_request_by_name_nodev(offset_to_ofnode(node), "nvidia,vbus-gpio",
+				   0, &config->vbus_gpio, GPIOD_IS_OUT);
+	gpio_request_by_name_nodev(offset_to_ofnode(node),
+				   "nvidia,phy-reset-gpio", 0,
 				   &config->phy_reset_gpio, GPIOD_IS_OUT);
 	debug("enabled=%d, legacy_mode=%d, utmi=%d, ulpi=%d, periph_id=%d, "
 		"vbus=%d, phy_reset=%d, dr_mode=%d\n",
diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index e52cd6ad32..d62c266599 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -252,8 +252,9 @@ static int vf_usb_ofdata_to_platdata(struct udevice *dev)
 	}
 
 	if (priv->dr_mode == DR_MODE_OTG) {
-		gpio_request_by_name_nodev(dt_blob, node, "fsl,cdet-gpio", 0,
-					   &priv->cdet_gpio, GPIOD_IS_IN);
+		gpio_request_by_name_nodev(offset_to_ofnode(node),
+				"fsl,cdet-gpio", 0, &priv->cdet_gpio,
+				GPIOD_IS_IN);
 		if (dm_gpio_is_valid(&priv->cdet_gpio)) {
 			if (dm_gpio_get_value(&priv->cdet_gpio))
 				priv->init_type = USB_INIT_DEVICE;
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index d78491dfc2..bf230c15ba 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -7,6 +7,8 @@
 #ifndef _ASM_GENERIC_GPIO_H_
 #define _ASM_GENERIC_GPIO_H_
 
+#include <dm/ofnode.h>
+
 struct ofnode_phandle_args;
 
 /*
@@ -488,9 +490,8 @@ int gpio_get_list_count(struct udevice *dev, const char *list_name);
  * This is a version of gpio_request_list_by_name() that does not use a
  * device. Avoid it unless the caller is not yet using driver model
  */
-int gpio_request_by_name_nodev(const void *blob, int node,
-			       const char *list_name,
-			       int index, struct gpio_desc *desc, int flags);
+int gpio_request_by_name_nodev(ofnode node, const char *list_name, int index,
+			       struct gpio_desc *desc, int flags);
 
 /**
  * gpio_request_list_by_name_nodev() - request GPIOs without a device
@@ -498,8 +499,7 @@ int gpio_request_by_name_nodev(const void *blob, int node,
  * This is a version of gpio_request_list_by_name() that does not use a
  * device. Avoid it unless the caller is not yet using driver model
  */
-int gpio_request_list_by_name_nodev(const void *blob, int node,
-				    const char *list_name,
+int gpio_request_list_by_name_nodev(ofnode node, const char *list_name,
 				    struct gpio_desc *desc_list, int max_count,
 				    int flags);
 
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 32/71] cros_ec: Fix debug() statement in ec_command_inptr()
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (30 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 31/71] dm: gpio: Add live tree support Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 33/71] cros_ec: Convert to support live tree Simon Glass
                   ` (38 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

This prints out the wrong pointers. Fix it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/misc/cros_ec.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c
index 3d449b2a55..e2027ea5d2 100644
--- a/drivers/misc/cros_ec.c
+++ b/drivers/misc/cros_ec.c
@@ -304,8 +304,7 @@ static int ec_command_inptr(struct cros_ec_dev *dev, uint8_t cmd,
 				NULL, 0, &din, din_len);
 	}
 
-	debug("%s: len=%d, dinp=%p, *dinp=%p\n", __func__, len, dinp,
-	      dinp ? *dinp : NULL);
+	debug("%s: len=%d, din=%p\n", __func__, len, din);
 	if (dinp) {
 		/* If we have any data to return, it must be 64bit-aligned */
 		assert(len <= 0 || !((uintptr_t)din & 7));
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 33/71] cros_ec: Convert to support live tree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (31 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 32/71] cros_ec: Fix debug() statement in ec_command_inptr() Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 34/71] sandbox: Add a new sandbox_flattree board Simon Glass
                   ` (37 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Convert this driver to support the live device tree and remove the old
fdtdec support.

The keyboard is not yet converted.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/misc/cros_ec.c         | 33 ++++++++++++++-------------------
 drivers/misc/cros_ec_sandbox.c | 23 +++++++++++------------
 include/cros_ec.h              |  7 ++-----
 include/fdtdec.h               | 13 -------------
 lib/fdtdec.c                   | 32 --------------------------------
 5 files changed, 27 insertions(+), 81 deletions(-)

diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c
index e2027ea5d2..feaa5d8567 100644
--- a/drivers/misc/cros_ec.c
+++ b/drivers/misc/cros_ec.c
@@ -26,6 +26,7 @@
 #include <asm/io.h>
 #include <asm-generic/gpio.h>
 #include <dm/device-internal.h>
+#include <dm/of_extra.h>
 #include <dm/uclass-internal.h>
 
 #ifdef DEBUG_TRACE
@@ -996,15 +997,12 @@ int cros_ec_get_ldo(struct udevice *dev, uint8_t index, uint8_t *state)
 int cros_ec_register(struct udevice *dev)
 {
 	struct cros_ec_dev *cdev = dev_get_uclass_priv(dev);
-	const void *blob = gd->fdt_blob;
-	int node = dev_of_offset(dev);
 	char id[MSG_BYTES];
 
 	cdev->dev = dev;
 	gpio_request_by_name(dev, "ec-interrupt", 0, &cdev->ec_int,
 			     GPIOD_IS_IN);
-	cdev->optimise_flash_write = fdtdec_get_bool(blob, node,
-						     "optimise-flash-write");
+	cdev->optimise_flash_write = dev_read_bool(dev, "optimise-flash-write");
 
 	if (cros_ec_check_version(cdev)) {
 		debug("%s: Could not detect CROS-EC version\n", __func__);
@@ -1023,28 +1021,26 @@ int cros_ec_register(struct udevice *dev)
 	return 0;
 }
 
-int cros_ec_decode_ec_flash(const void *blob, int node,
-			    struct fdt_cros_ec *config)
+int cros_ec_decode_ec_flash(struct udevice *dev, struct fdt_cros_ec *config)
 {
-	int flash_node;
+	ofnode flash_node, node;
 
-	flash_node = fdt_subnode_offset(blob, node, "flash");
-	if (flash_node < 0) {
+	flash_node = dev_read_subnode(dev, "flash");
+	if (!ofnode_valid(flash_node)) {
 		debug("Failed to find flash node\n");
 		return -1;
 	}
 
-	if (fdtdec_read_fmap_entry(blob, flash_node, "flash",
-				   &config->flash)) {
-		debug("Failed to decode flash node in chrome-ec'\n");
+	if (of_read_fmap_entry(flash_node, "flash", &config->flash)) {
+		debug("Failed to decode flash node in chrome-ec\n");
 		return -1;
 	}
 
-	config->flash_erase_value = fdtdec_get_int(blob, flash_node,
-						    "erase-value", -1);
-	for (node = fdt_first_subnode(blob, flash_node); node >= 0;
-	     node = fdt_next_subnode(blob, node)) {
-		const char *name = fdt_get_name(blob, node, NULL);
+	config->flash_erase_value = ofnode_read_s32_default(flash_node,
+							    "erase-value", -1);
+	for (node = ofnode_first_subnode(flash_node); ofnode_valid(node);
+	     node = ofnode_next_subnode(node)) {
+		const char *name = ofnode_get_name(node);
 		enum ec_flash_region region;
 
 		if (0 == strcmp(name, "ro")) {
@@ -1058,8 +1054,7 @@ int cros_ec_decode_ec_flash(const void *blob, int node,
 			return -1;
 		}
 
-		if (fdtdec_read_fmap_entry(blob, node, "reg",
-					   &config->region[region])) {
+		if (of_read_fmap_entry(node, "reg", &config->region[region])) {
 			debug("Failed to decode flash region in chrome-ec'\n");
 			return -1;
 		}
diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c
index 848c67bc23..c96e26e6b7 100644
--- a/drivers/misc/cros_ec_sandbox.c
+++ b/drivers/misc/cros_ec_sandbox.c
@@ -188,18 +188,16 @@ static int get_image_used(struct ec_state *ec, struct fmap_entry *entry)
  * RR=Row CC=Column KKKK=Key Code
  *
  * @param ec	Current emulated EC state
- * @param blob	Device tree blob containing keyscan information
  * @param node	Keyboard node of device tree containing keyscan information
  * @return 0 if ok, -1 on error
  */
-static int keyscan_read_fdt_matrix(struct ec_state *ec, const void *blob,
-				   int node)
+static int keyscan_read_fdt_matrix(struct ec_state *ec, ofnode node)
 {
 	const u32 *cell;
 	int upto;
 	int len;
 
-	cell = fdt_getprop(blob, node, "linux,keymap", &len);
+	cell = ofnode_read_prop(node, "linux,keymap", &len);
 	ec->matrix_count = len / 4;
 	ec->matrix = calloc(ec->matrix_count, sizeof(*ec->matrix));
 	if (!ec->matrix) {
@@ -516,28 +514,29 @@ int cros_ec_probe(struct udevice *dev)
 {
 	struct ec_state *ec = dev->priv;
 	struct cros_ec_dev *cdev = dev->uclass_priv;
-	const void *blob = gd->fdt_blob;
 	struct udevice *keyb_dev;
-	int node;
+	ofnode node;
 	int err;
 
 	memcpy(ec, &s_state, sizeof(*ec));
-	err = cros_ec_decode_ec_flash(blob, dev_of_offset(dev), &ec->ec_config);
-	if (err)
+	err = cros_ec_decode_ec_flash(dev, &ec->ec_config);
+	if (err) {
+		debug("%s: Cannot device EC flash\n", __func__);
 		return err;
+	}
 
-	node = -1;
+	node = ofnode_null();
 	for (device_find_first_child(dev, &keyb_dev);
 	     keyb_dev;
 	     device_find_next_child(&keyb_dev)) {
 		if (device_get_uclass_id(keyb_dev) == UCLASS_KEYBOARD) {
-			node = dev_of_offset(keyb_dev);
+			node = dev_ofnode(keyb_dev);
 			break;
 		}
 	}
-	if (node < 0) {
+	if (!ofnode_valid(node)) {
 		debug("%s: No cros_ec keyboard found\n", __func__);
-	} else if (keyscan_read_fdt_matrix(ec, blob, node)) {
+	} else if (keyscan_read_fdt_matrix(ec, node)) {
 		debug("%s: Could not read key matrix\n", __func__);
 		return -1;
 	}
diff --git a/include/cros_ec.h b/include/cros_ec.h
index 2bd9f2251f..771a176eea 100644
--- a/include/cros_ec.h
+++ b/include/cros_ec.h
@@ -11,7 +11,6 @@
 
 #include <linux/compiler.h>
 #include <ec_commands.h>
-#include <fdtdec.h>
 #include <cros_ec_message.h>
 #include <asm/gpio.h>
 #include <dm/of_extra.h>
@@ -378,12 +377,10 @@ int cros_ec_get_error(void);
 /**
  * Returns information from the FDT about the Chrome EC flash
  *
- * @param blob		FDT blob to use
- * @param node		Node offset to read from
+ * @param dev		Device to read from
  * @param config	Structure to use to return information
  */
-int cros_ec_decode_ec_flash(const void *blob, int node,
-			    struct fdt_cros_ec *config);
+int cros_ec_decode_ec_flash(struct udevice *dev, struct fdt_cros_ec *config);
 
 /**
  * Check the current keyboard state, in case recovery mode is requested.
diff --git a/include/fdtdec.h b/include/fdtdec.h
index bcdf9fa420..09d0d31865 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -815,19 +815,6 @@ const u8 *fdtdec_locate_byte_array(const void *blob, int node,
 int fdtdec_decode_region(const void *blob, int node, const char *prop_name,
 			 fdt_addr_t *basep, fdt_size_t *sizep);
 
-struct fmap_entry;
-/**
- * Read a flash entry from the fdt
- *
- * @param blob		FDT blob
- * @param node		Offset of node to read
- * @param name		Name of node being read
- * @param entry		Place to put offset and size of this node
- * @return 0 if ok, -ve on error
- */
-int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
-			   struct fmap_entry *entry);
-
 /**
  * Obtain an indexed resource from a device property.
  *
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 90b8946fa2..6ad25585ec 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -941,38 +941,6 @@ int fdtdec_decode_region(const void *blob, int node, const char *prop_name,
 	return 0;
 }
 
-/**
- * Read a flash entry from the fdt
- *
- * @param blob		FDT blob
- * @param node		Offset of node to read
- * @param name		Name of node being read
- * @param entry		Place to put offset and size of this node
- * @return 0 if ok, -ve on error
- */
-int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
-			   struct fmap_entry *entry)
-{
-	const char *prop;
-	u32 reg[2];
-
-	if (fdtdec_get_int_array(blob, node, "reg", reg, 2)) {
-		debug("Node '%s' has bad/missing 'reg' property\n", name);
-		return -FDT_ERR_NOTFOUND;
-	}
-	entry->offset = reg[0];
-	entry->length = reg[1];
-	entry->used = fdtdec_get_int(blob, node, "used", entry->length);
-	prop = fdt_getprop(blob, node, "compress", NULL);
-	entry->compress_algo = prop && !strcmp(prop, "lzo") ?
-		FMAP_COMPRESS_LZO : FMAP_COMPRESS_NONE;
-	prop = fdt_getprop(blob, node, "hash", &entry->hash_size);
-	entry->hash_algo = prop ? FMAP_HASH_SHA256 : FMAP_HASH_NONE;
-	entry->hash = (uint8_t *)prop;
-
-	return 0;
-}
-
 u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells)
 {
 	u64 number = 0;
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 34/71] sandbox: Add a new sandbox_flattree board
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (32 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 33/71] cros_ec: Convert to support live tree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 35/71] test: Update 'make test' to run more tests Simon Glass
                   ` (36 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Add a sandbox board to test the non-livetree build (i.e. with
CONFIG_OF_FLAT disabled). This increases our build and test coverage.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 board/sandbox/MAINTAINERS          |   7 ++
 configs/sandbox_flattree_defconfig | 179 +++++++++++++++++++++++++++++++++++++
 2 files changed, 186 insertions(+)
 create mode 100644 configs/sandbox_flattree_defconfig

diff --git a/board/sandbox/MAINTAINERS b/board/sandbox/MAINTAINERS
index 4dcbf4ba03..6d0790ccd1 100644
--- a/board/sandbox/MAINTAINERS
+++ b/board/sandbox/MAINTAINERS
@@ -18,3 +18,10 @@ S:	Maintained
 F:	board/sandbox/
 F:	include/configs/sandbox_spl.h
 F:	configs/sandbox_spl_defconfig
+
+SANDBOX FLAT TREE BOARD
+M:	Simon Glass <sjg@chromium.org>
+S:	Maintained
+F:	board/sandbox/
+F:	include/configs/sandbox.h
+F:	configs/sandbox_flattree_defconfig
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
new file mode 100644
index 0000000000..83efb23dbc
--- /dev/null
+++ b/configs/sandbox_flattree_defconfig
@@ -0,0 +1,179 @@
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DEFAULT_DEVICE_TREE="sandbox"
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_BOOTSTAGE=y
+CONFIG_BOOTSTAGE_REPORT=y
+CONFIG_BOOTSTAGE_USER_COUNT=0x20
+CONFIG_BOOTSTAGE_FDT=y
+CONFIG_BOOTSTAGE_STASH=y
+CONFIG_BOOTSTAGE_STASH_ADDR=0x0
+CONFIG_BOOTSTAGE_STASH_SIZE=0x4096
+CONFIG_CONSOLE_RECORD=y
+CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
+CONFIG_SILENT_CONSOLE=y
+CONFIG_CMD_CPU=y
+CONFIG_CMD_LICENSE=y
+CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_ASKENV=y
+CONFIG_CMD_GREPENV=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_LOOPW=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MX_CYCLIC=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_DEMO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_REMOTEPROC=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_TFTPPUT=y
+CONFIG_CMD_TFTPSRV=y
+CONFIG_CMD_RARP=y
+CONFIG_CMD_CDP=y
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_TIMER=y
+CONFIG_CMD_SOUND=y
+CONFIG_CMD_QFW=y
+CONFIG_CMD_BOOTSTAGE=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
+CONFIG_CMD_TPM_TEST=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_MAC_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_HOSTFILE=y
+CONFIG_NETCONSOLE=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_DEVRES=y
+CONFIG_DEBUG_DEVRES=y
+CONFIG_ADC=y
+CONFIG_ADC_SANDBOX=y
+CONFIG_CLK=y
+CONFIG_CPU=y
+CONFIG_DM_DEMO=y
+CONFIG_DM_DEMO_SIMPLE=y
+CONFIG_DM_DEMO_SHAPE=y
+CONFIG_PM8916_GPIO=y
+CONFIG_SANDBOX_GPIO=y
+CONFIG_DM_I2C_COMPAT=y
+CONFIG_I2C_CROS_EC_TUNNEL=y
+CONFIG_I2C_CROS_EC_LDO=y
+CONFIG_DM_I2C_GPIO=y
+CONFIG_SYS_I2C_SANDBOX=y
+CONFIG_I2C_MUX=y
+CONFIG_SPL_I2C_MUX=y
+CONFIG_I2C_ARB_GPIO_CHALLENGE=y
+CONFIG_CROS_EC_KEYB=y
+CONFIG_I8042_KEYB=y
+CONFIG_LED=y
+CONFIG_LED_BLINK=y
+CONFIG_LED_GPIO=y
+CONFIG_DM_MAILBOX=y
+CONFIG_SANDBOX_MBOX=y
+CONFIG_MISC=y
+CONFIG_CROS_EC=y
+CONFIG_CROS_EC_I2C=y
+CONFIG_CROS_EC_LPC=y
+CONFIG_CROS_EC_SANDBOX=y
+CONFIG_CROS_EC_SPI=y
+CONFIG_PWRSEQ=y
+CONFIG_SPL_PWRSEQ=y
+CONFIG_I2C_EEPROM=y
+CONFIG_MMC_SANDBOX=y
+CONFIG_SPI_FLASH_SANDBOX=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_ETH=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCI_SANDBOX=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_ROCKCHIP_RK3036=y
+CONFIG_PINCTRL_ROCKCHIP_RK3288=y
+CONFIG_PINCTRL_SANDBOX=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_SANDBOX_POWER_DOMAIN=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_ACT8846=y
+CONFIG_DM_PMIC_PFUZE100=y
+CONFIG_DM_PMIC_MAX77686=y
+CONFIG_PMIC_PM8916=y
+CONFIG_PMIC_RK808=y
+CONFIG_PMIC_S2MPS11=y
+CONFIG_DM_PMIC_SANDBOX=y
+CONFIG_PMIC_S5M8767=y
+CONFIG_PMIC_TPS65090=y
+CONFIG_DM_REGULATOR=y
+CONFIG_REGULATOR_ACT8846=y
+CONFIG_DM_REGULATOR_PFUZE100=y
+CONFIG_DM_REGULATOR_MAX77686=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_REGULATOR_RK808=y
+CONFIG_REGULATOR_S5M8767=y
+CONFIG_DM_REGULATOR_SANDBOX=y
+CONFIG_REGULATOR_TPS65090=y
+CONFIG_RAM=y
+CONFIG_REMOTEPROC_SANDBOX=y
+CONFIG_DM_RESET=y
+CONFIG_SANDBOX_RESET=y
+CONFIG_DM_RTC=y
+CONFIG_SANDBOX_SERIAL=y
+CONFIG_SOUND=y
+CONFIG_SOUND_SANDBOX=y
+CONFIG_SANDBOX_SPI=y
+CONFIG_SPMI=y
+CONFIG_SPMI_SANDBOX=y
+CONFIG_SYSRESET=y
+CONFIG_TIMER=y
+CONFIG_TIMER_EARLY=y
+CONFIG_SANDBOX_TIMER=y
+CONFIG_TPM_TIS_SANDBOX=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EMUL=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_SYS_USB_EVENT_POLL=y
+CONFIG_DM_VIDEO=y
+CONFIG_CONSOLE_ROTATION=y
+CONFIG_CONSOLE_TRUETYPE=y
+CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
+CONFIG_VIDEO_SANDBOX_SDL=y
+CONFIG_PHY=y
+CONFIG_PHY_SANDBOX=y
+CONFIG_CMD_DHRYSTONE=y
+CONFIG_TPM=y
+CONFIG_LZ4=y
+CONFIG_ERRNO_STR=y
+CONFIG_UNIT_TEST=y
+CONFIG_UT_TIME=y
+CONFIG_UT_DM=y
+CONFIG_UT_ENV=y
+CONFIG_DM_PWM=y
+CONFIG_PWM_SANDBOX=y
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 35/71] test: Update 'make test' to run more tests
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (33 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 34/71] sandbox: Add a new sandbox_flattree board Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 36/71] fdt: Rename a few functions in fdt_support Simon Glass
                   ` (35 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

The standard sandbox board cannot run the of-platdata test since it needs
SPL. Also, we should test the flat tree version of sandbox.

Add these tests to the default test script.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 test/run | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/test/run b/test/run
index a6dcf8f44f..b1649ee101 100755
--- a/test/run
+++ b/test/run
@@ -1,4 +1,10 @@
 #!/bin/sh
 
-# Run all tests
+# Run all tests that the standard sandbox build can support
 ./test/py/test.py --bd sandbox --build
+
+# Run tests which require sandbox_spl
+./test/py/test.py --bd sandbox_spl --build -k test/py/tests/test_ofplatdata.py
+
+# Run tests for the flat DT version of sandbox
+./test/py/test.py --bd sandbox_flattree --build
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 36/71] fdt: Rename a few functions in fdt_support
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (34 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 35/71] test: Update 'make test' to run more tests Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 37/71] dm: Add more livetree helpers and definitions Simon Glass
                   ` (34 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

These two functions have an of_ prefix which conflicts with naming used
in of_addr. Rename them:

   fdt_read_number
   fdt_support_bus_default_count_cells

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 arch/arm/cpu/armv8/fsl-layerscape/fdt.c    |  4 ++--
 arch/arm/mach-tegra/tegra186/nvtboot_mem.c |  4 ++--
 common/fdt_support.c                       | 26 +++++++++++++-------------
 drivers/core/ofnode.c                      |  4 ++--
 drivers/mtd/altera_qspi.c                  |  2 +-
 drivers/mtd/cfi_flash.c                    |  2 +-
 drivers/mtd/pic32_flash.c                  |  2 +-
 drivers/net/altera_tse.c                   |  2 +-
 include/fdt_support.h                      |  4 ++--
 9 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
index 05c4577753..f5f4840f19 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
@@ -79,13 +79,13 @@ remove_psci_node:
 		puts("couldn't find /cpus node\n");
 		return;
 	}
-	of_bus_default_count_cells(blob, off, &addr_cells, NULL);
+	fdt_support_default_count_cells(blob, off, &addr_cells, NULL);
 
 	off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
 	while (off != -FDT_ERR_NOTFOUND) {
 		reg = (fdt32_t *)fdt_getprop(blob, off, "reg", 0);
 		if (reg) {
-			core_id = of_read_number(reg, addr_cells);
+			core_id = fdt_read_number(reg, addr_cells);
 			if (core_id  == 0 || (is_core_online(core_id))) {
 				val = spin_tbl_addr;
 				val += id_to_core(core_id) *
diff --git a/arch/arm/mach-tegra/tegra186/nvtboot_mem.c b/arch/arm/mach-tegra/tegra186/nvtboot_mem.c
index bf1616628b..966cf9f1c4 100644
--- a/arch/arm/mach-tegra/tegra186/nvtboot_mem.c
+++ b/arch/arm/mach-tegra/tegra186/nvtboot_mem.c
@@ -60,9 +60,9 @@ int dram_init(void)
 
 	gd->ram_size = 0;
 	for (i = 0; i < len; i++) {
-		ram_banks[i].start = of_read_number(prop, na);
+		ram_banks[i].start = fdt_read_number(prop, na);
 		prop += na;
-		ram_banks[i].size = of_read_number(prop, ns);
+		ram_banks[i].size = fdt_read_number(prop, ns);
 		prop += ns;
 		gd->ram_size += ram_banks[i].size;
 	}
diff --git a/common/fdt_support.c b/common/fdt_support.c
index c63b27bbb6..dfdc04dfba 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -1008,7 +1008,7 @@ struct of_bus {
 };
 
 /* Default translator (generic bus) */
-void of_bus_default_count_cells(const void *blob, int parentoffset,
+void fdt_support_default_count_cells(const void *blob, int parentoffset,
 					int *addrc, int *sizec)
 {
 	const fdt32_t *prop;
@@ -1030,9 +1030,9 @@ static u64 of_bus_default_map(fdt32_t *addr, const fdt32_t *range,
 {
 	u64 cp, s, da;
 
-	cp = of_read_number(range, na);
-	s  = of_read_number(range + na + pna, ns);
-	da = of_read_number(addr, na);
+	cp = fdt_read_number(range, na);
+	s  = fdt_read_number(range + na + pna, ns);
+	da = fdt_read_number(addr, na);
 
 	debug("OF: default map, cp=%" PRIu64 ", s=%" PRIu64
 	      ", da=%" PRIu64 "\n", cp, s, da);
@@ -1044,7 +1044,7 @@ static u64 of_bus_default_map(fdt32_t *addr, const fdt32_t *range,
 
 static int of_bus_default_translate(fdt32_t *addr, u64 offset, int na)
 {
-	u64 a = of_read_number(addr, na);
+	u64 a = fdt_read_number(addr, na);
 	memset(addr, 0, na * 4);
 	a += offset;
 	if (na > 1)
@@ -1086,9 +1086,9 @@ static u64 of_bus_isa_map(fdt32_t *addr, const fdt32_t *range,
 	if ((addr[0] ^ range[0]) & cpu_to_be32(1))
 		return OF_BAD_ADDR;
 
-	cp = of_read_number(range + 1, na - 1);
-	s  = of_read_number(range + na + pna, ns);
-	da = of_read_number(addr + 1, na - 1);
+	cp = fdt_read_number(range + 1, na - 1);
+	s  = fdt_read_number(range + na + pna, ns);
+	da = fdt_read_number(addr + 1, na - 1);
 
 	debug("OF: ISA map, cp=%" PRIu64 ", s=%" PRIu64
 	      ", da=%" PRIu64 "\n", cp, s, da);
@@ -1122,7 +1122,7 @@ static struct of_bus of_busses[] = {
 	{
 		.name = "default",
 		.addresses = "reg",
-		.count_cells = of_bus_default_count_cells,
+		.count_cells = fdt_support_default_count_cells,
 		.map = of_bus_default_map,
 		.translate = of_bus_default_translate,
 	},
@@ -1173,7 +1173,7 @@ static int of_translate_one(const void *blob, int parent, struct of_bus *bus,
 	 */
 	ranges = fdt_getprop(blob, parent, rprop, &rlen);
 	if (ranges == NULL || rlen == 0) {
-		offset = of_read_number(addr, na);
+		offset = fdt_read_number(addr, na);
 		memset(addr, 0, pna * 4);
 		debug("OF: no ranges, 1:1 translation\n");
 		goto finish;
@@ -1253,7 +1253,7 @@ static u64 __of_translate_address(const void *blob, int node_offset,
 		/* If root, we have finished */
 		if (parent < 0) {
 			debug("OF: reached root node\n");
-			result = of_read_number(addr, na);
+			result = fdt_read_number(addr, na);
 			break;
 		}
 
@@ -1666,8 +1666,8 @@ int fdt_setup_simplefb_node(void *fdt, int node, u64 base_address, u32 width,
 	fdt32_t cells[4];
 	int i, addrc, sizec, ret;
 
-	of_bus_default_count_cells(fdt, fdt_parent_offset(fdt, node),
-				   &addrc, &sizec);
+	fdt_support_default_count_cells(fdt, fdt_parent_offset(fdt, node),
+					&addrc, &sizec);
 	i = 0;
 	if (addrc == 2)
 		cells[i++] = cpu_to_fdt32(base_address >> 32);
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index ac312d6546..6805fe2424 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -457,8 +457,8 @@ fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property,
 
 		na = of_n_addr_cells(np);
 		ns = of_n_addr_cells(np);
-		*sizep = of_read_number(prop + na, ns);
-		return of_read_number(prop, na);
+		*sizep = fdt_read_number(prop + na, ns);
+		return fdt_read_number(prop, na);
 	} else {
 		return fdtdec_get_addr_size(gd->fdt_blob,
 					    ofnode_to_offset(node), property,
diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c
index e04964b558..fb33cef13f 100644
--- a/drivers/mtd/altera_qspi.c
+++ b/drivers/mtd/altera_qspi.c
@@ -362,7 +362,7 @@ static int altera_qspi_ofdata_to_platdata(struct udevice *dev)
 	 * match with reg-names.
 	 */
 	parent = fdt_parent_offset(blob, node);
-	of_bus_default_count_cells(blob, parent, &addrc, &sizec);
+	fdt_support_default_count_cells(blob, parent, &addrc, &sizec);
 	list = fdt_getprop(blob, node, "reg-names", &len);
 	if (!list)
 		return -ENOENT;
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index d440f5ccd9..048a51785e 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -2448,7 +2448,7 @@ static int cfi_flash_probe(struct udevice *dev)
 	int len, idx;
 
 	parent = fdt_parent_offset(blob, node);
-	of_bus_default_count_cells(blob, parent, &addrc, &sizec);
+	fdt_support_default_count_cells(blob, parent, &addrc, &sizec);
 	/* decode regs, there may be multiple reg tuples. */
 	cell = fdt_getprop(blob, node, "reg", &len);
 	if (!cell)
diff --git a/drivers/mtd/pic32_flash.c b/drivers/mtd/pic32_flash.c
index 8ed7874cc9..e1a8d3bc4b 100644
--- a/drivers/mtd/pic32_flash.c
+++ b/drivers/mtd/pic32_flash.c
@@ -384,7 +384,7 @@ static int pic32_flash_probe(struct udevice *dev)
 	 * match with reg-names.
 	 */
 	parent = fdt_parent_offset(blob, node);
-	of_bus_default_count_cells(blob, parent, &addrc, &sizec);
+	fdt_support_default_count_cells(blob, parent, &addrc, &sizec);
 	list = fdt_getprop(blob, node, "reg-names", &len);
 	if (!list)
 		return -ENOENT;
diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c
index d4d17dd222..fb878d4e63 100644
--- a/drivers/net/altera_tse.c
+++ b/drivers/net/altera_tse.c
@@ -595,7 +595,7 @@ static int altera_tse_probe(struct udevice *dev)
 	 * match with reg-names.
 	 */
 	parent = fdt_parent_offset(blob, node);
-	of_bus_default_count_cells(blob, parent, &addrc, &sizec);
+	fdt_support_default_count_cells(blob, parent, &addrc, &sizec);
 	list = fdt_getprop(blob, node, "reg-names", &len);
 	if (!list)
 		return -ENOENT;
diff --git a/include/fdt_support.h b/include/fdt_support.h
index 6fea5c7da0..5ef78cce6e 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -248,7 +248,7 @@ static inline int fdt_status_fail_by_alias(void *fdt, const char *alias)
 }
 
 /* Helper to read a big number; size is in cells (not bytes) */
-static inline u64 of_read_number(const fdt32_t *cell, int size)
+static inline u64 fdt_read_number(const fdt32_t *cell, int size)
 {
 	u64 r = 0;
 	while (size--)
@@ -256,7 +256,7 @@ static inline u64 of_read_number(const fdt32_t *cell, int size)
 	return r;
 }
 
-void of_bus_default_count_cells(const void *blob, int parentoffset,
+void fdt_support_default_count_cells(const void *blob, int parentoffset,
 					int *addrc, int *sizec);
 int ft_verify_fdt(void *fdt);
 int arch_fixup_memory_node(void *blob);
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 37/71] dm: Add more livetree helpers and definitions
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (35 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 36/71] fdt: Rename a few functions in fdt_support Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 38/71] string: Add strchrnul() Simon Glass
                   ` (33 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Add some definitions and helpers for livetree in the main of.h header
file. These include:

- reading multi-cell integers
- default number of address/size cells
- functions for comparing names

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/ofnode.c |  4 ++--
 include/dm/of.h       | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index 6805fe2424..ac312d6546 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -457,8 +457,8 @@ fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property,
 
 		na = of_n_addr_cells(np);
 		ns = of_n_addr_cells(np);
-		*sizep = fdt_read_number(prop + na, ns);
-		return fdt_read_number(prop, na);
+		*sizep = of_read_number(prop + na, ns);
+		return of_read_number(prop, na);
 	} else {
 		return fdtdec_get_addr_size(gd->fdt_blob,
 					    ofnode_to_offset(node), property,
diff --git a/include/dm/of.h b/include/dm/of.h
index 102565018e..8a1f50bdc9 100644
--- a/include/dm/of.h
+++ b/include/dm/of.h
@@ -100,4 +100,40 @@ static inline bool of_live_active(void)
 }
 #endif
 
+#define OF_BAD_ADDR	((u64)-1)
+
+static inline const char *of_node_full_name(const struct device_node *np)
+{
+	return np ? np->full_name : "<no-node>";
+}
+
+/* Default #address and #size cells */
+#if !defined(OF_ROOT_NODE_ADDR_CELLS_DEFAULT)
+#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
+#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
+#endif
+
+/* Default string compare functions */
+#if !defined(of_compat_cmp)
+#define of_compat_cmp(s1, s2, l)	strcasecmp((s1), (s2))
+#define of_prop_cmp(s1, s2)		strcmp((s1), (s2))
+#define of_node_cmp(s1, s2)		strcasecmp((s1), (s2))
+#endif
+
+/* Helper to read a big number; size is in cells (not bytes) */
+static inline u64 of_read_number(const __be32 *cell, int size)
+{
+	u64 r = 0;
+	while (size--)
+		r = (r << 32) | be32_to_cpu(*(cell++));
+	return r;
+}
+
+/* Like of_read_number, but we want an unsigned long result */
+static inline unsigned long of_read_ulong(const __be32 *cell, int size)
+{
+	/* toss away upper bits if unsigned long is smaller than u64 */
+	return of_read_number(cell, size);
+}
+
 #endif
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 38/71] string: Add strchrnul()
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (36 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 37/71] dm: Add more livetree helpers and definitions Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 39/71] string: Add strcspn() Simon Glass
                   ` (32 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

This functions works like strchr() but returns the end of the string if
the character is not found. Add an implementation of this.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/linux/string.h | 13 +++++++++++++
 lib/string.c           |  8 ++++++++
 2 files changed, 21 insertions(+)

diff --git a/include/linux/string.h b/include/linux/string.h
index 091ccab395..718c3720a1 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -50,6 +50,19 @@ extern int strncasecmp(const char *s1, const char *s2, __kernel_size_t len);
 #ifndef __HAVE_ARCH_STRCHR
 extern char * strchr(const char *,int);
 #endif
+
+/**
+ * strchrnul() - return position of a character in the string, or end of string
+ *
+ * The strchrnul() function is like strchr() except that if c is not found
+ * in s, then it returns a pointer to the nul byte at the end of s, rather than
+ * NULL
+ * @s: string to search
+ * @c: character to search for
+ * @return position of @c in @s, or end of @s if not found
+ */
+const char *strchrnul(const char *s, int c);
+
 #ifndef __HAVE_ARCH_STRRCHR
 extern char * strrchr(const char *,int);
 #endif
diff --git a/lib/string.c b/lib/string.c
index c1a28c14ce..d1ff94dc64 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -230,6 +230,14 @@ char * strchr(const char * s, int c)
 }
 #endif
 
+const char *strchrnul(const char *s, int c)
+{
+	for (; *s != (char)c; ++s)
+		if (*s == '\0')
+			break;
+	return s;
+}
+
 #ifndef __HAVE_ARCH_STRRCHR
 /**
  * strrchr - Find the last occurrence of a character in a string
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 39/71] string: Add strcspn()
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (37 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 38/71] string: Add strchrnul() Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 40/71] dm: i2c: Convert uclass to livetree Simon Glass
                   ` (31 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Add an implementation of strcspn() which returns the number of initial
characters that do not match any in a rejection list.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/linux/string.h | 15 +++++++++++++++
 lib/string.c           | 24 ++++++++++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/include/linux/string.h b/include/linux/string.h
index 718c3720a1..3606620739 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -76,6 +76,21 @@ extern __kernel_size_t strlen(const char *);
 #ifndef __HAVE_ARCH_STRNLEN
 extern __kernel_size_t strnlen(const char *,__kernel_size_t);
 #endif
+
+#ifndef __HAVE_ARCH_STRCSPN
+/**
+ * strcspn() - find span of string without given characters
+ *
+ * Calculates the length of the initial segment of @s which consists entirely
+ * of bsytes not in reject.
+ *
+ * @s: string to search
+ * @reject: strings which cause the search to halt
+ * @return number of characters at the start of @s which are not in @reject
+ */
+size_t strcspn(const char *s, const char *reject);
+#endif
+
 #ifndef __HAVE_ARCH_STRDUP
 extern char * strdup(const char *);
 #endif
diff --git a/lib/string.c b/lib/string.c
index d1ff94dc64..8a8ebb90df 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -286,6 +286,30 @@ size_t strnlen(const char * s, size_t count)
 }
 #endif
 
+#ifndef __HAVE_ARCH_STRCSPN
+/**
+ * strcspn - Calculate the length of the initial substring of @s which does
+ * not contain letters in @reject
+ * @s: The string to be searched
+ * @reject: The string to avoid
+ */
+size_t strcspn(const char *s, const char *reject)
+{
+	const char *p;
+	const char *r;
+	size_t count = 0;
+
+	for (p = s; *p != '\0'; ++p) {
+		for (r = reject; *r != '\0'; ++r) {
+			if (*p == *r)
+				return count;
+		}
+		++count;
+	}
+	return count;
+}
+#endif
+
 #ifndef __HAVE_ARCH_STRDUP
 char * strdup(const char *s)
 {
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 40/71] dm: i2c: Convert uclass to livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (38 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 39/71] string: Add strcspn() Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 41/71] dm: pmic: " Simon Glass
                   ` (30 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the i2c uclass to support a live device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/i2c/i2c-uclass.c | 28 +++++++++++++---------------
 include/i2c.h            |  3 +--
 2 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index f3184c71d9..1397f34dda 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -7,7 +7,6 @@
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
-#include <fdtdec.h>
 #include <i2c.h>
 #include <malloc.h>
 #include <dm/device-internal.h>
@@ -467,18 +466,20 @@ int i2c_deblock(struct udevice *bus)
 }
 
 #if CONFIG_IS_ENABLED(OF_CONTROL)
-int i2c_chip_ofdata_to_platdata(const void *blob, int node,
-				struct dm_i2c_chip *chip)
+int i2c_chip_ofdata_to_platdata(struct udevice *dev, struct dm_i2c_chip *chip)
 {
-	chip->offset_len = fdtdec_get_int(gd->fdt_blob, node,
-					  "u-boot,i2c-offset-len", 1);
+	int addr;
+
+	chip->offset_len = dev_read_u32_default(dev, "u-boot,i2c-offset-len",
+						1);
 	chip->flags = 0;
-	chip->chip_addr = fdtdec_get_int(gd->fdt_blob, node, "reg", -1);
-	if (chip->chip_addr == -1) {
-		debug("%s: I2C Node '%s' has no 'reg' property\n", __func__,
-		      fdt_get_name(blob, node, NULL));
+	addr = dev_read_u32_default(dev, "reg", -1);
+	if (addr == -1) {
+		debug("%s: I2C Node '%s' has no 'reg' property %s\n", __func__,
+		      dev_read_name(dev), dev->name);
 		return -EINVAL;
 	}
+	chip->chip_addr = addr;
 
 	return 0;
 }
@@ -489,8 +490,7 @@ static int i2c_post_probe(struct udevice *dev)
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 	struct dm_i2c_bus *i2c = dev_get_uclass_priv(dev);
 
-	i2c->speed_hz = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-				     "clock-frequency", 100000);
+	i2c->speed_hz = dev_read_u32_default(dev, "clock-frequency", 100000);
 
 	return dm_i2c_set_bus_speed(dev, i2c->speed_hz);
 #else
@@ -503,11 +503,9 @@ static int i2c_child_post_bind(struct udevice *dev)
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 	struct dm_i2c_chip *plat = dev_get_parent_platdata(dev);
 
-	if (dev_of_offset(dev) == -1)
+	if (!dev_of_valid(dev))
 		return 0;
-
-	return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev_of_offset(dev),
-					   plat);
+	return i2c_chip_ofdata_to_platdata(dev, plat);
 #else
 	return 0;
 #endif
diff --git a/include/i2c.h b/include/i2c.h
index cd7f61e1c1..c93e95259a 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -525,8 +525,7 @@ int i2c_get_chip_for_busnum(int busnum, int chip_addr, uint offset_len,
  * @node:	Node offset to read from
  * @spi:	Place to put the decoded information
  */
-int i2c_chip_ofdata_to_platdata(const void *blob, int node,
-				struct dm_i2c_chip *chip);
+int i2c_chip_ofdata_to_platdata(struct udevice *dev, struct dm_i2c_chip *chip);
 
 /**
  * i2c_dump_msgs() - Dump a list of I2C messages
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 41/71] dm: pmic: Convert uclass to livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (39 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 40/71] dm: i2c: Convert uclass to livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 42/71] sandbox: pmic: Convert pmic emulator to support livetree Simon Glass
                   ` (29 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the pmic uclass and all pmics to support a live device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/power/pmic/act8846.c     |  8 +++-----
 drivers/power/pmic/lp873x.c      | 12 +++++-------
 drivers/power/pmic/max77686.c    |  8 +++-----
 drivers/power/pmic/palmas.c      | 16 +++++++---------
 drivers/power/pmic/pfuze100.c    |  8 +++-----
 drivers/power/pmic/pmic-uclass.c | 22 ++++++++++------------
 drivers/power/pmic/rk808.c       |  8 +++-----
 drivers/power/pmic/s5m8767.c     |  7 +++----
 drivers/power/pmic/sandbox.c     |  2 +-
 drivers/power/pmic/tps65090.c    |  8 +++-----
 include/power/pmic.h             |  2 +-
 11 files changed, 42 insertions(+), 59 deletions(-)

diff --git a/drivers/power/pmic/act8846.c b/drivers/power/pmic/act8846.c
index 15da12edea..a6b0940956 100644
--- a/drivers/power/pmic/act8846.c
+++ b/drivers/power/pmic/act8846.c
@@ -48,13 +48,11 @@ static int act8846_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 
 static int act8846_bind(struct udevice *dev)
 {
-	const void *blob = gd->fdt_blob;
-	int regulators_node;
+	ofnode regulators_node;
 	int children;
 
-	regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev),
-					     "regulators");
-	if (regulators_node <= 0) {
+	regulators_node = dev_read_subnode(dev, "regulators");
+	if (!ofnode_valid(regulators_node)) {
 		debug("%s: %s regulators subnode not found!", __func__,
 		      dev->name);
 		return -ENXIO;
diff --git a/drivers/power/pmic/lp873x.c b/drivers/power/pmic/lp873x.c
index d8f30df371..f505468313 100644
--- a/drivers/power/pmic/lp873x.c
+++ b/drivers/power/pmic/lp873x.c
@@ -46,15 +46,13 @@ static int lp873x_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 
 static int lp873x_bind(struct udevice *dev)
 {
-	int regulators_node;
-	const void *blob = gd->fdt_blob;
+	ofnode regulators_node;
 	int children;
-	int node = dev_of_offset(dev);
 
-	regulators_node = fdt_subnode_offset(blob, node, "regulators");
-
-	if (regulators_node <= 0) {
-		printf("%s: %s reg subnode not found!", __func__, dev->name);
+	regulators_node = dev_read_subnode(dev, "regulators");
+	if (!ofnode_valid(regulators_node)) {
+		debug("%s: %s regulators subnode not found!", __func__,
+		      dev->name);
 		return -ENXIO;
 	}
 
diff --git a/drivers/power/pmic/max77686.c b/drivers/power/pmic/max77686.c
index 8295fab3f0..ceca9f96a7 100644
--- a/drivers/power/pmic/max77686.c
+++ b/drivers/power/pmic/max77686.c
@@ -50,13 +50,11 @@ static int max77686_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 
 static int max77686_bind(struct udevice *dev)
 {
-	int regulators_node;
-	const void *blob = gd->fdt_blob;
+	ofnode regulators_node;
 	int children;
 
-	regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev),
-					     "voltage-regulators");
-	if (regulators_node <= 0) {
+	regulators_node = dev_read_subnode(dev, "voltage-regulators");
+	if (!ofnode_valid(regulators_node)) {
 		debug("%s: %s regulators subnode not found!", __func__,
 							     dev->name);
 		return -ENXIO;
diff --git a/drivers/power/pmic/palmas.c b/drivers/power/pmic/palmas.c
index f5a23073c4..804c0d13a0 100644
--- a/drivers/power/pmic/palmas.c
+++ b/drivers/power/pmic/palmas.c
@@ -46,17 +46,15 @@ static int palmas_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 
 static int palmas_bind(struct udevice *dev)
 {
-	int pmic_node = -1, regulators_node;
-	const void *blob = gd->fdt_blob;
+	ofnode pmic_node = ofnode_null(), regulators_node;
+	ofnode subnode;
 	int children;
-	int node = dev_of_offset(dev);
-	int subnode, len;
 
-	fdt_for_each_subnode(subnode, blob, node) {
+	dev_for_each_subnode(subnode, dev) {
 		const char *name;
 		char *temp;
 
-		name = fdt_get_name(blob, subnode, &len);
+		name = ofnode_get_name(subnode);
 		temp = strstr(name, "pmic");
 		if (temp) {
 			pmic_node = subnode;
@@ -64,14 +62,14 @@ static int palmas_bind(struct udevice *dev)
 		}
 	}
 
-	if (pmic_node <= 0) {
+	if (!ofnode_valid(pmic_node)) {
 		debug("%s: %s pmic subnode not found!", __func__, dev->name);
 		return -ENXIO;
 	}
 
-	regulators_node = fdt_subnode_offset(blob, pmic_node, "regulators");
+	regulators_node = ofnode_find_subnode(pmic_node, "regulators");
 
-	if (regulators_node <= 0) {
+	if (!ofnode_valid(regulators_node)) {
 		debug("%s: %s reg subnode not found!", __func__, dev->name);
 		return -ENXIO;
 	}
diff --git a/drivers/power/pmic/pfuze100.c b/drivers/power/pmic/pfuze100.c
index 90a43f2fe5..5f361c7696 100644
--- a/drivers/power/pmic/pfuze100.c
+++ b/drivers/power/pmic/pfuze100.c
@@ -52,13 +52,11 @@ static int pfuze100_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 
 static int pfuze100_bind(struct udevice *dev)
 {
+	ofnode regulators_node;
 	int children;
-	int regulators_node;
-	const void *blob = gd->fdt_blob;
 
-	regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev),
-					     "regulators");
-	if (regulators_node <= 0) {
+	regulators_node = dev_read_subnode(dev, "regulators");
+	if (!ofnode_valid(regulators_node)) {
 		debug("%s: %s regulators subnode not found!", __func__,
 		      dev->name);
 		return -ENXIO;
diff --git a/drivers/power/pmic/pmic-uclass.c b/drivers/power/pmic/pmic-uclass.c
index 0f7fa517f9..953bbe5026 100644
--- a/drivers/power/pmic/pmic-uclass.c
+++ b/drivers/power/pmic/pmic-uclass.c
@@ -19,29 +19,27 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
-int pmic_bind_children(struct udevice *pmic, int offset,
+int pmic_bind_children(struct udevice *pmic, ofnode parent,
 		       const struct pmic_child_info *child_info)
 {
 	const struct pmic_child_info *info;
-	const void *blob = gd->fdt_blob;
 	struct driver *drv;
 	struct udevice *child;
 	const char *node_name;
 	int bind_count = 0;
-	int node;
+	ofnode node;
 	int prefix_len;
 	int ret;
 
 	debug("%s for '%s' at node offset: %d\n", __func__, pmic->name,
 	      dev_of_offset(pmic));
 
-	for (node = fdt_first_subnode(blob, offset);
-	     node > 0;
-	     node = fdt_next_subnode(blob, node)) {
-		node_name = fdt_get_name(blob, node, NULL);
+	for (node = ofnode_first_subnode(parent);
+	     ofnode_valid(node);
+	     node = ofnode_next_subnode(node)) {
+		node_name = ofnode_get_name(node);
 
-		debug("* Found child node: '%s' at offset:%d\n", node_name,
-								 node);
+		debug("* Found child node: '%s'\n", node_name);
 
 		child = NULL;
 		for (info = child_info; info->prefix && info->driver; info++) {
@@ -60,8 +58,8 @@ int pmic_bind_children(struct udevice *pmic, int offset,
 
 			debug("  - found child driver: '%s'\n", drv->name);
 
-			ret = device_bind(pmic, drv, node_name, NULL,
-					  node, &child);
+			ret = device_bind_with_driver_data(pmic, drv, node_name,
+							   0, node, &child);
 			if (ret) {
 				debug("  - child binding error: %d\n", ret);
 				continue;
@@ -82,7 +80,7 @@ int pmic_bind_children(struct udevice *pmic, int offset,
 			debug("  - compatible prefix not found\n");
 	}
 
-	debug("Bound: %d childs for PMIC: '%s'\n", bind_count, pmic->name);
+	debug("Bound: %d children for PMIC: '%s'\n", bind_count, pmic->name);
 	return bind_count;
 }
 #endif
diff --git a/drivers/power/pmic/rk808.c b/drivers/power/pmic/rk808.c
index 3f5f316b56..f62d623cf3 100644
--- a/drivers/power/pmic/rk808.c
+++ b/drivers/power/pmic/rk808.c
@@ -57,13 +57,11 @@ static int rk808_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
 static int rk808_bind(struct udevice *dev)
 {
-	const void *blob = gd->fdt_blob;
-	int regulators_node;
+	ofnode regulators_node;
 	int children;
 
-	regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev),
-					     "regulators");
-	if (regulators_node <= 0) {
+	regulators_node = dev_read_subnode(dev, "regulators");
+	if (!ofnode_valid(regulators_node)) {
 		debug("%s: %s regulators subnode not found!", __func__,
 		      dev->name);
 		return -ENXIO;
diff --git a/drivers/power/pmic/s5m8767.c b/drivers/power/pmic/s5m8767.c
index 25d673b998..f8ae5ea2db 100644
--- a/drivers/power/pmic/s5m8767.c
+++ b/drivers/power/pmic/s5m8767.c
@@ -54,12 +54,11 @@ int s5m8767_enable_32khz_cp(struct udevice *dev)
 
 static int s5m8767_bind(struct udevice *dev)
 {
-	int node;
-	const void *blob = gd->fdt_blob;
 	int children;
+	ofnode node;
 
-	node = fdt_subnode_offset(blob, dev_of_offset(dev), "regulators");
-	if (node <= 0) {
+	node = dev_read_subnode(dev, "regulators");
+	if (!ofnode_valid(node)) {
 		debug("%s: %s regulators subnode not found!", __func__,
 		      dev->name);
 		return -ENXIO;
diff --git a/drivers/power/pmic/sandbox.c b/drivers/power/pmic/sandbox.c
index b4e412eb3e..6763303c66 100644
--- a/drivers/power/pmic/sandbox.c
+++ b/drivers/power/pmic/sandbox.c
@@ -51,7 +51,7 @@ static int sandbox_pmic_read(struct udevice *dev, uint reg,
 
 static int sandbox_pmic_bind(struct udevice *dev)
 {
-	if (!pmic_bind_children(dev, dev_of_offset(dev), pmic_children_info))
+	if (!pmic_bind_children(dev, dev_ofnode(dev), pmic_children_info))
 		error("%s:%d PMIC: %s - no child found!", __func__, __LINE__,
 							  dev->name);
 
diff --git a/drivers/power/pmic/tps65090.c b/drivers/power/pmic/tps65090.c
index b30a7f08e9..4565e3b54c 100644
--- a/drivers/power/pmic/tps65090.c
+++ b/drivers/power/pmic/tps65090.c
@@ -52,13 +52,11 @@ static int tps65090_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 
 static int tps65090_bind(struct udevice *dev)
 {
-	int regulators_node;
-	const void *blob = gd->fdt_blob;
+	ofnode regulators_node;
 	int children;
 
-	regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev),
-					     "regulators");
-	if (regulators_node <= 0) {
+	regulators_node = dev_read_subnode(dev, "regulators");
+	if (!ofnode_valid(regulators_node)) {
 		debug("%s: %s regulators subnode not found!", __func__,
 		      dev->name);
 		return -ENXIO;
diff --git a/include/power/pmic.h b/include/power/pmic.h
index e0b2e129dd..4b34316427 100644
--- a/include/power/pmic.h
+++ b/include/power/pmic.h
@@ -226,7 +226,7 @@ struct pmic_child_info {
  *     buck2 { ... };
  * };
  */
-int pmic_bind_children(struct udevice *pmic, int offset,
+int pmic_bind_children(struct udevice *pmic, ofnode parent,
 		       const struct pmic_child_info *child_info);
 
 /**
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 42/71] sandbox: pmic: Convert pmic emulator to support livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (40 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 41/71] dm: pmic: " Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 43/71] dm: regulator: Convert regulator uclass " Simon Glass
                   ` (28 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update this driver to support a live device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/power/pmic/i2c_pmic_emul.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/power/pmic/i2c_pmic_emul.c b/drivers/power/pmic/i2c_pmic_emul.c
index 4f92e3dad8..2d35d09d45 100644
--- a/drivers/power/pmic/i2c_pmic_emul.c
+++ b/drivers/power/pmic/i2c_pmic_emul.c
@@ -6,7 +6,6 @@
  */
 
 #include <common.h>
-#include <fdtdec.h>
 #include <errno.h>
 #include <dm.h>
 #include <i2c.h>
@@ -108,9 +107,8 @@ static int sandbox_i2c_pmic_ofdata_to_platdata(struct udevice *emul)
 
 	debug("%s:%d Setting PMIC default registers\n", __func__, __LINE__);
 
-	reg_defaults = fdtdec_locate_byte_array(gd->fdt_blob,
-			dev_of_offset(emul), "reg-defaults",
-			SANDBOX_PMIC_REG_COUNT);
+	reg_defaults = dev_read_u8_array_ptr(emul, "reg-defaults",
+					     SANDBOX_PMIC_REG_COUNT);
 
 	if (!reg_defaults) {
 		error("Property \"reg-defaults\" not found for device: %s!",
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 43/71] dm: regulator: Convert regulator uclass to support livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (41 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 42/71] sandbox: pmic: Convert pmic emulator to support livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 44/71] dm: regulator: Update fixed regulator " Simon Glass
                   ` (27 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the regulator uclass to support a live device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/power/regulator/regulator-uclass.c | 39 ++++++++++++------------------
 1 file changed, 16 insertions(+), 23 deletions(-)

diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c
index 2e0b5ed307..a42f80bb2b 100644
--- a/drivers/power/regulator/regulator-uclass.c
+++ b/drivers/power/regulator/regulator-uclass.c
@@ -4,8 +4,8 @@
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
+
 #include <common.h>
-#include <fdtdec.h>
 #include <errno.h>
 #include <dm.h>
 #include <dm/uclass-internal.h>
@@ -278,20 +278,16 @@ static bool regulator_name_is_unique(struct udevice *check_dev,
 static int regulator_post_bind(struct udevice *dev)
 {
 	struct dm_regulator_uclass_platdata *uc_pdata;
-	int offset = dev_of_offset(dev);
-	const void *blob = gd->fdt_blob;
 	const char *property = "regulator-name";
 
 	uc_pdata = dev_get_uclass_platdata(dev);
-	if (!uc_pdata)
-		return -ENXIO;
 
 	/* Regulator's mandatory constraint */
-	uc_pdata->name = fdt_getprop(blob, offset, property, NULL);
+	uc_pdata->name = dev_read_string(dev, property);
 	if (!uc_pdata->name) {
-		debug("%s: dev: %s has no property 'regulator-name'\n",
-		      __func__, dev->name);
-		uc_pdata->name = fdt_get_name(blob, offset, NULL);
+		debug("%s: dev '%s' has no property '%s'\n",
+		      __func__, dev->name, property);
+		uc_pdata->name = dev_read_name(dev);
 		if (!uc_pdata->name)
 			return -EINVAL;
 	}
@@ -299,7 +295,7 @@ static int regulator_post_bind(struct udevice *dev)
 	if (regulator_name_is_unique(dev, uc_pdata->name))
 		return 0;
 
-	debug("\"%s\" of dev: \"%s\", has nonunique value: \"%s\"",
+	debug("'%s' of dev: '%s', has nonunique value: '%s\n",
 	      property, dev->name, uc_pdata->name);
 
 	return -EINVAL;
@@ -308,25 +304,22 @@ static int regulator_post_bind(struct udevice *dev)
 static int regulator_pre_probe(struct udevice *dev)
 {
 	struct dm_regulator_uclass_platdata *uc_pdata;
-	int offset = dev_of_offset(dev);
 
 	uc_pdata = dev_get_uclass_platdata(dev);
 	if (!uc_pdata)
 		return -ENXIO;
 
 	/* Regulator's optional constraints */
-	uc_pdata->min_uV = fdtdec_get_int(gd->fdt_blob, offset,
-					  "regulator-min-microvolt", -ENODATA);
-	uc_pdata->max_uV = fdtdec_get_int(gd->fdt_blob, offset,
-					  "regulator-max-microvolt", -ENODATA);
-	uc_pdata->min_uA = fdtdec_get_int(gd->fdt_blob, offset,
-					  "regulator-min-microamp", -ENODATA);
-	uc_pdata->max_uA = fdtdec_get_int(gd->fdt_blob, offset,
-					  "regulator-max-microamp", -ENODATA);
-	uc_pdata->always_on = fdtdec_get_bool(gd->fdt_blob, offset,
-					      "regulator-always-on");
-	uc_pdata->boot_on = fdtdec_get_bool(gd->fdt_blob, offset,
-					    "regulator-boot-on");
+	uc_pdata->min_uV = dev_read_u32_default(dev, "regulator-min-microvolt",
+						-ENODATA);
+	uc_pdata->max_uV = dev_read_u32_default(dev, "regulator-max-microvolt",
+						-ENODATA);
+	uc_pdata->min_uA = dev_read_u32_default(dev, "regulator-min-microamp",
+						-ENODATA);
+	uc_pdata->max_uA = dev_read_u32_default(dev, "regulator-max-microamp",
+						-ENODATA);
+	uc_pdata->always_on = dev_read_bool(dev, "regulator-always-on");
+	uc_pdata->boot_on = dev_read_bool(dev, "regulator-boot-on");
 
 	/* Those values are optional (-ENODATA if unset) */
 	if ((uc_pdata->min_uV != -ENODATA) &&
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 44/71] dm: regulator: Update fixed regulator to support livetree.
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (42 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 43/71] dm: regulator: Convert regulator uclass " Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 45/71] dm: mmc: Convert uclass to livetree Simon Glass
                   ` (26 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update this driver to support a live device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/power/regulator/fixed.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/power/regulator/fixed.c b/drivers/power/regulator/fixed.c
index cd5213766d..656371b235 100644
--- a/drivers/power/regulator/fixed.c
+++ b/drivers/power/regulator/fixed.c
@@ -7,7 +7,6 @@
  */
 
 #include <common.h>
-#include <fdtdec.h>
 #include <errno.h>
 #include <dm.h>
 #include <i2c.h>
@@ -27,8 +26,7 @@ static int fixed_regulator_ofdata_to_platdata(struct udevice *dev)
 	struct dm_regulator_uclass_platdata *uc_pdata;
 	struct fixed_regulator_platdata *dev_pdata;
 	struct gpio_desc *gpio;
-	const void *blob = gd->fdt_blob;
-	int node = dev_of_offset(dev), flags = GPIOD_IS_OUT;
+	int flags = GPIOD_IS_OUT;
 	int ret;
 
 	dev_pdata = dev_get_platdata(dev);
@@ -39,7 +37,7 @@ static int fixed_regulator_ofdata_to_platdata(struct udevice *dev)
 	/* Set type to fixed */
 	uc_pdata->type = REGULATOR_TYPE_FIXED;
 
-	if (fdtdec_get_bool(blob, node, "enable-active-high"))
+	if (dev_read_bool(dev, "enable-active-high"))
 		flags |= GPIOD_IS_OUT_ACTIVE;
 
 	/* Get fixed regulator optional enable GPIO desc */
@@ -53,9 +51,8 @@ static int fixed_regulator_ofdata_to_platdata(struct udevice *dev)
 	}
 
 	/* Get optional ramp up delay */
-	dev_pdata->startup_delay_us = fdtdec_get_uint(gd->fdt_blob,
-						      dev_of_offset(dev),
-						      "startup-delay-us", 0);
+	dev_pdata->startup_delay_us = dev_read_u32_default(dev,
+							"startup-delay-us", 0);
 
 	return 0;
 }
@@ -108,8 +105,11 @@ static int fixed_regulator_set_enable(struct udevice *dev, bool enable)
 	struct fixed_regulator_platdata *dev_pdata = dev_get_platdata(dev);
 	int ret;
 
+	debug("%s: dev='%s', enable=%d, delay=%d, has_gpio=%d\n", __func__,
+	      dev->name, enable, dev_pdata->startup_delay_us,
+	      dm_gpio_is_valid(&dev_pdata->gpio));
 	/* Enable GPIO is optional */
-	if (!dev_pdata->gpio.dev) {
+	if (!dm_gpio_is_valid(&dev_pdata->gpio)) {
 		if (!enable)
 			return -ENOSYS;
 		return 0;
@@ -124,6 +124,7 @@ static int fixed_regulator_set_enable(struct udevice *dev, bool enable)
 
 	if (enable && dev_pdata->startup_delay_us)
 		udelay(dev_pdata->startup_delay_us);
+	debug("%s: done\n", __func__);
 
 	return 0;
 }
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 45/71] dm: mmc: Convert uclass to livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (43 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 44/71] dm: regulator: Update fixed regulator " Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 46/71] dm: adc: " Simon Glass
                   ` (25 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the mmc uclass to support a live device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/mmc/mmc-uclass.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 91f6fc5753..994d2686f4 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -204,7 +204,8 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
 #endif
 #ifndef CONFIG_SPL_BUILD
 	/* Use the fixed index with aliase node's index */
-	fdtdec_get_alias_seq(gd->fdt_blob, "mmc", dev_of_offset(dev), &devnum);
+	ret = dev_read_alias_seq(dev, &devnum);
+	debug("%s: alias ret=%d, devnum=%d\n", __func__, ret, devnum);
 #endif
 
 	ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC,
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 46/71] dm: adc: Convert uclass to livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (44 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 45/71] dm: mmc: Convert uclass to livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 47/71] dm: usb: " Simon Glass
                   ` (24 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the adc uclass to support a live device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/adc/adc-uclass.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/adc/adc-uclass.c b/drivers/adc/adc-uclass.c
index 3e28a5600b..a5ef722d21 100644
--- a/drivers/adc/adc-uclass.c
+++ b/drivers/adc/adc-uclass.c
@@ -345,12 +345,11 @@ nodev:
 static int adc_vdd_platdata_set(struct udevice *dev)
 {
 	struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
-	int ret, offset = dev_of_offset(dev);
-	const void *fdt = gd->fdt_blob;
+	int ret;
 	char *prop;
 
 	prop = "vdd-polarity-negative";
-	uc_pdata->vdd_polarity_negative = fdtdec_get_bool(fdt, offset, prop);
+	uc_pdata->vdd_polarity_negative = dev_read_bool(dev, prop);
 
 	ret = adc_vdd_platdata_update(dev);
 	if (ret != -ENOENT)
@@ -358,7 +357,7 @@ static int adc_vdd_platdata_set(struct udevice *dev)
 
 	/* No vdd-supply phandle. */
 	prop  = "vdd-microvolts";
-	uc_pdata->vdd_microvolts = fdtdec_get_int(fdt, offset, prop, -ENODATA);
+	uc_pdata->vdd_microvolts = dev_read_u32_default(dev, prop, -ENODATA);
 
 	return 0;
 }
@@ -366,12 +365,11 @@ static int adc_vdd_platdata_set(struct udevice *dev)
 static int adc_vss_platdata_set(struct udevice *dev)
 {
 	struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
-	int ret, offset = dev_of_offset(dev);
-	const void *fdt = gd->fdt_blob;
+	int ret;
 	char *prop;
 
 	prop = "vss-polarity-negative";
-	uc_pdata->vss_polarity_negative = fdtdec_get_bool(fdt, offset, prop);
+	uc_pdata->vss_polarity_negative = dev_read_bool(dev, prop);
 
 	ret = adc_vss_platdata_update(dev);
 	if (ret != -ENOENT)
@@ -379,7 +377,7 @@ static int adc_vss_platdata_set(struct udevice *dev)
 
 	/* No vss-supply phandle. */
 	prop = "vss-microvolts";
-	uc_pdata->vss_microvolts = fdtdec_get_int(fdt, offset, prop, -ENODATA);
+	uc_pdata->vss_microvolts = dev_read_u32_default(dev, prop, -ENODATA);
 
 	return 0;
 }
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 47/71] dm: usb: Convert uclass to livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (45 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 46/71] dm: adc: " Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 48/71] sandbox: usb: Convert emulators " Simon Glass
                   ` (23 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the usb uclass to support a live device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/usb-uclass.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 6eded4abad..110ddc92fa 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -683,20 +683,18 @@ int usb_detect_change(void)
 int usb_child_post_bind(struct udevice *dev)
 {
 	struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
-	const void *blob = gd->fdt_blob;
 	int val;
 
-	if (dev_of_offset(dev) == -1)
+	if (!dev_of_valid(dev))
 		return 0;
 
 	/* We only support matching a few things */
-	val = fdtdec_get_int(blob, dev_of_offset(dev), "usb,device-class", -1);
+	val = dev_read_u32_default(dev, "usb,device-class", -1);
 	if (val != -1) {
 		plat->id.match_flags |= USB_DEVICE_ID_MATCH_DEV_CLASS;
 		plat->id.bDeviceClass = val;
 	}
-	val = fdtdec_get_int(blob, dev_of_offset(dev), "usb,interface-class",
-			     -1);
+	val = dev_read_u32_default(dev, "usb,interface-class", -1);
 	if (val != -1) {
 		plat->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS;
 		plat->id.bInterfaceClass = val;
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 48/71] sandbox: usb: Convert emulators to livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (46 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 47/71] dm: usb: " Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 49/71] clk: Modify xlate() method for livetree Simon Glass
                   ` (22 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the sandbox flash and hub USB emulators to support a live device
tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/emul/sandbox_flash.c | 4 +---
 drivers/usb/emul/sandbox_hub.c   | 3 +--
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c
index 9abb323745..73fa82b8e6 100644
--- a/drivers/usb/emul/sandbox_flash.c
+++ b/drivers/usb/emul/sandbox_flash.c
@@ -371,10 +371,8 @@ err:
 static int sandbox_flash_ofdata_to_platdata(struct udevice *dev)
 {
 	struct sandbox_flash_plat *plat = dev_get_platdata(dev);
-	const void *blob = gd->fdt_blob;
 
-	plat->pathname = fdt_getprop(blob, dev_of_offset(dev),
-				     "sandbox,filepath", NULL);
+	plat->pathname = dev_read_string(dev, "sandbox,filepath");
 
 	return 0;
 }
diff --git a/drivers/usb/emul/sandbox_hub.c b/drivers/usb/emul/sandbox_hub.c
index f0939b19f4..9ffda9cc74 100644
--- a/drivers/usb/emul/sandbox_hub.c
+++ b/drivers/usb/emul/sandbox_hub.c
@@ -277,8 +277,7 @@ static int sandbox_child_post_bind(struct udevice *dev)
 {
 	struct sandbox_hub_platdata *plat = dev_get_parent_platdata(dev);
 
-	plat->port = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg",
-				    -1);
+	plat->port = dev_read_u32_default(dev, "reg", -1);
 
 	return 0;
 }
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 49/71] clk: Modify xlate() method for livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (47 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 48/71] sandbox: usb: Convert emulators " Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 50/71] dm: clk: Update uclass to support livetree Simon Glass
                   ` (21 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the xlate() method to use ofnode_phandle_args instead of the fdtdec
variant. This will allow drivers to support a live device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/clk/at91/pmc.c    | 2 +-
 drivers/clk/at91/pmc.h    | 2 +-
 drivers/clk/clk-uclass.c  | 7 ++++---
 drivers/clk/clk_stm32f7.c | 3 +--
 include/clk-uclass.h      | 5 +++--
 5 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index f4ec5fcb5e..be1d11ed4e 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -87,7 +87,7 @@ int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name)
 	return 0;
 }
 
-int at91_clk_of_xlate(struct clk *clk, struct fdtdec_phandle_args *args)
+int at91_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
 {
 	int periph;
 
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index f222fce11f..bd3caba48d 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -15,7 +15,7 @@ struct pmc_platdata {
 int at91_pmc_core_probe(struct udevice *dev);
 int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name);
 
-int at91_clk_of_xlate(struct clk *clk, struct fdtdec_phandle_args *args);
+int at91_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args);
 int at91_clk_probe(struct udevice *dev);
 
 #endif
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 6fcfd6997c..f6194b60f9 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -38,7 +38,7 @@ int clk_get_by_index_platdata(struct udevice *dev, int index,
 }
 # else
 static int clk_of_xlate_default(struct clk *clk,
-				struct fdtdec_phandle_args *args)
+				struct ofnode_phandle_args *args)
 {
 	debug("%s(clk=%p)\n", __func__, clk);
 
@@ -86,9 +86,10 @@ int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
 	ops = clk_dev_ops(dev_clk);
 
 	if (ops->of_xlate)
-		ret = ops->of_xlate(clk, &args);
+		ret = ops->of_xlate(clk, (struct ofnode_phandle_args *)&args);
 	else
-		ret = clk_of_xlate_default(clk, &args);
+		ret = clk_of_xlate_default(clk,
+					   (struct ofnode_phandle_args *)&args);
 	if (ret) {
 		debug("of_xlate() failed: %d\n", ret);
 		return ret;
diff --git a/drivers/clk/clk_stm32f7.c b/drivers/clk/clk_stm32f7.c
index 0d86395d47..ce11e4632e 100644
--- a/drivers/clk/clk_stm32f7.c
+++ b/drivers/clk/clk_stm32f7.c
@@ -291,8 +291,7 @@ static int stm32_clk_probe(struct udevice *dev)
 	return 0;
 }
 
-static int stm32_clk_of_xlate(struct clk *clk,
-			struct fdtdec_phandle_args *args)
+static int stm32_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
 {
 	debug("%s(clk=%p)\n", __func__, clk);
 
diff --git a/include/clk-uclass.h b/include/clk-uclass.h
index 07c1065495..e7ea334c60 100644
--- a/include/clk-uclass.h
+++ b/include/clk-uclass.h
@@ -12,7 +12,8 @@
 /* See clk.h for background documentation. */
 
 #include <clk.h>
-#include <fdtdec.h>
+
+struct ofnode_phandle_args;
 
 /**
  * struct clk_ops - The functions that a clock driver must implement.
@@ -37,7 +38,7 @@ struct clk_ops {
 	 * @return 0 if OK, or a negative error code.
 	 */
 	int (*of_xlate)(struct clk *clock,
-			struct fdtdec_phandle_args *args);
+			struct ofnode_phandle_args *args);
 	/**
 	 * request - Request a translated clock.
 	 *
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 50/71] dm: clk: Update uclass to support livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (48 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 49/71] clk: Modify xlate() method for livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 51/71] dm: clk: fixed: Update " Simon Glass
                   ` (20 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the clk uclass to support a live device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/clk/clk-uclass.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index f6194b60f9..83b63288fb 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -58,23 +58,22 @@ static int clk_of_xlate_default(struct clk *clk,
 int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
 {
 	int ret;
-	struct fdtdec_phandle_args args;
+	struct ofnode_phandle_args args;
 	struct udevice *dev_clk;
 	struct clk_ops *ops;
 
 	debug("%s(dev=%p, index=%d, clk=%p)\n", __func__, dev, index, clk);
 
 	assert(clk);
-	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
-					     "clocks", "#clock-cells", 0, index,
-					     &args);
+	ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0,
+					  index, &args);
 	if (ret) {
 		debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n",
 		      __func__, ret);
 		return ret;
 	}
 
-	ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev_clk);
+	ret = uclass_get_device_by_ofnode(UCLASS_CLK, args.node, &dev_clk);
 	if (ret) {
 		debug("%s: uclass_get_device_by_of_offset failed: err=%d\n",
 		      __func__, ret);
@@ -86,10 +85,9 @@ int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
 	ops = clk_dev_ops(dev_clk);
 
 	if (ops->of_xlate)
-		ret = ops->of_xlate(clk, (struct ofnode_phandle_args *)&args);
+		ret = ops->of_xlate(clk, &args);
 	else
-		ret = clk_of_xlate_default(clk,
-					   (struct ofnode_phandle_args *)&args);
+		ret = clk_of_xlate_default(clk, &args);
 	if (ret) {
 		debug("of_xlate() failed: %d\n", ret);
 		return ret;
@@ -105,8 +103,7 @@ int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
 
 	debug("%s(dev=%p, name=%s, clk=%p)\n", __func__, dev, name, clk);
 
-	index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
-				      "clock-names", name);
+	index = dev_read_stringlist_search(dev, "clock-names", name);
 	if (index < 0) {
 		debug("fdt_stringlist_search() failed: %d\n", index);
 		return index;
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 51/71] dm: clk: fixed: Update to support livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (49 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 50/71] dm: clk: Update uclass to support livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 52/71] dm: test: Separate out the bus DT offset test Simon Glass
                   ` (19 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the fixed-rate clock driver to support a live device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/clk/clk_fixed_rate.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/clk_fixed_rate.c b/drivers/clk/clk_fixed_rate.c
index 1cac4bbb85..63565b6ed8 100644
--- a/drivers/clk/clk_fixed_rate.c
+++ b/drivers/clk/clk_fixed_rate.c
@@ -31,9 +31,8 @@ const struct clk_ops clk_fixed_rate_ops = {
 static int clk_fixed_rate_ofdata_to_platdata(struct udevice *dev)
 {
 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
-	to_clk_fixed_rate(dev)->fixed_rate =
-				fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-					       "clock-frequency", 0);
+	to_clk_fixed_rate(dev)->fixed_rate = dev_read_u32_default(dev,
+							"clock-frequency", 0);
 #endif
 
 	return 0;
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 52/71] dm: test: Separate out the bus DT offset test
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (50 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 51/71] dm: clk: fixed: Update " Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 53/71] dm: test: Disable the fdt_offset test with livetree Simon Glass
                   ` (18 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

We cannot access the device tree via an offset when running in livetree
mode. Separate out that part of the bus' children tests and mark it as
for the flat tree only.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 test/dm/bus.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/test/dm/bus.c b/test/dm/bus.c
index 6a2773565e..8ba75d4b7d 100644
--- a/test/dm/bus.c
+++ b/test/dm/bus.c
@@ -160,8 +160,21 @@ static int dm_test_bus_children_funcs(struct unit_test_state *uts)
 	node = fdt_path_offset(blob, "/d-test");
 	ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev));
 
+	return 0;
+}
+DM_TEST(dm_test_bus_children_funcs, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+static int dm_test_bus_children_of_offset(struct unit_test_state *uts)
+{
+	const void *blob = gd->fdt_blob;
+	struct udevice *bus, *dev;
+	int node;
+
+	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
+
 	/* Find a valid child */
 	node = fdt_path_offset(blob, "/some-bus/c-test at 1");
+	ut_assert(node > 0);
 	ut_assertok(device_find_child_by_of_offset(bus, node, &dev));
 	ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
 	ut_assertok(device_get_child_by_of_offset(bus, node, &dev));
@@ -169,7 +182,8 @@ static int dm_test_bus_children_funcs(struct unit_test_state *uts)
 
 	return 0;
 }
-DM_TEST(dm_test_bus_children_funcs, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+DM_TEST(dm_test_bus_children_of_offset,
+	DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
 
 /* Test that we can iterate through children */
 static int dm_test_bus_children_iterators(struct unit_test_state *uts)
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 53/71] dm: test: Disable the fdt_offset test with livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (51 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 52/71] dm: test: Separate out the bus DT offset test Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 54/71] dm: phy: Update tests to use ut_asserteq() Simon Glass
                   ` (17 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

We cannot run this test with livetree since it uses device tree offsets.
Mark it as flat tree only.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 test/dm/test-fdt.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 3048a7b890..987a265ba9 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -265,4 +265,5 @@ static int dm_test_fdt_offset(struct unit_test_state *uts)
 
 	return 0;
 }
-DM_TEST(dm_test_fdt_offset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+DM_TEST(dm_test_fdt_offset,
+	DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 54/71] dm: phy: Update tests to use ut_asserteq()
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (52 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 53/71] dm: test: Disable the fdt_offset test with livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 55/71] dm: mailbox: Update uclass to support livetree Simon Glass
                   ` (16 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Use ut_asserteq() to test equality since this gives a better error message
on failure. Also make a few of the tests more specific.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 test/dm/phy.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/test/dm/phy.c b/test/dm/phy.c
index 811045fc0a..65b33fe68d 100644
--- a/test/dm/phy.c
+++ b/test/dm/phy.c
@@ -49,8 +49,8 @@ static int dm_test_phy_base(struct unit_test_state *uts)
 
 	/* Try to get a non-existing phy */
 	ut_asserteq(-ENODEV, uclass_get_device(UCLASS_PHY, 3, &dev));
-	ut_assert(generic_phy_get_by_name(parent, "phy_not_existing",
-					  &phy1_method1) < 0)
+	ut_asserteq(-ENODATA, generic_phy_get_by_name(parent,
+					"phy_not_existing", &phy1_method1));
 
 	return 0;
 }
@@ -68,8 +68,11 @@ static int dm_test_phy_ops(struct unit_test_state *uts)
 					      "gen_phy_user", &parent));
 
 	ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1));
+	ut_asserteq(0, phy1.id);
 	ut_assertok(generic_phy_get_by_name(parent, "phy2", &phy2));
+	ut_asserteq(1, phy2.id);
 	ut_assertok(generic_phy_get_by_name(parent, "phy3", &phy3));
+	ut_asserteq(0, phy3.id);
 
 	/* test normal operations */
 	ut_assertok(generic_phy_init(&phy1));
@@ -100,12 +103,12 @@ static int dm_test_phy_ops(struct unit_test_state *uts)
 	/* PHY2 has a known problem with power off */
 	ut_assertok(generic_phy_init(&phy2));
 	ut_assertok(generic_phy_power_on(&phy2));
-	ut_assert(generic_phy_power_off(&phy2) == -EIO);
+	ut_asserteq(-EIO, generic_phy_power_off(&phy2));
 
-	/* PHY3 has a known problem with power off and power on*/
+	/* PHY3 has a known problem with power off and power on */
 	ut_assertok(generic_phy_init(&phy3));
-	ut_assert(generic_phy_power_off(&phy3) == -EIO);
-	ut_assert(generic_phy_power_off(&phy3) == -EIO);
+	ut_asserteq(-EIO, generic_phy_power_off(&phy3));
+	ut_asserteq(-EIO, generic_phy_power_off(&phy3));
 
 	return 0;
 }
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 55/71] dm: mailbox: Update uclass to support livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (53 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 54/71] dm: phy: Update tests to use ut_asserteq() Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 56/71] dm: phy: " Simon Glass
                   ` (15 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the mailbox uclass to support livetree. Fix the xlate() method
in all callers.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/mailbox/mailbox-uclass.c | 20 ++++++++------------
 drivers/mailbox/tegra-hsp.c      |  2 +-
 include/mailbox-uclass.h         |  2 +-
 3 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/mailbox/mailbox-uclass.c b/drivers/mailbox/mailbox-uclass.c
index 38448de965..822ae5b45e 100644
--- a/drivers/mailbox/mailbox-uclass.c
+++ b/drivers/mailbox/mailbox-uclass.c
@@ -6,7 +6,6 @@
 
 #include <common.h>
 #include <dm.h>
-#include <fdtdec.h>
 #include <mailbox.h>
 #include <mailbox-uclass.h>
 
@@ -18,7 +17,7 @@ static inline struct mbox_ops *mbox_dev_ops(struct udevice *dev)
 }
 
 static int mbox_of_xlate_default(struct mbox_chan *chan,
-				 struct fdtdec_phandle_args *args)
+				 struct ofnode_phandle_args *args)
 {
 	debug("%s(chan=%p)\n", __func__, chan);
 
@@ -34,24 +33,22 @@ static int mbox_of_xlate_default(struct mbox_chan *chan,
 
 int mbox_get_by_index(struct udevice *dev, int index, struct mbox_chan *chan)
 {
-	struct fdtdec_phandle_args args;
+	struct ofnode_phandle_args args;
 	int ret;
 	struct udevice *dev_mbox;
 	struct mbox_ops *ops;
 
 	debug("%s(dev=%p, index=%d, chan=%p)\n", __func__, dev, index, chan);
 
-	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
-					     "mboxes", "#mbox-cells", 0,
-					     index, &args);
+	ret = dev_read_phandle_with_args(dev, "mboxes", "#mbox-cells", 0, index,
+					 &args);
 	if (ret) {
-		debug("%s: fdtdec_parse_phandle_with_args failed: %d\n",
-		      __func__, ret);
+		debug("%s: dev_read_phandle_with_args failed: %d\n", __func__,
+		      ret);
 		return ret;
 	}
 
-	ret = uclass_get_device_by_of_offset(UCLASS_MAILBOX, args.node,
-					     &dev_mbox);
+	ret = uclass_get_device_by_ofnode(UCLASS_MAILBOX, args.node, &dev_mbox);
 	if (ret) {
 		debug("%s: uclass_get_device_by_of_offset failed: %d\n",
 		      __func__, ret);
@@ -85,8 +82,7 @@ int mbox_get_by_name(struct udevice *dev, const char *name,
 
 	debug("%s(dev=%p, name=%s, chan=%p)\n", __func__, dev, name, chan);
 
-	index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
-				      "mbox-names", name);
+	index = dev_read_stringlist_search(dev, "mbox-names", name);
 	if (index < 0) {
 		debug("fdt_stringlist_search() failed: %d\n", index);
 		return index;
diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c
index b546ba2471..bd2ec411c7 100644
--- a/drivers/mailbox/tegra-hsp.c
+++ b/drivers/mailbox/tegra-hsp.c
@@ -72,7 +72,7 @@ static int tegra_hsp_db_id(ulong chan_id)
 }
 
 static int tegra_hsp_of_xlate(struct mbox_chan *chan,
-			      struct fdtdec_phandle_args *args)
+			      struct ofnode_phandle_args *args)
 {
 	debug("%s(chan=%p)\n", __func__, chan);
 
diff --git a/include/mailbox-uclass.h b/include/mailbox-uclass.h
index 6ec62e5a0e..8a638b04c5 100644
--- a/include/mailbox-uclass.h
+++ b/include/mailbox-uclass.h
@@ -36,7 +36,7 @@ struct mbox_ops {
 	 * @return 0 if OK, or a negative error code.
 	 */
 	int (*of_xlate)(struct mbox_chan *chan,
-			struct fdtdec_phandle_args *args);
+			struct ofnode_phandle_args *args);
 	/**
 	 * request - Request a translated channel.
 	 *
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 56/71] dm: phy: Update uclass to support livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (54 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 55/71] dm: mailbox: Update uclass to support livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 57/71] sandbox: phy: Update driver for livetree Simon Glass
                   ` (14 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the phy uclass to support livetree. Fix the xlate() method
which has no callers.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/phy/phy-uclass.c | 21 +++++++++------------
 include/generic-phy.h    |  3 +--
 2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c
index 0d8bef76db..d8b8d58e44 100644
--- a/drivers/phy/phy-uclass.c
+++ b/drivers/phy/phy-uclass.c
@@ -17,7 +17,7 @@ static inline struct phy_ops *phy_dev_ops(struct udevice *dev)
 }
 
 static int generic_phy_xlate_offs_flags(struct phy *phy,
-				 struct fdtdec_phandle_args *args)
+					struct ofnode_phandle_args *args)
 {
 	debug("%s(phy=%p)\n", __func__, phy);
 
@@ -31,14 +31,13 @@ static int generic_phy_xlate_offs_flags(struct phy *phy,
 	else
 		phy->id = 0;
 
-
 	return 0;
 }
 
 int generic_phy_get_by_index(struct udevice *dev, int index,
 			     struct phy *phy)
 {
-	struct fdtdec_phandle_args args;
+	struct ofnode_phandle_args args;
 	struct phy_ops *ops;
 	int ret;
 	struct udevice *phydev;
@@ -46,18 +45,17 @@ int generic_phy_get_by_index(struct udevice *dev, int index,
 	debug("%s(dev=%p, index=%d, phy=%p)\n", __func__, dev, index, phy);
 
 	assert(phy);
-	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
-					     "phys", "#phy-cells", 0, index,
-					     &args);
+	ret = dev_read_phandle_with_args(dev, "phys", "#phy-cells", 0, index,
+					 &args);
 	if (ret) {
-		debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n",
+		debug("%s: dev_read_phandle_with_args failed: err=%d\n",
 		      __func__, ret);
 		return ret;
 	}
 
-	ret = uclass_get_device_by_of_offset(UCLASS_PHY, args.node, &phydev);
+	ret = uclass_get_device_by_ofnode(UCLASS_PHY, args.node, &phydev);
 	if (ret) {
-		debug("%s: uclass_get_device_by_of_offset failed: err=%d\n",
+		debug("%s: uclass_get_device_by_ofnode failed: err=%d\n",
 		      __func__, ret);
 		return ret;
 	}
@@ -88,10 +86,9 @@ int generic_phy_get_by_name(struct udevice *dev, const char *phy_name,
 
 	debug("%s(dev=%p, name=%s, phy=%p)\n", __func__, dev, phy_name, phy);
 
-	index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
-				      "phy-names", phy_name);
+	index = dev_read_stringlist_search(dev, "phy-names", phy_name);
 	if (index < 0) {
-		debug("fdt_stringlist_search() failed: %d\n", index);
+		debug("dev_read_stringlist_search() failed: %d\n", index);
 		return index;
 	}
 
diff --git a/include/generic-phy.h b/include/generic-phy.h
index d8cf0c9f6a..762704c208 100644
--- a/include/generic-phy.h
+++ b/include/generic-phy.h
@@ -50,8 +50,7 @@ struct phy_ops {
 	 * @args:	The phy specifier values from device tree.
 	 * @return 0 if OK, or a negative error code.
 	 */
-	int	(*of_xlate)(struct phy *phy,
-			struct fdtdec_phandle_args *args);
+	int	(*of_xlate)(struct phy *phy, struct ofnode_phandle_args *args);
 
 	/**
 	 * init - initialize the hardware.
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 57/71] sandbox: phy: Update driver for livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (55 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 56/71] dm: phy: " Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 58/71] dm: power-domain: Update uclass to support livetree Simon Glass
                   ` (13 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the sandbox phy driver to support livetree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/phy/sandbox-phy.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/phy/sandbox-phy.c b/drivers/phy/sandbox-phy.c
index 9ad820c24c..867c6fe704 100644
--- a/drivers/phy/sandbox-phy.c
+++ b/drivers/phy/sandbox-phy.c
@@ -80,8 +80,7 @@ static int sandbox_phy_probe(struct udevice *dev)
 
 	priv->initialized = false;
 	priv->on = false;
-	priv->broken = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
-				       "broken");
+	priv->broken = dev_read_bool(dev, "broken");
 
 	return 0;
 }
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 58/71] dm: power-domain: Update uclass to support livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (56 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 57/71] sandbox: phy: Update driver for livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 59/71] dm: reset: " Simon Glass
                   ` (12 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the power domain uclass to support livetree. Fix the xlate() method
which has no callers.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/power/domain/power-domain-uclass.c | 19 ++++++++-----------
 include/power-domain-uclass.h              |  2 +-
 2 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/power/domain/power-domain-uclass.c b/drivers/power/domain/power-domain-uclass.c
index 3dabbe4ac0..1847a492a3 100644
--- a/drivers/power/domain/power-domain-uclass.c
+++ b/drivers/power/domain/power-domain-uclass.c
@@ -6,7 +6,6 @@
 
 #include <common.h>
 #include <dm.h>
-#include <fdtdec.h>
 #include <power-domain.h>
 #include <power-domain-uclass.h>
 
@@ -18,7 +17,7 @@ static inline struct power_domain_ops *power_domain_dev_ops(struct udevice *dev)
 }
 
 static int power_domain_of_xlate_default(struct power_domain *power_domain,
-				       struct fdtdec_phandle_args *args)
+					 struct ofnode_phandle_args *args)
 {
 	debug("%s(power_domain=%p)\n", __func__, power_domain);
 
@@ -34,27 +33,25 @@ static int power_domain_of_xlate_default(struct power_domain *power_domain,
 
 int power_domain_get(struct udevice *dev, struct power_domain *power_domain)
 {
-	struct fdtdec_phandle_args args;
+	struct ofnode_phandle_args args;
 	int ret;
 	struct udevice *dev_power_domain;
 	struct power_domain_ops *ops;
 
 	debug("%s(dev=%p, power_domain=%p)\n", __func__, dev, power_domain);
 
-	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
-					     "power-domains",
-					     "#power-domain-cells", 0, 0,
-					     &args);
+	ret = dev_read_phandle_with_args(dev, "power-domains",
+					 "#power-domain-cells", 0, 0, &args);
 	if (ret) {
-		debug("%s: fdtdec_parse_phandle_with_args failed: %d\n",
+		debug("%s: dev_read_phandle_with_args failed: %d\n",
 		      __func__, ret);
 		return ret;
 	}
 
-	ret = uclass_get_device_by_of_offset(UCLASS_POWER_DOMAIN, args.node,
-					     &dev_power_domain);
+	ret = uclass_get_device_by_ofnode(UCLASS_POWER_DOMAIN, args.node,
+					  &dev_power_domain);
 	if (ret) {
-		debug("%s: uclass_get_device_by_of_offset failed: %d\n",
+		debug("%s: uclass_get_device_by_ofnode failed: %d\n",
 		      __func__, ret);
 		return ret;
 	}
diff --git a/include/power-domain-uclass.h b/include/power-domain-uclass.h
index 5878021e32..802233d17f 100644
--- a/include/power-domain-uclass.h
+++ b/include/power-domain-uclass.h
@@ -40,7 +40,7 @@ struct power_domain_ops {
 	 * @return 0 if OK, or a negative error code.
 	 */
 	int (*of_xlate)(struct power_domain *power_domain,
-			struct fdtdec_phandle_args *args);
+			struct ofnode_phandle_args *args);
 	/**
 	 * request - Request a translated power domain.
 	 *
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 59/71] dm: reset: Update uclass to support livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (57 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 58/71] dm: power-domain: Update uclass to support livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 60/71] dm: pci: " Simon Glass
                   ` (11 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the reset domain uclass to support livetree. Fix the xlate() method
which has no callers.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/reset/reset-uclass.c | 21 ++++++++++-----------
 include/reset-uclass.h       |  4 ++--
 2 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c
index e92b24fa34..de3695ffaa 100644
--- a/drivers/reset/reset-uclass.c
+++ b/drivers/reset/reset-uclass.c
@@ -18,7 +18,7 @@ static inline struct reset_ops *reset_dev_ops(struct udevice *dev)
 }
 
 static int reset_of_xlate_default(struct reset_ctl *reset_ctl,
-				  struct fdtdec_phandle_args *args)
+				  struct ofnode_phandle_args *args)
 {
 	debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
 
@@ -35,7 +35,7 @@ static int reset_of_xlate_default(struct reset_ctl *reset_ctl,
 int reset_get_by_index(struct udevice *dev, int index,
 		       struct reset_ctl *reset_ctl)
 {
-	struct fdtdec_phandle_args args;
+	struct ofnode_phandle_args args;
 	int ret;
 	struct udevice *dev_reset;
 	struct reset_ops *ops;
@@ -43,20 +43,20 @@ int reset_get_by_index(struct udevice *dev, int index,
 	debug("%s(dev=%p, index=%d, reset_ctl=%p)\n", __func__, dev, index,
 	      reset_ctl);
 
-	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
-					     "resets", "#reset-cells", 0,
-					     index, &args);
+	ret = dev_read_phandle_with_args(dev, "resets", "#reset-cells", 0,
+					  index, &args);
 	if (ret) {
-		debug("%s: fdtdec_parse_phandle_with_args failed: %d\n",
+		debug("%s: fdtdec_parse_phandle_with_args() failed: %d\n",
 		      __func__, ret);
 		return ret;
 	}
 
-	ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node,
-					     &dev_reset);
+	ret = uclass_get_device_by_ofnode(UCLASS_RESET, args.node,
+					  &dev_reset);
 	if (ret) {
-		debug("%s: uclass_get_device_by_of_offset failed: %d\n",
+		debug("%s: uclass_get_device_by_ofnode() failed: %d\n",
 		      __func__, ret);
+		debug("%s %d\n", ofnode_get_name(args.node), args.args[0]);
 		return ret;
 	}
 	ops = reset_dev_ops(dev_reset);
@@ -88,8 +88,7 @@ int reset_get_by_name(struct udevice *dev, const char *name,
 	debug("%s(dev=%p, name=%s, reset_ctl=%p)\n", __func__, dev, name,
 	      reset_ctl);
 
-	index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
-				      "reset-names", name);
+	index = dev_read_stringlist_search(dev, "reset-names", name);
 	if (index < 0) {
 		debug("fdt_stringlist_search() failed: %d\n", index);
 		return index;
diff --git a/include/reset-uclass.h b/include/reset-uclass.h
index 38c716ff89..50fbeb10d6 100644
--- a/include/reset-uclass.h
+++ b/include/reset-uclass.h
@@ -11,7 +11,7 @@
 
 #include <reset.h>
 
-struct fdtdec_phandle_args;
+struct ofnode_phandle_args;
 struct udevice;
 
 /**
@@ -38,7 +38,7 @@ struct reset_ops {
 	 * @return 0 if OK, or a negative error code.
 	 */
 	int (*of_xlate)(struct reset_ctl *reset_ctl,
-			struct fdtdec_phandle_args *args);
+			struct ofnode_phandle_args *args);
 	/**
 	 * request - Request a translated reset control.
 	 *
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 60/71] dm: pci: Update uclass to support livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (58 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 59/71] dm: reset: " Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 61/71] dm: Update the I2C eeprom driver for livetree Simon Glass
                   ` (10 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the PCI uclass to support livetree. This mostly involves fixing
the address decoding from the device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/pci/pci-uclass.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 40f59c0c4c..9acc555601 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -8,12 +8,11 @@
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
-#include <fdtdec.h>
 #include <inttypes.h>
 #include <pci.h>
 #include <asm/io.h>
-#include <dm/lists.h>
 #include <dm/device-internal.h>
+#include <dm/lists.h>
 #if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
 #include <asm/fsp/fsp_support.h>
 #endif
@@ -753,8 +752,8 @@ error:
 	return ret;
 }
 
-static int decode_regions(struct pci_controller *hose, const void *blob,
-			  int parent_node, int node)
+static int decode_regions(struct pci_controller *hose, ofnode parent_node,
+			  ofnode node)
 {
 	int pci_addr_cells, addr_cells, size_cells;
 	phys_addr_t base = 0, size;
@@ -763,12 +762,12 @@ static int decode_regions(struct pci_controller *hose, const void *blob,
 	int len;
 	int i;
 
-	prop = fdt_getprop(blob, node, "ranges", &len);
+	prop = ofnode_read_prop(node, "ranges", &len);
 	if (!prop)
 		return -EINVAL;
-	pci_addr_cells = fdt_address_cells(blob, node);
-	addr_cells = fdt_address_cells(blob, parent_node);
-	size_cells = fdt_size_cells(blob, node);
+	pci_addr_cells = ofnode_read_addr_cells(node);
+	addr_cells = ofnode_read_addr_cells(parent_node);
+	size_cells = ofnode_read_size_cells(node);
 
 	/* PCI addresses are always 3-cells */
 	len /= sizeof(u32);
@@ -840,9 +839,8 @@ static int pci_uclass_pre_probe(struct udevice *bus)
 	/* For bridges, use the top-level PCI controller */
 	if (!device_is_on_pci_bus(bus)) {
 		hose->ctlr = bus;
-		ret = decode_regions(hose, gd->fdt_blob,
-				     dev_of_offset(bus->parent),
-				     dev_of_offset(bus));
+		ret = decode_regions(hose, dev_ofnode(bus->parent),
+				     dev_ofnode(bus));
 		if (ret) {
 			debug("%s: Cannot decode regions\n", __func__);
 			return ret;
@@ -905,7 +903,7 @@ static int pci_uclass_child_post_bind(struct udevice *dev)
 	struct fdt_pci_addr addr;
 	int ret;
 
-	if (dev_of_offset(dev) == -1)
+	if (!dev_of_valid(dev))
 		return 0;
 
 	/*
@@ -913,8 +911,8 @@ static int pci_uclass_child_post_bind(struct udevice *dev)
 	 * just check the address.
 	 */
 	pplat = dev_get_parent_platdata(dev);
-	ret = fdtdec_get_pci_addr(gd->fdt_blob, dev_of_offset(dev),
-				  FDT_PCI_SPACE_CONFIG, "reg", &addr);
+	ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG, "reg",
+				   &addr);
 
 	if (ret) {
 		if (ret != -ENOENT)
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 61/71] dm: Update the I2C eeprom driver for livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (59 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 60/71] dm: pci: " Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 62/71] cros_ec: Update the cros_ec keyboard driver to livetree Simon Glass
                   ` (9 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update this driver so that it works with livetree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/misc/i2c_eeprom_emul.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/misc/i2c_eeprom_emul.c b/drivers/misc/i2c_eeprom_emul.c
index 02de8d7df3..52aa7d69e9 100644
--- a/drivers/misc/i2c_eeprom_emul.c
+++ b/drivers/misc/i2c_eeprom_emul.c
@@ -9,7 +9,6 @@
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
-#include <fdtdec.h>
 #include <i2c.h>
 #include <malloc.h>
 #include <asm/test.h>
@@ -115,10 +114,8 @@ static int sandbox_i2c_eeprom_ofdata_to_platdata(struct udevice *dev)
 {
 	struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev);
 
-	plat->size = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-				    "sandbox,size", 32);
-	plat->filename = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
-				     "sandbox,filename", NULL);
+	plat->size = dev_read_u32_default(dev, "sandbox,size", 32);
+	plat->filename = dev_read_string(dev, "sandbox,filename");
 	if (!plat->filename) {
 		debug("%s: No filename for device '%s'\n", __func__,
 		      dev->name);
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 62/71] cros_ec: Update the cros_ec keyboard driver to livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (60 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 61/71] dm: Update the I2C eeprom driver for livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 63/71] dm: spi: Convert uclass " Simon Glass
                   ` (8 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update this driver and key_matrix to support a live device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/input/cros_ec_keyb.c | 24 ++++++++++++------------
 drivers/input/key_matrix.c   | 19 +++++++++----------
 drivers/input/tegra-kbc.c    |  3 +--
 include/key_matrix.h         |  3 +--
 4 files changed, 23 insertions(+), 26 deletions(-)

diff --git a/drivers/input/cros_ec_keyb.c b/drivers/input/cros_ec_keyb.c
index 00381dcd72..6fa35a63dd 100644
--- a/drivers/input/cros_ec_keyb.c
+++ b/drivers/input/cros_ec_keyb.c
@@ -10,7 +10,6 @@
 #include <cros_ec.h>
 #include <dm.h>
 #include <errno.h>
-#include <fdtdec.h>
 #include <input.h>
 #include <keyboard.h>
 #include <key_matrix.h>
@@ -161,15 +160,15 @@ int cros_ec_kbc_check(struct input_config *input)
  * @param config	Configuration data read from fdt
  * @return 0 if ok, -1 on error
  */
-static int cros_ec_keyb_decode_fdt(const void *blob, int node,
-				struct cros_ec_keyb_priv *config)
+static int cros_ec_keyb_decode_fdt(struct udevice *dev,
+				   struct cros_ec_keyb_priv *config)
 {
 	/*
 	 * Get keyboard rows and columns - at present we are limited to
 	 * 8 columns by the protocol (one byte per row scan)
 	 */
-	config->key_rows = fdtdec_get_int(blob, node, "keypad,num-rows", 0);
-	config->key_cols = fdtdec_get_int(blob, node, "keypad,num-columns", 0);
+	config->key_rows = dev_read_u32_default(dev, "keypad,num-rows", 0);
+	config->key_cols = dev_read_u32_default(dev, "keypad,num-columns", 0);
 	if (!config->key_rows || !config->key_cols ||
 			config->key_rows * config->key_cols / 8
 				> CROS_EC_KEYSCAN_COLS) {
@@ -177,8 +176,8 @@ static int cros_ec_keyb_decode_fdt(const void *blob, int node,
 		      config->key_rows, config->key_cols);
 		return -1;
 	}
-	config->ghost_filter = fdtdec_get_bool(blob, node,
-					       "google,needs-ghost-filter");
+	config->ghost_filter = dev_read_bool(dev, "google,needs-ghost-filter");
+
 	return 0;
 }
 
@@ -188,12 +187,13 @@ static int cros_ec_kbd_probe(struct udevice *dev)
 	struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct stdio_dev *sdev = &uc_priv->sdev;
 	struct input_config *input = &uc_priv->input;
-	const void *blob = gd->fdt_blob;
-	int node = dev_of_offset(dev);
 	int ret;
 
-	if (cros_ec_keyb_decode_fdt(blob, node, priv))
-		return -1;
+	ret = cros_ec_keyb_decode_fdt(dev, priv);
+	if (ret) {
+		debug("%s: Cannot decode node (ret=%d)\n", __func__, ret);
+		return -EINVAL;
+	}
 	input_set_delays(input, KBC_REPEAT_DELAY_MS, KBC_REPEAT_RATE_MS);
 	ret = key_matrix_init(&priv->matrix, priv->key_rows, priv->key_cols,
 			      priv->ghost_filter);
@@ -201,7 +201,7 @@ static int cros_ec_kbd_probe(struct udevice *dev)
 		debug("%s: cannot init key matrix\n", __func__);
 		return ret;
 	}
-	ret = key_matrix_decode_fdt(&priv->matrix, gd->fdt_blob, node);
+	ret = key_matrix_decode_fdt(dev, &priv->matrix);
 	if (ret) {
 		debug("%s: Could not decode key matrix from fdt\n", __func__);
 		return ret;
diff --git a/drivers/input/key_matrix.c b/drivers/input/key_matrix.c
index 8867e4964e..cd5bce3613 100644
--- a/drivers/input/key_matrix.c
+++ b/drivers/input/key_matrix.c
@@ -8,7 +8,7 @@
  */
 
 #include <common.h>
-#include <fdtdec.h>
+#include <dm.h>
 #include <key_matrix.h>
 #include <malloc.h>
 #include <linux/input.h>
@@ -105,7 +105,7 @@ int key_matrix_decode(struct key_matrix *config, struct key_matrix_key keys[],
  * @param pos           Returns position of map_keycode, if found, else -1
  * @return map  Pointer to allocated map
  */
-static uchar *create_keymap(struct key_matrix *config, u32 *data, int len,
+static uchar *create_keymap(struct key_matrix *config, const u32 *data, int len,
 			    int map_keycode, int *pos)
 {
 	uchar *map;
@@ -138,33 +138,32 @@ static uchar *create_keymap(struct key_matrix *config, u32 *data, int len,
 	return map;
 }
 
-int key_matrix_decode_fdt(struct key_matrix *config, const void *blob, int node)
+int key_matrix_decode_fdt(struct udevice *dev, struct key_matrix *config)
 {
-	const struct fdt_property *prop;
+	const u32 *prop;
 	int proplen;
 	uchar *plain_keycode;
 
-	prop = fdt_get_property(blob, node, "linux,keymap", &proplen);
+	prop = dev_read_prop(dev, "linux,keymap", &proplen);
 	/* Basic keymap is required */
 	if (!prop) {
 		debug("%s: cannot find keycode-plain map\n", __func__);
 		return -1;
 	}
 
-	plain_keycode = create_keymap(config, (u32 *)prop->data,
-		proplen, KEY_FN, &config->fn_pos);
+	plain_keycode = create_keymap(config, prop, proplen, KEY_FN,
+				      &config->fn_pos);
 	config->plain_keycode = plain_keycode;
 	/* Conversion error -> fail */
 	if (!config->plain_keycode)
 		return -1;
 
-	prop = fdt_get_property(blob, node, "linux,fn-keymap", &proplen);
+	prop = dev_read_prop(dev, "linux,fn-keymap", &proplen);
 	/* fn keymap is optional */
 	if (!prop)
 		goto done;
 
-	config->fn_keycode = create_keymap(config, (u32 *)prop->data,
-		proplen, -1, NULL);
+	config->fn_keycode = create_keymap(config, prop, proplen, -1, NULL);
 	/* Conversion error -> fail */
 	if (!config->fn_keycode) {
 		free(plain_keycode);
diff --git a/drivers/input/tegra-kbc.c b/drivers/input/tegra-kbc.c
index 836aba1f1b..cb5695784e 100644
--- a/drivers/input/tegra-kbc.c
+++ b/drivers/input/tegra-kbc.c
@@ -290,7 +290,6 @@ static int tegra_kbd_probe(struct udevice *dev)
 	struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct stdio_dev *sdev = &uc_priv->sdev;
 	struct input_config *input = &uc_priv->input;
-	int node = dev_of_offset(dev);
 	int ret;
 
 	priv->kbc = (struct kbc_tegra *)devfdt_get_addr(dev);
@@ -306,7 +305,7 @@ static int tegra_kbd_probe(struct udevice *dev)
 		debug("%s: Could not init key matrix: %d\n", __func__, ret);
 		return ret;
 	}
-	ret = key_matrix_decode_fdt(&priv->matrix, gd->fdt_blob, node);
+	ret = key_matrix_decode_fdt(dev, &priv->matrix);
 	if (ret) {
 		debug("%s: Could not decode key matrix from fdt: %d\n",
 		      __func__, ret);
diff --git a/include/key_matrix.h b/include/key_matrix.h
index 8db686040d..8dfa44de13 100644
--- a/include/key_matrix.h
+++ b/include/key_matrix.h
@@ -69,8 +69,7 @@ int key_matrix_decode(struct key_matrix *config, struct key_matrix_key *keys,
  * @param node          Node containing compatible data
  * @return 0 if ok, -1 on error
  */
-int key_matrix_decode_fdt(struct key_matrix *config, const void *blob,
-			  int node);
+int key_matrix_decode_fdt(struct udevice *dev, struct key_matrix *config);
 
 /**
  * Set up a new key matrix.
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 63/71] dm: spi: Convert uclass to livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (61 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 62/71] cros_ec: Update the cros_ec keyboard driver to livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 64/71] dm: sandbox: i2c: Drop fdtdec.h header Simon Glass
                   ` (7 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the SPI uclass to support a live device tree. Also adjust
spi_slave_ofdata_to_platdata() to accept a device instead of a blob and
offset.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/spi/spi-uclass.c | 31 ++++++++++++++-----------------
 include/spi.h            |  2 +-
 2 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index c061c05443..e06a603ab1 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -7,7 +7,6 @@
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
-#include <fdtdec.h>
 #include <malloc.h>
 #include <spi.h>
 #include <dm/device-internal.h>
@@ -113,11 +112,10 @@ static int spi_child_post_bind(struct udevice *dev)
 {
 	struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
 
-	if (dev_of_offset(dev) == -1)
+	if (!dev_of_valid(dev))
 		return 0;
 
-	return spi_slave_ofdata_to_platdata(gd->fdt_blob, dev_of_offset(dev),
-					    plat);
+	return spi_slave_ofdata_to_platdata(dev, plat);
 }
 #endif
 
@@ -126,8 +124,7 @@ static int spi_post_probe(struct udevice *bus)
 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
 	struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
 
-	spi->max_hz = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
-				     "spi-max-frequency", 0);
+	spi->max_hz = dev_read_u32_default(bus, "spi-max-frequency", 0);
 #endif
 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
 	struct dm_spi_ops *ops = spi_get_ops(bus);
@@ -375,7 +372,7 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
 	int ret;
 
 	ret = spi_get_bus_and_cs(busnum, cs, speed, mode, NULL, 0, &dev,
-				  &slave);
+				 &slave);
 	if (ret)
 		return NULL;
 
@@ -388,27 +385,27 @@ void spi_free_slave(struct spi_slave *slave)
 	slave->dev = NULL;
 }
 
-int spi_slave_ofdata_to_platdata(const void *blob, int node,
+int spi_slave_ofdata_to_platdata(struct udevice *dev,
 				 struct dm_spi_slave_platdata *plat)
 {
 	int mode = 0;
 	int value;
 
-	plat->cs = fdtdec_get_int(blob, node, "reg", -1);
-	plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 0);
-	if (fdtdec_get_bool(blob, node, "spi-cpol"))
+	plat->cs = dev_read_u32_default(dev, "reg", -1);
+	plat->max_hz = dev_read_u32_default(dev, "spi-max-frequency", 0);
+	if (dev_read_bool(dev, "spi-cpol"))
 		mode |= SPI_CPOL;
-	if (fdtdec_get_bool(blob, node, "spi-cpha"))
+	if (dev_read_bool(dev, "spi-cpha"))
 		mode |= SPI_CPHA;
-	if (fdtdec_get_bool(blob, node, "spi-cs-high"))
+	if (dev_read_bool(dev, "spi-cs-high"))
 		mode |= SPI_CS_HIGH;
-	if (fdtdec_get_bool(blob, node, "spi-3wire"))
+	if (dev_read_bool(dev, "spi-3wire"))
 		mode |= SPI_3WIRE;
-	if (fdtdec_get_bool(blob, node, "spi-half-duplex"))
+	if (dev_read_bool(dev, "spi-half-duplex"))
 		mode |= SPI_PREAMBLE;
 
 	/* Device DUAL/QUAD mode */
-	value = fdtdec_get_uint(blob, node, "spi-tx-bus-width", 1);
+	value = dev_read_u32_default(dev, "spi-tx-bus-width", 1);
 	switch (value) {
 	case 1:
 		break;
@@ -423,7 +420,7 @@ int spi_slave_ofdata_to_platdata(const void *blob, int node,
 		break;
 	}
 
-	value = fdtdec_get_uint(blob, node, "spi-rx-bus-width", 1);
+	value = dev_read_u32_default(dev, "spi-rx-bus-width", 1);
 	switch (value) {
 	case 1:
 		break;
diff --git a/include/spi.h b/include/spi.h
index deb65efdfb..8c4b882c54 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -562,7 +562,7 @@ int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp);
  * @node:	Node offset to read from
  * @plat:	Place to put the decoded information
  */
-int spi_slave_ofdata_to_platdata(const void *blob, int node,
+int spi_slave_ofdata_to_platdata(struct udevice *dev,
 				 struct dm_spi_slave_platdata *plat);
 
 /**
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 64/71] dm: sandbox: i2c: Drop fdtdec.h header
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (62 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 63/71] dm: spi: Convert uclass " Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 65/71] dm: sandbox: i2c_rtc: " Simon Glass
                   ` (6 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

This is not needed in this driver. Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/i2c/sandbox_i2c.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c
index 4696a1ae62..f5978fda29 100644
--- a/drivers/i2c/sandbox_i2c.c
+++ b/drivers/i2c/sandbox_i2c.c
@@ -9,7 +9,6 @@
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
-#include <fdtdec.h>
 #include <i2c.h>
 #include <asm/test.h>
 #include <dm/lists.h>
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 65/71] dm: sandbox: i2c_rtc: Drop fdtdec.h header
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (63 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 64/71] dm: sandbox: i2c: Drop fdtdec.h header Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 66/71] dm: spi-flash: Convert uclass to livetree Simon Glass
                   ` (5 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

This is not needed in this driver. Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/rtc/i2c_rtc_emul.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/rtc/i2c_rtc_emul.c b/drivers/rtc/i2c_rtc_emul.c
index 20827fdff1..0e06c97367 100644
--- a/drivers/rtc/i2c_rtc_emul.c
+++ b/drivers/rtc/i2c_rtc_emul.c
@@ -16,7 +16,6 @@
 
 #include <common.h>
 #include <dm.h>
-#include <fdtdec.h>
 #include <i2c.h>
 #include <os.h>
 #include <rtc.h>
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 66/71] dm: spi-flash: Convert uclass to livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (64 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 65/71] dm: sandbox: i2c_rtc: " Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 67/71] dm: sandbox: spi: Convert driver to support livetree Simon Glass
                   ` (4 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update the SPI flash uclass to support a live device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/mtd/spi/spi_flash.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index ab7910bc14..0034a28d5f 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -914,14 +914,13 @@ static int set_quad_mode(struct spi_flash *flash,
 }
 
 #if CONFIG_IS_ENABLED(OF_CONTROL)
-int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
+int spi_flash_decode_fdt(struct spi_flash *flash)
 {
 #ifdef CONFIG_DM_SPI_FLASH
 	fdt_addr_t addr;
 	fdt_size_t size;
-	int node = dev_of_offset(flash->dev);
 
-	addr = fdtdec_get_addr_size(blob, node, "memory-map", &size);
+	addr = dev_read_addr_size(flash->dev, "memory-map", &size);
 	if (addr == FDT_ADDR_T_NONE) {
 		debug("%s: Cannot decode address\n", __func__);
 		return 0;
@@ -1081,7 +1080,7 @@ int spi_flash_scan(struct spi_flash *flash)
 #endif
 
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
-	ret = spi_flash_decode_fdt(gd->fdt_blob, flash);
+	ret = spi_flash_decode_fdt(flash);
 	if (ret) {
 		debug("SF: FDT decode error\n");
 		return -EINVAL;
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 67/71] dm: sandbox: spi: Convert driver to support livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (65 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 66/71] dm: spi-flash: Convert uclass to livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 68/71] dm: sandbox: sysreset: Convert driver to livetree Simon Glass
                   ` (3 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update this driver to support a live device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/mtd/spi/sandbox.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index a53f4ebc68..1ba6815232 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -515,11 +515,9 @@ static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen,
 int sandbox_sf_ofdata_to_platdata(struct udevice *dev)
 {
 	struct sandbox_spi_flash_plat_data *pdata = dev_get_platdata(dev);
-	const void *blob = gd->fdt_blob;
-	int node = dev_of_offset(dev);
 
-	pdata->filename = fdt_getprop(blob, node, "sandbox,filename", NULL);
-	pdata->device_name = fdt_getprop(blob, node, "compatible", NULL);
+	pdata->filename = dev_read_string(dev, "sandbox,filename");
+	pdata->device_name = dev_read_string(dev, "compatible");
 	if (!pdata->filename || !pdata->device_name) {
 		debug("%s: Missing properties, filename=%s, device_name=%s\n",
 		      __func__, pdata->filename, pdata->device_name);
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 68/71] dm: sandbox: sysreset: Convert driver to livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (66 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 67/71] dm: sandbox: spi: Convert driver to support livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 69/71] dm: test: Fix nit with position of backslash Simon Glass
                   ` (2 subsequent siblings)
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Update this driver to support a live device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/sysreset/sysreset_sandbox.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/sysreset/sysreset_sandbox.c b/drivers/sysreset/sysreset_sandbox.c
index 0c4e2e1a93..12b3e5f86e 100644
--- a/drivers/sysreset/sysreset_sandbox.c
+++ b/drivers/sysreset/sysreset_sandbox.c
@@ -41,7 +41,7 @@ static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type)
 	 * (see the U_BOOT_DEVICE() declaration below) should not do anything.
 	 * If we are that device, return an error.
 	 */
-	if (state->fdt_fname && dev_of_offset(dev) == -1)
+	if (state->fdt_fname && !dev_of_valid(dev))
 		return -ENODEV;
 
 	switch (type) {
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 69/71] dm: test: Fix nit with position of backslash
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (67 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 68/71] dm: sandbox: sysreset: Convert driver to livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 70/71] dm: gpio: power: Convert pm8916 drivers to livetree Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 71/71] sandbox: Move to use live tree Simon Glass
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

Line up this backslash with all the others.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/test/ut.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/test/ut.h b/include/test/ut.h
index 85434d785a..d176df58c7 100644
--- a/include/test/ut.h
+++ b/include/test/ut.h
@@ -104,7 +104,7 @@ void ut_failf(struct unit_test_state *uts, const char *fname, int line,
 }
 
 /* Assert that a pointer is not an error pointer */
-#define ut_assertok_ptr(expr) {					\
+#define ut_assertok_ptr(expr) {						\
 	const void *val = (expr);					\
 									\
 	if (IS_ERR(val)) {						\
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 70/71] dm: gpio: power: Convert pm8916 drivers to livetree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (68 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 69/71] dm: test: Fix nit with position of backslash Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 71/71] sandbox: Move to use live tree Simon Glass
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

This PMIC driver (power and GPIO) is used by the sandbox SPMI tests.
Update the drivers to support a live device tree so that the tests pass.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/gpio/pm8916_gpio.c  | 8 +++-----
 drivers/power/pmic/pm8916.c | 2 +-
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/gpio/pm8916_gpio.c b/drivers/gpio/pm8916_gpio.c
index 8dea69f281..9ec2a24b3e 100644
--- a/drivers/gpio/pm8916_gpio.c
+++ b/drivers/gpio/pm8916_gpio.c
@@ -173,7 +173,7 @@ static int pm8916_gpio_probe(struct udevice *dev)
 	struct pm8916_gpio_bank *priv = dev_get_priv(dev);
 	int reg;
 
-	priv->pid = devfdt_get_addr(dev);
+	priv->pid = dev_read_addr(dev);
 	if (priv->pid == FDT_ADDR_T_NONE)
 		return -EINVAL;
 
@@ -193,10 +193,8 @@ static int pm8916_gpio_ofdata_to_platdata(struct udevice *dev)
 {
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
-	uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-					     "gpio-count", 0);
-	uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
-					 "gpio-bank-name", NULL);
+	uc_priv->gpio_count = dev_read_u32_default(dev, "gpio-count", 0);
+	uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
 	if (uc_priv->bank_name == NULL)
 		uc_priv->bank_name = "pm8916";
 
diff --git a/drivers/power/pmic/pm8916.c b/drivers/power/pmic/pm8916.c
index 3632ee2d1e..a048bbe7ce 100644
--- a/drivers/power/pmic/pm8916.c
+++ b/drivers/power/pmic/pm8916.c
@@ -70,7 +70,7 @@ static int pm8916_probe(struct udevice *dev)
 {
 	struct pm8916_priv *priv = dev_get_priv(dev);
 
-	priv->usid = devfdt_get_addr(dev);
+	priv->usid = dev_read_addr(dev);
 
 	if (priv->usid == FDT_ADDR_T_NONE)
 		return -EINVAL;
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 71/71] sandbox: Move to use live tree
  2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
                   ` (69 preceding siblings ...)
  2017-05-10 14:21 ` [U-Boot] [PATCH v2 70/71] dm: gpio: power: Convert pm8916 drivers to livetree Simon Glass
@ 2017-05-10 14:21 ` Simon Glass
  70 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-10 14:21 UTC (permalink / raw)
  To: u-boot

This updates sandbox to use a live device tree. This means that after
relocation (from board_init_r() onwards) it no-longer uses flat device
tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2:
- Rewrite based on testing and refining the v1 series
- Convert various subsystems to enable sandbox tests to pass

 configs/sandbox_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 83efb23dbc..d8d8a17404 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -55,6 +55,7 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_MAC_PARTITION=y
 CONFIG_AMIGA_PARTITION=y
 CONFIG_OF_CONTROL=y
+CONFIG_OF_LIVE=y
 CONFIG_OF_HOSTFILE=y
 CONFIG_NETCONSOLE=y
 CONFIG_REGMAP=y
-- 
2.13.0.rc2.291.g57267f2277-goog

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 05/71] dm: Add a function to create a 'live' device tree
  2017-05-10 14:20 ` [U-Boot] [PATCH v2 05/71] dm: Add a function to create a 'live' device tree Simon Glass
@ 2017-05-11 14:59   ` Lothar Waßmann
  2017-05-15  3:03     ` Simon Glass
  0 siblings, 1 reply; 76+ messages in thread
From: Lothar Waßmann @ 2017-05-11 14:59 UTC (permalink / raw)
  To: u-boot

Hi,

On Wed, 10 May 2017 08:20:44 -0600 Simon Glass wrote:
> This function converts the flat device tree into a hierarchical one with
> C structures and pointers. This is easier to access.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 
> Changes in v2: None
> 
>  include/of_live.h |  24 ++++
>  lib/Makefile      |   1 +
>  lib/of_live.c     | 333 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 358 insertions(+)
>  create mode 100644 include/of_live.h
>  create mode 100644 lib/of_live.c
> 
> diff --git a/include/of_live.h b/include/of_live.h
> new file mode 100644
> index 0000000000..f5303bb018
> --- /dev/null
> +++ b/include/of_live.h
> @@ -0,0 +1,24 @@
> +/*
> + * Copyright (c) 2017 Google, Inc
> + * Written by Simon Glass <sjg@chromium.org>
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + *
> + * Support for a 'live' (as opposed to flat) device tree
> + */
> +
> +#ifndef _OF_LIVE_H
> +#define _OF_LIVE_H
> +
> +struct device_node;
> +
> +/**
> + * of_live_build() - build a live (hierarchical) tree from a flat DT
> + *
> + * @fdt_blob: Input tree to convert
> + * @rootp: Returns live tree that was created
> + * @return 0 if OK, -ve on error
> + */
> +int of_live_build(const void *fdt_blob, struct device_node **rootp);
> +
> +#endif
> diff --git a/lib/Makefile b/lib/Makefile
> index 23e9f1ef11..bc2fb0a361 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -15,6 +15,7 @@ obj-$(CONFIG_ZLIB) += zlib/
>  obj-$(CONFIG_BZIP2) += bzip2/
>  obj-$(CONFIG_TIZEN) += tizen/
>  obj-$(CONFIG_FIT) += libfdt/
> +obj-$(CONFIG_OF_LIVE) += of_live.o
>  obj-$(CONFIG_CMD_DHRYSTONE) += dhry/
>  
>  obj-$(CONFIG_AES) += aes.o
> diff --git a/lib/of_live.c b/lib/of_live.c
> new file mode 100644
> index 0000000000..51927f9e91
> --- /dev/null
> +++ b/lib/of_live.c
> @@ -0,0 +1,333 @@
> +/*
> + * Copyright 2009 Benjamin Herrenschmidt, IBM Corp
> + * benh at kernel.crashing.org
> + *
> + * Based on parts of drivers/of/fdt.c from Linux v4.9
> + * Modifications for U-Boot
> + * Copyright (c) 2017 Google, Inc
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <libfdt.h>
> +#include <of_live.h>
> +#include <malloc.h>
> +#include <dm/of_access.h>
> +#include <linux/err.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static void *unflatten_dt_alloc(void **mem, unsigned long size,
> +				unsigned long align)
> +{
> +	void *res;
> +
> +	*mem = PTR_ALIGN(*mem, align);
> +	res = *mem;
> +	*mem += size;
> +
> +	return res;
> +}
> +
> +/**
> + * unflatten_dt_node() - Alloc and populate a device_node from the flat tree
> + * @blob: The parent device tree blob
> + * @mem: Memory chunk to use for allocating device nodes and properties
> + * @poffset: pointer to node in flat tree
> + * @dad: Parent struct device_node
> + * @nodepp: The device_node tree created by the call
> + * @fpsize: Size of the node path up at t05he current depth.
> + * @dryrun: If true, do not allocate device nodes but still calculate needed
> + * memory size
> + */
> +static void *unflatten_dt_node(const void *blob, void *mem, int *poffset,
> +			       struct device_node *dad,
> +			       struct device_node **nodepp,
> +			       unsigned long fpsize, bool dryrun)
> +{
> +	const __be32 *p;
> +	struct device_node *np;
> +	struct property *pp, **prev_pp = NULL;
> +	const char *pathp;
> +	int l;
> +	unsigned int allocl;
> +	static int depth;
> +	int old_depth;
> +	int offset;
> +	int has_name = 0;
> +	int new_format = 0;
> +
> +	pathp = fdt_get_name(blob, *poffset, &l);
> +	if (!pathp)
> +		return mem;
> +
> +	allocl = ++l;
> +
> +	/*
> +	 * version 0x10 has a more compact unit name here instead of the full
> +	 * path. we accumulate the full path size using "fpsize", we'll rebuild
> +	 * it later. We detect this because the first character of the name is
> +	 * not '/'.
> +	 */
> +	if ((*pathp) != '/') {
> +		new_format = 1;
> +		if (fpsize == 0) {
> +			/*
> +			 * root node: special case. fpsize accounts for path
> +			 * plus terminating zero. root node only has '/', so
> +			 * fpsize should be 2, but we want to avoid the first
> +			 * level nodes to have two '/' so we use fpsize 1 here
> +			 */
> +			fpsize = 1;
> +			allocl = 2;
> +			l = 1;
> +			pathp = "";
> +		} else {
> +			/*
> +			 * account for '/' and path size minus terminal 0
> +			 * already in 'l'
> +			 */
> +			fpsize += l;
> +			allocl = fpsize;
> +		}
> +	}
> +
> +	np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
> +				__alignof__(struct device_node));
> +	if (!dryrun) {
> +		char *fn;
> +
> +		fn = (char *)np + sizeof(*np);
> +		np->full_name = fn;
> +		if (new_format) {
> +			/* rebuild full path for new format */
> +			if (dad && dad->parent) {
> +				strcpy(fn, dad->full_name);
>
strcpy() is EVIL! How do you ascertain, that the string
at dad->full_name cannot overflow the buffer at fn?
 

Lothar Waßmann

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 05/71] dm: Add a function to create a 'live' device tree
  2017-05-11 14:59   ` Lothar Waßmann
@ 2017-05-15  3:03     ` Simon Glass
  2017-05-15  7:34       ` Lothar Waßmann
  0 siblings, 1 reply; 76+ messages in thread
From: Simon Glass @ 2017-05-15  3:03 UTC (permalink / raw)
  To: u-boot

Hi Lothar,

On 11 May 2017 at 08:59, Lothar Waßmann <LW@karo-electronics.de> wrote:
> Hi,
>
> On Wed, 10 May 2017 08:20:44 -0600 Simon Glass wrote:
>> This function converts the flat device tree into a hierarchical one with
>> C structures and pointers. This is easier to access.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v2: None
>>
>>  include/of_live.h |  24 ++++
>>  lib/Makefile      |   1 +
>>  lib/of_live.c     | 333 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 358 insertions(+)
>>  create mode 100644 include/of_live.h
>>  create mode 100644 lib/of_live.c
>>
>> diff --git a/include/of_live.h b/include/of_live.h
>> new file mode 100644
>> index 0000000000..f5303bb018
>> --- /dev/null
>> +++ b/include/of_live.h
>> @@ -0,0 +1,24 @@
>> +/*
>> + * Copyright (c) 2017 Google, Inc
>> + * Written by Simon Glass <sjg@chromium.org>
>> + *
>> + * SPDX-License-Identifier:  GPL-2.0+
>> + *
>> + * Support for a 'live' (as opposed to flat) device tree
>> + */
>> +
>> +#ifndef _OF_LIVE_H
>> +#define _OF_LIVE_H
>> +
>> +struct device_node;
>> +
>> +/**
>> + * of_live_build() - build a live (hierarchical) tree from a flat DT
>> + *
>> + * @fdt_blob: Input tree to convert
>> + * @rootp: Returns live tree that was created
>> + * @return 0 if OK, -ve on error
>> + */
>> +int of_live_build(const void *fdt_blob, struct device_node **rootp);
>> +
>> +#endif
>> diff --git a/lib/Makefile b/lib/Makefile
>> index 23e9f1ef11..bc2fb0a361 100644
>> --- a/lib/Makefile
>> +++ b/lib/Makefile
>> @@ -15,6 +15,7 @@ obj-$(CONFIG_ZLIB) += zlib/
>>  obj-$(CONFIG_BZIP2) += bzip2/
>>  obj-$(CONFIG_TIZEN) += tizen/
>>  obj-$(CONFIG_FIT) += libfdt/
>> +obj-$(CONFIG_OF_LIVE) += of_live.o
>>  obj-$(CONFIG_CMD_DHRYSTONE) += dhry/
>>
>>  obj-$(CONFIG_AES) += aes.o
>> diff --git a/lib/of_live.c b/lib/of_live.c
>> new file mode 100644
>> index 0000000000..51927f9e91
>> --- /dev/null
>> +++ b/lib/of_live.c
>> @@ -0,0 +1,333 @@
>> +/*
>> + * Copyright 2009 Benjamin Herrenschmidt, IBM Corp
>> + * benh at kernel.crashing.org
>> + *
>> + * Based on parts of drivers/of/fdt.c from Linux v4.9
>> + * Modifications for U-Boot
>> + * Copyright (c) 2017 Google, Inc
>> + *
>> + * SPDX-License-Identifier:  GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <libfdt.h>
>> +#include <of_live.h>
>> +#include <malloc.h>
>> +#include <dm/of_access.h>
>> +#include <linux/err.h>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +static void *unflatten_dt_alloc(void **mem, unsigned long size,
>> +                             unsigned long align)
>> +{
>> +     void *res;
>> +
>> +     *mem = PTR_ALIGN(*mem, align);
>> +     res = *mem;
>> +     *mem += size;
>> +
>> +     return res;
>> +}
>> +
>> +/**
>> + * unflatten_dt_node() - Alloc and populate a device_node from the flat tree
>> + * @blob: The parent device tree blob
>> + * @mem: Memory chunk to use for allocating device nodes and properties
>> + * @poffset: pointer to node in flat tree
>> + * @dad: Parent struct device_node
>> + * @nodepp: The device_node tree created by the call
>> + * @fpsize: Size of the node path up at t05he current depth.
>> + * @dryrun: If true, do not allocate device nodes but still calculate needed
>> + * memory size
>> + */
>> +static void *unflatten_dt_node(const void *blob, void *mem, int *poffset,
>> +                            struct device_node *dad,
>> +                            struct device_node **nodepp,
>> +                            unsigned long fpsize, bool dryrun)
>> +{
>> +     const __be32 *p;
>> +     struct device_node *np;
>> +     struct property *pp, **prev_pp = NULL;
>> +     const char *pathp;
>> +     int l;
>> +     unsigned int allocl;
>> +     static int depth;
>> +     int old_depth;
>> +     int offset;
>> +     int has_name = 0;
>> +     int new_format = 0;
>> +
>> +     pathp = fdt_get_name(blob, *poffset, &l);
>> +     if (!pathp)
>> +             return mem;
>> +
>> +     allocl = ++l;
>> +
>> +     /*
>> +      * version 0x10 has a more compact unit name here instead of the full
>> +      * path. we accumulate the full path size using "fpsize", we'll rebuild
>> +      * it later. We detect this because the first character of the name is
>> +      * not '/'.
>> +      */
>> +     if ((*pathp) != '/') {
>> +             new_format = 1;
>> +             if (fpsize == 0) {
>> +                     /*
>> +                      * root node: special case. fpsize accounts for path
>> +                      * plus terminating zero. root node only has '/', so
>> +                      * fpsize should be 2, but we want to avoid the first
>> +                      * level nodes to have two '/' so we use fpsize 1 here
>> +                      */
>> +                     fpsize = 1;
>> +                     allocl = 2;
>> +                     l = 1;
>> +                     pathp = "";
>> +             } else {
>> +                     /*
>> +                      * account for '/' and path size minus terminal 0
>> +                      * already in 'l'
>> +                      */
>> +                     fpsize += l;
>> +                     allocl = fpsize;
>> +             }
>> +     }
>> +
>> +     np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
>> +                             __alignof__(struct device_node));
>> +     if (!dryrun) {
>> +             char *fn;
>> +
>> +             fn = (char *)np + sizeof(*np);
>> +             np->full_name = fn;
>> +             if (new_format) {
>> +                     /* rebuild full path for new format */
>> +                     if (dad && dad->parent) {
>> +                             strcpy(fn, dad->full_name);
>>
> strcpy() is EVIL! How do you ascertain, that the string
> at dad->full_name cannot overflow the buffer at fn?

The size has been calculated the code above. This is a two-pass
approach - one pass figures out the total size of the required buffer,
and the next pass actually copies in the data.

If the length were wrong that would indicate a bug in the code above.
See the part where it sets new_format to 1.

Regards,
Simon

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 05/71] dm: Add a function to create a 'live' device tree
  2017-05-15  3:03     ` Simon Glass
@ 2017-05-15  7:34       ` Lothar Waßmann
  2017-05-16  0:18         ` Simon Glass
  0 siblings, 1 reply; 76+ messages in thread
From: Lothar Waßmann @ 2017-05-15  7:34 UTC (permalink / raw)
  To: u-boot

Hi,

On Sun, 14 May 2017 21:03:23 -0600 Simon Glass wrote:
> Hi Lothar,
> 
> On 11 May 2017 at 08:59, Lothar Waßmann <LW@karo-electronics.de> wrote:
> > Hi,
> >
> > On Wed, 10 May 2017 08:20:44 -0600 Simon Glass wrote:
> >> This function converts the flat device tree into a hierarchical one with
> >> C structures and pointers. This is easier to access.
> >>
> >> Signed-off-by: Simon Glass <sjg@chromium.org>
> >> ---
> >>
> >> Changes in v2: None
> >>
> >>  include/of_live.h |  24 ++++
> >>  lib/Makefile      |   1 +
> >>  lib/of_live.c     | 333 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >>  3 files changed, 358 insertions(+)
> >>  create mode 100644 include/of_live.h
> >>  create mode 100644 lib/of_live.c
> >>
> >> diff --git a/include/of_live.h b/include/of_live.h
> >> new file mode 100644
> >> index 0000000000..f5303bb018
> >> --- /dev/null
> >> +++ b/include/of_live.h
> >> @@ -0,0 +1,24 @@
> >> +/*
> >> + * Copyright (c) 2017 Google, Inc
> >> + * Written by Simon Glass <sjg@chromium.org>
> >> + *
> >> + * SPDX-License-Identifier:  GPL-2.0+
> >> + *
> >> + * Support for a 'live' (as opposed to flat) device tree
> >> + */
> >> +
> >> +#ifndef _OF_LIVE_H
> >> +#define _OF_LIVE_H
> >> +
> >> +struct device_node;
> >> +
> >> +/**
> >> + * of_live_build() - build a live (hierarchical) tree from a flat DT
> >> + *
> >> + * @fdt_blob: Input tree to convert
> >> + * @rootp: Returns live tree that was created
> >> + * @return 0 if OK, -ve on error
> >> + */
> >> +int of_live_build(const void *fdt_blob, struct device_node **rootp);
> >> +
> >> +#endif
> >> diff --git a/lib/Makefile b/lib/Makefile
> >> index 23e9f1ef11..bc2fb0a361 100644
> >> --- a/lib/Makefile
> >> +++ b/lib/Makefile
> >> @@ -15,6 +15,7 @@ obj-$(CONFIG_ZLIB) += zlib/
> >>  obj-$(CONFIG_BZIP2) += bzip2/
> >>  obj-$(CONFIG_TIZEN) += tizen/
> >>  obj-$(CONFIG_FIT) += libfdt/
> >> +obj-$(CONFIG_OF_LIVE) += of_live.o
> >>  obj-$(CONFIG_CMD_DHRYSTONE) += dhry/
> >>
> >>  obj-$(CONFIG_AES) += aes.o
> >> diff --git a/lib/of_live.c b/lib/of_live.c
> >> new file mode 100644
> >> index 0000000000..51927f9e91
> >> --- /dev/null
> >> +++ b/lib/of_live.c
> >> @@ -0,0 +1,333 @@
> >> +/*
> >> + * Copyright 2009 Benjamin Herrenschmidt, IBM Corp
> >> + * benh at kernel.crashing.org
> >> + *
> >> + * Based on parts of drivers/of/fdt.c from Linux v4.9
> >> + * Modifications for U-Boot
> >> + * Copyright (c) 2017 Google, Inc
> >> + *
> >> + * SPDX-License-Identifier:  GPL-2.0+
> >> + */
> >> +
> >> +#include <common.h>
> >> +#include <libfdt.h>
> >> +#include <of_live.h>
> >> +#include <malloc.h>
> >> +#include <dm/of_access.h>
> >> +#include <linux/err.h>
> >> +
> >> +DECLARE_GLOBAL_DATA_PTR;
> >> +
> >> +static void *unflatten_dt_alloc(void **mem, unsigned long size,
> >> +                             unsigned long align)
> >> +{
> >> +     void *res;
> >> +
> >> +     *mem = PTR_ALIGN(*mem, align);
> >> +     res = *mem;
> >> +     *mem += size;
> >> +
> >> +     return res;
> >> +}
> >> +
> >> +/**
> >> + * unflatten_dt_node() - Alloc and populate a device_node from the flat tree
> >> + * @blob: The parent device tree blob
> >> + * @mem: Memory chunk to use for allocating device nodes and properties
> >> + * @poffset: pointer to node in flat tree
> >> + * @dad: Parent struct device_node
> >> + * @nodepp: The device_node tree created by the call
> >> + * @fpsize: Size of the node path up at t05he current depth.
> >> + * @dryrun: If true, do not allocate device nodes but still calculate needed
> >> + * memory size
> >> + */
> >> +static void *unflatten_dt_node(const void *blob, void *mem, int *poffset,
> >> +                            struct device_node *dad,
> >> +                            struct device_node **nodepp,
> >> +                            unsigned long fpsize, bool dryrun)
> >> +{
> >> +     const __be32 *p;
> >> +     struct device_node *np;
> >> +     struct property *pp, **prev_pp = NULL;
> >> +     const char *pathp;
> >> +     int l;
> >> +     unsigned int allocl;
> >> +     static int depth;
> >> +     int old_depth;
> >> +     int offset;
> >> +     int has_name = 0;
> >> +     int new_format = 0;
> >> +
> >> +     pathp = fdt_get_name(blob, *poffset, &l);
> >> +     if (!pathp)
> >> +             return mem;
> >> +
> >> +     allocl = ++l;
> >> +
> >> +     /*
> >> +      * version 0x10 has a more compact unit name here instead of the full
> >> +      * path. we accumulate the full path size using "fpsize", we'll rebuild
> >> +      * it later. We detect this because the first character of the name is
> >> +      * not '/'.
> >> +      */
> >> +     if ((*pathp) != '/') {
> >> +             new_format = 1;
> >> +             if (fpsize == 0) {
> >> +                     /*
> >> +                      * root node: special case. fpsize accounts for path
> >> +                      * plus terminating zero. root node only has '/', so
> >> +                      * fpsize should be 2, but we want to avoid the first
> >> +                      * level nodes to have two '/' so we use fpsize 1 here
> >> +                      */
> >> +                     fpsize = 1;
> >> +                     allocl = 2;
> >> +                     l = 1;
> >> +                     pathp = "";
> >> +             } else {
> >> +                     /*
> >> +                      * account for '/' and path size minus terminal 0
> >> +                      * already in 'l'
> >> +                      */
> >> +                     fpsize += l;
> >> +                     allocl = fpsize;
> >> +             }
> >> +     }
> >> +
> >> +     np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
> >> +                             __alignof__(struct device_node));
> >> +     if (!dryrun) {
> >> +             char *fn;
> >> +
> >> +             fn = (char *)np + sizeof(*np);
> >> +             np->full_name = fn;
> >> +             if (new_format) {
> >> +                     /* rebuild full path for new format */
> >> +                     if (dad && dad->parent) {
> >> +                             strcpy(fn, dad->full_name);
> >>
> > strcpy() is EVIL! How do you ascertain, that the string
> > at dad->full_name cannot overflow the buffer at fn?
> 
> The size has been calculated the code above. This is a two-pass
> approach - one pass figures out the total size of the required buffer,
> and the next pass actually copies in the data.
> 
> If the length were wrong that would indicate a bug in the code above.
> See the part where it sets new_format to 1.
> 
dad->full_name is touched nowhere else in the code, so it is not
apparent from the code that its strlen() is accounted for in any way.


Lothar Waßmann

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [U-Boot] [PATCH v2 05/71] dm: Add a function to create a 'live' device tree
  2017-05-15  7:34       ` Lothar Waßmann
@ 2017-05-16  0:18         ` Simon Glass
  0 siblings, 0 replies; 76+ messages in thread
From: Simon Glass @ 2017-05-16  0:18 UTC (permalink / raw)
  To: u-boot

Hi Lothar,

On 15 May 2017 at 01:34, Lothar Waßmann <LW@karo-electronics.de> wrote:
> Hi,
>
> On Sun, 14 May 2017 21:03:23 -0600 Simon Glass wrote:
>> Hi Lothar,
>>
>> On 11 May 2017 at 08:59, Lothar Waßmann <LW@karo-electronics.de> wrote:
>> > Hi,
>> >
>> > On Wed, 10 May 2017 08:20:44 -0600 Simon Glass wrote:
>> >> This function converts the flat device tree into a hierarchical one with
>> >> C structures and pointers. This is easier to access.
>> >>
>> >> Signed-off-by: Simon Glass <sjg@chromium.org>
>> >> ---
>> >>
>> >> Changes in v2: None
>> >>
>> >>  include/of_live.h |  24 ++++
>> >>  lib/Makefile      |   1 +
>> >>  lib/of_live.c     | 333 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> >>  3 files changed, 358 insertions(+)
>> >>  create mode 100644 include/of_live.h
>> >>  create mode 100644 lib/of_live.c
>> >>
>> >> diff --git a/include/of_live.h b/include/of_live.h
>> >> new file mode 100644
>> >> index 0000000000..f5303bb018
>> >> --- /dev/null
>> >> +++ b/include/of_live.h
>> >> @@ -0,0 +1,24 @@
>> >> +/*
>> >> + * Copyright (c) 2017 Google, Inc
>> >> + * Written by Simon Glass <sjg@chromium.org>
>> >> + *
>> >> + * SPDX-License-Identifier:  GPL-2.0+
>> >> + *
>> >> + * Support for a 'live' (as opposed to flat) device tree
>> >> + */
>> >> +
>> >> +#ifndef _OF_LIVE_H
>> >> +#define _OF_LIVE_H
>> >> +
>> >> +struct device_node;
>> >> +
>> >> +/**
>> >> + * of_live_build() - build a live (hierarchical) tree from a flat DT
>> >> + *
>> >> + * @fdt_blob: Input tree to convert
>> >> + * @rootp: Returns live tree that was created
>> >> + * @return 0 if OK, -ve on error
>> >> + */
>> >> +int of_live_build(const void *fdt_blob, struct device_node **rootp);
>> >> +
>> >> +#endif
>> >> diff --git a/lib/Makefile b/lib/Makefile
>> >> index 23e9f1ef11..bc2fb0a361 100644
>> >> --- a/lib/Makefile
>> >> +++ b/lib/Makefile
>> >> @@ -15,6 +15,7 @@ obj-$(CONFIG_ZLIB) += zlib/
>> >>  obj-$(CONFIG_BZIP2) += bzip2/
>> >>  obj-$(CONFIG_TIZEN) += tizen/
>> >>  obj-$(CONFIG_FIT) += libfdt/
>> >> +obj-$(CONFIG_OF_LIVE) += of_live.o
>> >>  obj-$(CONFIG_CMD_DHRYSTONE) += dhry/
>> >>
>> >>  obj-$(CONFIG_AES) += aes.o
>> >> diff --git a/lib/of_live.c b/lib/of_live.c
>> >> new file mode 100644
>> >> index 0000000000..51927f9e91
>> >> --- /dev/null
>> >> +++ b/lib/of_live.c
>> >> @@ -0,0 +1,333 @@
>> >> +/*
>> >> + * Copyright 2009 Benjamin Herrenschmidt, IBM Corp
>> >> + * benh at kernel.crashing.org
>> >> + *
>> >> + * Based on parts of drivers/of/fdt.c from Linux v4.9
>> >> + * Modifications for U-Boot
>> >> + * Copyright (c) 2017 Google, Inc
>> >> + *
>> >> + * SPDX-License-Identifier:  GPL-2.0+
>> >> + */
>> >> +
>> >> +#include <common.h>
>> >> +#include <libfdt.h>
>> >> +#include <of_live.h>
>> >> +#include <malloc.h>
>> >> +#include <dm/of_access.h>
>> >> +#include <linux/err.h>
>> >> +
>> >> +DECLARE_GLOBAL_DATA_PTR;
>> >> +
>> >> +static void *unflatten_dt_alloc(void **mem, unsigned long size,
>> >> +                             unsigned long align)
>> >> +{
>> >> +     void *res;
>> >> +
>> >> +     *mem = PTR_ALIGN(*mem, align);
>> >> +     res = *mem;
>> >> +     *mem += size;
>> >> +
>> >> +     return res;
>> >> +}
>> >> +
>> >> +/**
>> >> + * unflatten_dt_node() - Alloc and populate a device_node from the flat tree
>> >> + * @blob: The parent device tree blob
>> >> + * @mem: Memory chunk to use for allocating device nodes and properties
>> >> + * @poffset: pointer to node in flat tree
>> >> + * @dad: Parent struct device_node
>> >> + * @nodepp: The device_node tree created by the call
>> >> + * @fpsize: Size of the node path up at t05he current depth.
>> >> + * @dryrun: If true, do not allocate device nodes but still calculate needed
>> >> + * memory size
>> >> + */
>> >> +static void *unflatten_dt_node(const void *blob, void *mem, int *poffset,
>> >> +                            struct device_node *dad,
>> >> +                            struct device_node **nodepp,
>> >> +                            unsigned long fpsize, bool dryrun)
>> >> +{
>> >> +     const __be32 *p;
>> >> +     struct device_node *np;
>> >> +     struct property *pp, **prev_pp = NULL;
>> >> +     const char *pathp;
>> >> +     int l;
>> >> +     unsigned int allocl;
>> >> +     static int depth;
>> >> +     int old_depth;
>> >> +     int offset;
>> >> +     int has_name = 0;
>> >> +     int new_format = 0;
>> >> +
>> >> +     pathp = fdt_get_name(blob, *poffset, &l);
>> >> +     if (!pathp)
>> >> +             return mem;
>> >> +
>> >> +     allocl = ++l;
>> >> +
>> >> +     /*
>> >> +      * version 0x10 has a more compact unit name here instead of the full
>> >> +      * path. we accumulate the full path size using "fpsize", we'll rebuild
>> >> +      * it later. We detect this because the first character of the name is
>> >> +      * not '/'.
>> >> +      */
>> >> +     if ((*pathp) != '/') {
>> >> +             new_format = 1;
>> >> +             if (fpsize == 0) {
>> >> +                     /*
>> >> +                      * root node: special case. fpsize accounts for path
>> >> +                      * plus terminating zero. root node only has '/', so
>> >> +                      * fpsize should be 2, but we want to avoid the first
>> >> +                      * level nodes to have two '/' so we use fpsize 1 here
>> >> +                      */
>> >> +                     fpsize = 1;
>> >> +                     allocl = 2;
>> >> +                     l = 1;
>> >> +                     pathp = "";
>> >> +             } else {
>> >> +                     /*
>> >> +                      * account for '/' and path size minus terminal 0
>> >> +                      * already in 'l'
>> >> +                      */
>> >> +                     fpsize += l;
>> >> +                     allocl = fpsize;
>> >> +             }
>> >> +     }
>> >> +
>> >> +     np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
>> >> +                             __alignof__(struct device_node));
>> >> +     if (!dryrun) {
>> >> +             char *fn;
>> >> +
>> >> +             fn = (char *)np + sizeof(*np);
>> >> +             np->full_name = fn;
>> >> +             if (new_format) {
>> >> +                     /* rebuild full path for new format */
>> >> +                     if (dad && dad->parent) {
>> >> +                             strcpy(fn, dad->full_name);
>> >>
>> > strcpy() is EVIL! How do you ascertain, that the string
>> > at dad->full_name cannot overflow the buffer at fn?
>>
>> The size has been calculated the code above. This is a two-pass
>> approach - one pass figures out the total size of the required buffer,
>> and the next pass actually copies in the data.
>>
>> If the length were wrong that would indicate a bug in the code above.
>> See the part where it sets new_format to 1.
>>
> dad->full_name is touched nowhere else in the code, so it is not
> apparent from the code that its strlen() is accounted for in any way.

Well it is somewhat strange code, but I've brought it in from Linux
and am trying to avoid changing it too much.

Regards,
Simon

^ permalink raw reply	[flat|nested] 76+ messages in thread

end of thread, other threads:[~2017-05-16  0:18 UTC | newest]

Thread overview: 76+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-10 14:20 [U-Boot] [PATCH v2 00/71] dm: Add support for a 'live' device tree Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 01/71] dm: core: Set return value first in lists_bind_fdt() Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 02/71] Update WARN_ON() to return a value Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 03/71] dm: core: Add livetree definitions Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 04/71] dm: core: Add livetree access functions Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 05/71] dm: Add a function to create a 'live' device tree Simon Glass
2017-05-11 14:59   ` Lothar Waßmann
2017-05-15  3:03     ` Simon Glass
2017-05-15  7:34       ` Lothar Waßmann
2017-05-16  0:18         ` Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 06/71] dm: Build a live tree after relocation Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 07/71] dm: core: Rename of_device_is_compatible() Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 08/71] dm: core: Add operations on device tree references Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 09/71] dm: core: Add livetree address functions Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 10/71] fdt: Update fdt_get_base_address() to use const Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 11/71] dm: core: Add address operations on device tree references Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 12/71] dm: core: Add a place to put extra device-tree reading functions Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 13/71] dm: core: Add device-based 'read' functions to access DT Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 14/71] dm: core: Implement live tree 'read' functions Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 15/71] dm: core: Allow binding a device from a live tree Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 16/71] dm: core: Update lists_bind_fdt() to use ofnode Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 17/71] dm: core: Update device_bind_driver_to_node() " Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 18/71] dm: core: Scan the live tree when setting up driver model Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 19/71] dm: core: Add a way to find a device by ofnode Simon Glass
2017-05-10 14:20 ` [U-Boot] [PATCH v2 20/71] dm: regmap: Add support for livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 21/71] dm: simple-bus: " Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 22/71] dm: core: Update uclass_find_device_by_phandle() " Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 23/71] sandbox: Add a way to reset sandbox state for tests Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 24/71] dm: test: Move test running code into a separate function Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 25/71] dm: test: Show the test filename when running Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 26/71] dm: test: Add support for running tests with livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 27/71] dm: core: Run tests with both livetree and flat tree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 28/71] dm: gpio: Refactor to prepare for live tree support Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 29/71] dm: gpio: Drop blank line in gpio_xlate_offs_flags() comment Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 30/71] dm: gpio: sandbox: Use dev_read...() functions to access DT Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 31/71] dm: gpio: Add live tree support Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 32/71] cros_ec: Fix debug() statement in ec_command_inptr() Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 33/71] cros_ec: Convert to support live tree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 34/71] sandbox: Add a new sandbox_flattree board Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 35/71] test: Update 'make test' to run more tests Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 36/71] fdt: Rename a few functions in fdt_support Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 37/71] dm: Add more livetree helpers and definitions Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 38/71] string: Add strchrnul() Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 39/71] string: Add strcspn() Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 40/71] dm: i2c: Convert uclass to livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 41/71] dm: pmic: " Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 42/71] sandbox: pmic: Convert pmic emulator to support livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 43/71] dm: regulator: Convert regulator uclass " Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 44/71] dm: regulator: Update fixed regulator " Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 45/71] dm: mmc: Convert uclass to livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 46/71] dm: adc: " Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 47/71] dm: usb: " Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 48/71] sandbox: usb: Convert emulators " Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 49/71] clk: Modify xlate() method for livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 50/71] dm: clk: Update uclass to support livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 51/71] dm: clk: fixed: Update " Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 52/71] dm: test: Separate out the bus DT offset test Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 53/71] dm: test: Disable the fdt_offset test with livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 54/71] dm: phy: Update tests to use ut_asserteq() Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 55/71] dm: mailbox: Update uclass to support livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 56/71] dm: phy: " Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 57/71] sandbox: phy: Update driver for livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 58/71] dm: power-domain: Update uclass to support livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 59/71] dm: reset: " Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 60/71] dm: pci: " Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 61/71] dm: Update the I2C eeprom driver for livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 62/71] cros_ec: Update the cros_ec keyboard driver to livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 63/71] dm: spi: Convert uclass " Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 64/71] dm: sandbox: i2c: Drop fdtdec.h header Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 65/71] dm: sandbox: i2c_rtc: " Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 66/71] dm: spi-flash: Convert uclass to livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 67/71] dm: sandbox: spi: Convert driver to support livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 68/71] dm: sandbox: sysreset: Convert driver to livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 69/71] dm: test: Fix nit with position of backslash Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 70/71] dm: gpio: power: Convert pm8916 drivers to livetree Simon Glass
2017-05-10 14:21 ` [U-Boot] [PATCH v2 71/71] sandbox: Move to use live tree Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.