All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/27] dm: Change the way sequence numbers are implemented
@ 2020-11-30  1:53 Simon Glass
  2020-11-30  1:53 ` [PATCH 01/27] linker_lists: Fix alignment issue Simon Glass
                   ` (28 more replies)
  0 siblings, 29 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

At present each device has two sequence numbers, with 'req_seq' being
set up at bind time and 'seq' at probe time. The idea is that devices
can 'request' a sequence number and then the conflicts are resolved when
the device is probed.

This makes things complicated in a few cases, since we don't really know
(at bind time) what the sequence number will end up being. We want to
honour the bind-time requests if at all possible, but in fact the only
source of these at present is the devicetree aliases.

Apart from the obvious need for sequence numbers to supports U-Boot's
numbering on devices on the command line, the current scheme was
designed to:

- avoid calculating the sequence number until it is needed, to save
  execution time
- allow multiple devices to obtain a particular sequence number as they
  are probed and removed
- retain a record of the 'requested' sequence number even if it turns out
  that a device could not get it (to allow debugging and retrying)

After some years using the current scheme it seems on balance that these
goals don't have as much merit as first thought. The first point would
be persuasive except that we end up reading the devicetree aliases at
bind-time anyway. So the work of resolving the sequence numbers during
probing is not that great. The second point hasn't really been an issue,
as there is typically no contention for sequence numbers (boards tend to
allocate them statically in the devicetree). Re the third point, we can
often figure out what was requested by looking at aliases, and in the
cases where we can't, it doesn't seem to matter much.

Since we have the devicetree available at bind time, we may as well just
use it, in the hope that the required processing will turn out to be
useful later (i.e. the device actually gets used). In addition, it is
simpler to use a single sequence number, since it avoids confusion and
some extra code.

This series moves U-Boot to use a single, bind-time sequence number. All
uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign sequence
numbers to their devices, so that as soon as a device is bound, it has a
sequence number. If a devicetree alias provides the number, it will be
used. Otherwise, during initial binding, the first free number is used.
For ad-hoc calls to device_bind() afterwards (e.g. from driver code), the
sequence is set to the maximum sequence number for the uclass + 1.

Apart from the simplicity gains, overall these changes seem to reduce the
number of tweaks and workarounds needed to get the desired behaviour.

However there will certainly be some problems created, so board
maintainers should test this out.


Simon Glass (27):
  linker_lists: Fix alignment issue
  efi: Drop unwanted message in efi_uc_destroy()
  dm: Avoid accessing seq directly
  dm: core: Update uclass_find_next_free_req_seq() args
  dm: core: Add a new sequence number for devices
  dm: test: Add support for new sequence numbers
  dm: core: Switch binding to use new sequence numbers
  dm: Fix return value in dev_read_alias_seq()
  dm: test: Drop assumptions of no sequence numbers
  octeon: Don't attempt to set the sequence number
  i2c: Update for new sequence numbers
  net: Update to use new sequence numbers
  pci: Update to use new sequence numbers
  spi: Update for new sequence numbers
  usb: ehci-mx6: Drop assignment of sequence number
  usb: Update for new sequence numbers
  x86: Drop unnecessary mp_init logic
  x86: Simplify acpi_device_infer_name()
  gpio: Update for new sequence numbers
  pinctrl: Update for new sequence numbers
  dm: Switch over to use new sequence number for dev_seq()
  dm: Drop uclass_resolve_seq()
  dm: Drop the unused arg in uclass_find_device_by_seq()
  dm: core: Simplify uclass_find_next_free_req_seq()
  cmd: Drop use of old sequence numbers in commands
  dm: core: Drop seq and req_seq
  dm: Update documentation for new sequence numbers

 arch/Kconfig                             |  11 +++
 arch/arm/include/asm/mach-imx/mxc_i2c.h  |   2 +-
 arch/arm/mach-k3/am6_init.c              |   2 +-
 arch/arm/mach-k3/j721e_init.c            |   2 +-
 arch/arm/mach-k3/sysfw-loader.c          |   2 +-
 arch/sandbox/dts/test.dts                |   2 +-
 arch/x86/cpu/apollolake/cpu.c            |   2 +-
 arch/x86/cpu/broadwell/cpu_full.c        |   2 +-
 arch/x86/cpu/ivybridge/model_206ax.c     |   2 +-
 arch/x86/cpu/mp_init.c                   |  23 ++---
 arch/x86/include/asm/mp.h                |   2 +-
 board/xilinx/versal/board.c              |  12 +--
 board/xilinx/zynqmp/zynqmp.c             |  12 +--
 cmd/axi.c                                |   6 +-
 cmd/cpu.c                                |   2 +-
 cmd/i2c.c                                |   6 +-
 cmd/misc.c                               |   2 +-
 cmd/osd.c                                |   6 +-
 cmd/pci.c                                |   7 +-
 cmd/pmic.c                               |   4 +-
 cmd/remoteproc.c                         |   2 +-
 cmd/w1.c                                 |   4 +-
 doc/api/linker_lists.rst                 |  62 ++++++++++++
 doc/driver-model/design.rst              |  58 +++++++-----
 drivers/core/device-remove.c             |   1 -
 drivers/core/device.c                    |  52 ++++------
 drivers/core/dump.c                      |   4 +-
 drivers/core/read.c                      |   4 +-
 drivers/core/root.c                      |  21 ++++-
 drivers/core/uclass.c                    | 115 ++++++++++-------------
 drivers/gpio/imx_rgpio2p.c               |   2 +-
 drivers/gpio/iproc_gpio.c                |   2 +-
 drivers/gpio/mvebu_gpio.c                |   2 +-
 drivers/gpio/mxc_gpio.c                  |   2 +-
 drivers/gpio/octeon_gpio.c               |   2 +-
 drivers/gpio/vybrid_gpio.c               |   2 +-
 drivers/i2c/ast_i2c.c                    |   4 +-
 drivers/i2c/davinci_i2c.c                |   2 +-
 drivers/i2c/designware_i2c_pci.c         |  16 +---
 drivers/i2c/exynos_hs_i2c.c              |   2 +-
 drivers/i2c/i2c-gpio.c                   |   2 +-
 drivers/i2c/i2c-uclass.c                 |   8 +-
 drivers/i2c/i2c-versatile.c              |   5 -
 drivers/i2c/imx_lpi2c.c                  |  12 +--
 drivers/i2c/intel_i2c.c                  |  12 +--
 drivers/i2c/lpc32xx_i2c.c                |   6 +-
 drivers/i2c/muxes/i2c-mux-uclass.c       |   4 +-
 drivers/i2c/mvtwsi.c                     |   4 +-
 drivers/i2c/mxc_i2c.c                    |  10 +-
 drivers/i2c/nx_i2c.c                     |   2 +-
 drivers/i2c/octeon_i2c.c                 |   3 +-
 drivers/i2c/s3c24x0_i2c.c                |   2 +-
 drivers/i2c/tegra_i2c.c                  |   5 +-
 drivers/mmc/fsl_esdhc_imx.c              |   4 +-
 drivers/mmc/octeontx_hsmmc.c             |   2 -
 drivers/mtd/spi/sandbox.c                |   4 +-
 drivers/net/dwc_eth_qos.c                |   2 +-
 drivers/net/fec_mxc.c                    |   7 +-
 drivers/net/fsl-mc/mc.c                  |   2 +-
 drivers/net/fsl_mcdmafec.c               |   2 +-
 drivers/net/ftgmac100.c                  |   2 +-
 drivers/net/higmacv300.c                 |   2 +-
 drivers/net/mcffec.c                     |   2 +-
 drivers/net/octeontx/nicvf_main.c        |   9 +-
 drivers/net/octeontx/smi.c               |   3 +-
 drivers/net/octeontx2/nix.c              |   2 +-
 drivers/net/octeontx2/rvu_pf.c           |   6 +-
 drivers/net/xilinx_axi_emac.c            |   2 +-
 drivers/net/xilinx_emaclite.c            |   2 +-
 drivers/net/zynq_gem.c                   |   2 +-
 drivers/pci/pci-aardvark.c               |   2 +-
 drivers/pci/pci-uclass.c                 |  42 ++++-----
 drivers/pci/pci_auto.c                   |   6 +-
 drivers/pci/pcie_dw_mvebu.c              |   6 +-
 drivers/pci/pcie_dw_ti.c                 |   6 +-
 drivers/pci/pcie_ecam_generic.c          |   2 +-
 drivers/pci/pcie_fsl.c                   |  16 ++--
 drivers/pci/pcie_intel_fpga.c            |   2 +-
 drivers/pci/pcie_layerscape_fixup.c      |   4 +-
 drivers/pci/pcie_layerscape_gen4.c       |  10 +-
 drivers/pci/pcie_layerscape_gen4_fixup.c |   2 +-
 drivers/pci/pcie_layerscape_rc.c         |  12 +--
 drivers/pci/pcie_mediatek.c              |   2 +-
 drivers/pci/pcie_rockchip.c              |   6 +-
 drivers/pinctrl/exynos/pinctrl-exynos.c  |   2 +-
 drivers/serial/serial_mcf.c              |   2 +-
 drivers/serial/serial_s5p.c              |   2 +-
 drivers/spi/altera_spi.c                 |   2 +-
 drivers/spi/cf_spi.c                     |  12 +--
 drivers/spi/fsl_dspi.c                   |   8 +-
 drivers/spi/fsl_espi.c                   |   2 +-
 drivers/spi/octeon_spi.c                 |   2 +-
 drivers/spi/pic32_spi.c                  |   4 +-
 drivers/spi/rk_spi.c                     |   1 -
 drivers/spi/sandbox_spi.c                |   2 +-
 drivers/spi/spi-uclass.c                 |   4 +-
 drivers/spi/tegra114_spi.c               |   2 +-
 drivers/spi/tegra20_sflash.c             |   2 +-
 drivers/spi/tegra20_slink.c              |   2 +-
 drivers/spi/tegra210_qspi.c              |   2 +-
 drivers/spi/xilinx_spi.c                 |   2 +-
 drivers/spi/zynq_qspi.c                  |   2 +-
 drivers/spi/zynq_spi.c                   |   2 +-
 drivers/usb/gadget/max3420_udc.c         |   2 +-
 drivers/usb/host/ehci-mx5.c              |   2 +-
 drivers/usb/host/ehci-mx6.c              |  14 ++-
 drivers/usb/host/ehci-omap.c             |   2 +-
 drivers/usb/host/ehci-vf.c               |   8 +-
 drivers/usb/host/usb-sandbox.c           |   2 +-
 drivers/usb/host/usb-uclass.c            |   6 +-
 drivers/video/vidconsole-uclass.c        |   4 +-
 drivers/virtio/virtio-uclass.c           |   2 +-
 drivers/watchdog/ast_wdt.c               |   2 +-
 drivers/watchdog/at91sam9_wdt.c          |   2 +-
 drivers/watchdog/cdns_wdt.c              |   2 +-
 drivers/watchdog/omap_wdt.c              |   2 +-
 drivers/watchdog/orion_wdt.c             |   2 +-
 drivers/watchdog/sbsa_gwdt.c             |   2 +-
 drivers/watchdog/sp805_wdt.c             |   2 +-
 drivers/watchdog/tangier_wdt.c           |   2 +-
 drivers/watchdog/xilinx_tb_wdt.c         |   2 +-
 drivers/watchdog/xilinx_wwdt.c           |   2 +-
 include/asm-generic/global_data.h        |   2 +
 include/configs/sandbox.h                |   2 +-
 include/dm/device.h                      |  32 +++----
 include/dm/uclass-internal.h             |  34 +++----
 include/dm/uclass.h                      |  15 +--
 include/linker_lists.h                   |   3 +-
 include/pci.h                            |   2 +-
 include/spi.h                            |   2 +-
 lib/acpi/acpi_device.c                   |  27 +-----
 lib/efi_driver/efi_uclass.c              |   1 -
 lib/efi_loader/efi_device_path.c         |   4 +-
 net/eth-uclass.c                         |  24 +++--
 test/dm/acpi.c                           |   6 +-
 test/dm/blk.c                            |   3 -
 test/dm/bus.c                            |  15 +--
 test/dm/core.c                           |  19 ++++
 test/dm/eth.c                            |  14 +--
 test/dm/i2c.c                            |   3 -
 test/dm/spi.c                            |   3 -
 test/dm/test-fdt.c                       | 100 ++++++++++++--------
 test/dm/test-main.c                      |   6 ++
 143 files changed, 583 insertions(+), 569 deletions(-)

-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 01/27] linker_lists: Fix alignment issue
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  6:20   ` Heinrich Schuchardt
  2020-11-30  1:53 ` [PATCH 02/27] efi: Drop unwanted message in efi_uc_destroy() Simon Glass
                   ` (27 subsequent siblings)
  28 siblings, 1 reply; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

The linker script uses alphabetic sorting to group the different linker
lists together. Each group has its own struct and potentially its own
alignment. But when the linker packs the structs together it cannot
ensure that a linker list starts on the expected alignment boundary.

For example, if the first list has a struct size of 8 and we place 3 of
them in the image, that means that the next struct will start at offset
0x18 from the start of the linker_list section. If the next struct has
a size of 16 then it will start at an 8-byte aligned offset, but not a
16-byte aligned offset.

With sandbox on x86_64, a reference to a linker list item using
ll_entry_get() can force alignment of that particular linker_list item,
if it is in the same file as the linker_list item is declared.

Consider this example, where struct driver is 0x80 bytes:

	ll_entry_declare(struct driver, fred, driver)

...

	void *p = ll_entry_get(struct driver, fred, driver)

If these two lines of code are in the same file, then the entry is forced
to be aligned at the 'struct driver' alignment, which is 16 bytes. If the
second line of code is in a different file, then no action is taken, since
the compiler cannot update the alignment of the linker_list item.

In the first case, an 8-byte 'fill' region is added:

 .u_boot_list_2_driver_2_testbus_drv
                0x0000000000270018       0x80 test/built-in.o
                0x0000000000270018
                	_u_boot_list_2_driver_2_testbus_drv
 .u_boot_list_2_driver_2_testfdt1_drv
                0x0000000000270098       0x80 test/built-in.o
                0x0000000000270098
                	_u_boot_list_2_driver_2_testfdt1_drv
 *fill*         0x0000000000270118        0x8
 .u_boot_list_2_driver_2_testfdt_drv
                0x0000000000270120       0x80 test/built-in.o
                0x0000000000270120
                	_u_boot_list_2_driver_2_testfdt_drv
 .u_boot_list_2_driver_2_testprobe_drv
                0x00000000002701a0       0x80 test/built-in.o
                0x00000000002701a0
                	_u_boot_list_2_driver_2_testprobe_drv

With this, the linker_list no-longer works since items after testfdt1_drv
are not at the expected address.

Ideally we would have a way to tell gcc not to align structs in this way.
It is not clear how we could do this, and in any case it would require us
to adjust every struct used by the linker_list feature.

One possible fix is to force each separate linker_list to start on the
largest possible boundary that can be required by the compiler. However
that does not seem to work on x86_64, which uses 16-byte alignment in this
case but needs 32-byte alignment.

So add a Kconfig option to handle this. Set the default value to 4 so
as to avoid changing platforms that don't need it.

Update the ll_entry_start() accordingly.

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

 arch/Kconfig             | 11 +++++++
 doc/api/linker_lists.rst | 62 ++++++++++++++++++++++++++++++++++++++++
 include/linker_lists.h   |  3 +-
 3 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 3aa99e08fce..aa8664212f1 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -7,6 +7,17 @@ config HAVE_ARCH_IOREMAP
 config NEEDS_MANUAL_RELOC
 	bool
 
+config LINKER_LIST_ALIGN
+	int
+	default 32 if SANDBOX
+	default 8 if ARM64 || X86
+	default 4
+	help
+	  Force the each linker list to be aligned to this boundary. This
+	  is required if ll_entry_get() is used, since otherwise the linker
+	  may add padding into the table, thus breaking it.
+	  See linker_lists.rst for full details.
+
 choice
 	prompt "Architecture select"
 	default SANDBOX
diff --git a/doc/api/linker_lists.rst b/doc/api/linker_lists.rst
index 72f514e0ac0..7a37db52ba8 100644
--- a/doc/api/linker_lists.rst
+++ b/doc/api/linker_lists.rst
@@ -96,5 +96,67 @@ defined for the whole list and each sub-list:
   %u_boot_list_2_drivers_2_pci_3
   %u_boot_list_2_drivers_3
 
+Alignment issues
+----------------
+
+The linker script uses alphabetic sorting to group the different linker
+lists together. Each group has its own struct and potentially its own
+alignment. But when the linker packs the structs together it cannot ensure
+that a linker list starts on the expected alignment boundary.
+
+For example, if the first list has a struct size of 8 and we place 3 of
+them in the image, that means that the next struct will start at offset
+0x18 from the start of the linker_list section. If the next struct has
+a size of 16 then it will start at an 8-byte aligned offset, but not a
+16-byte aligned offset.
+
+With sandbox on x86_64, a reference to a linker list item using
+ll_entry_get() can force alignment of that particular linker_list item,
+if it is in the same file as the linker_list item is declared.
+
+Consider this example, where struct driver is 0x80 bytes:
+
+::
+
+    ll_entry_declare(struct driver, fred, driver)
+
+    ...
+
+    void *p = ll_entry_get(struct driver, fred, driver)
+
+If these two lines of code are in the same file, then the entry is forced
+to be aligned at the 'struct driver' alignment, which is 16 bytes. If the
+second line of code is in a different file, then no action is taken, since
+the compiler cannot update the alignment of the linker_list item.
+
+In the first case, an 8-byte 'fill' region is added:
+
+::
+
+    .u_boot_list_2_driver_2_testbus_drv
+                0x0000000000270018       0x80 test/built-in.o
+                0x0000000000270018                _u_boot_list_2_driver_2_testbus_drv
+    .u_boot_list_2_driver_2_testfdt1_drv
+                0x0000000000270098       0x80 test/built-in.o
+                0x0000000000270098                _u_boot_list_2_driver_2_testfdt1_drv
+    *fill*         0x0000000000270118        0x8
+    .u_boot_list_2_driver_2_testfdt_drv
+                0x0000000000270120       0x80 test/built-in.o
+                0x0000000000270120                _u_boot_list_2_driver_2_testfdt_drv
+    .u_boot_list_2_driver_2_testprobe_drv
+                0x00000000002701a0       0x80 test/built-in.o
+                0x00000000002701a0                _u_boot_list_2_driver_2_testprobe_drv
+
+With this, the linker_list no-longer works since items after testfdt1_drv
+are not at the expected address.
+
+Ideally we would have a way to tell gcc not to align structs in this way.
+It is not clear how we could do this, and in any case it would require us
+to adjust every struct used by the linker_list feature.
+
+The simplest fix seems to be to force each separate linker_list to start
+on the largest possible boundary that can be required by the compiler. This
+is the purpose of CONFIG_LINKER_LIST_ALIGN
+
 .. kernel-doc:: include/linker_lists.h
    :internal:
diff --git a/include/linker_lists.h b/include/linker_lists.h
index d775d041e04..fd98ecd297c 100644
--- a/include/linker_lists.h
+++ b/include/linker_lists.h
@@ -124,7 +124,8 @@
  */
 #define ll_entry_start(_type, _list)					\
 ({									\
-	static char start[0] __aligned(4) __attribute__((unused,	\
+	static char start[0] __aligned(CONFIG_LINKER_LIST_ALIGN)	\
+		__attribute__((unused,					\
 		section(".u_boot_list_2_"#_list"_1")));			\
 	(_type *)&start;						\
 })
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 02/27] efi: Drop unwanted message in efi_uc_destroy()
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
  2020-11-30  1:53 ` [PATCH 01/27] linker_lists: Fix alignment issue Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-12-01  8:04   ` Heinrich Schuchardt
  2020-11-30  1:53 ` [PATCH 03/27] dm: Avoid accessing seq directly Simon Glass
                   ` (26 subsequent siblings)
  28 siblings, 1 reply; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

This is not very useful and is printed by some tests, causing confusion.
Drop it.

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

 lib/efi_driver/efi_uclass.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c
index 0cf74b0361d..5b8315472e3 100644
--- a/lib/efi_driver/efi_uclass.c
+++ b/lib/efi_driver/efi_uclass.c
@@ -340,7 +340,6 @@ static int efi_uc_init(struct uclass *class)
  */
 static int efi_uc_destroy(struct uclass *class)
 {
-	printf("Destroying  UCLASS_EFI\n");
 	return 0;
 }
 
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 03/27] dm: Avoid accessing seq directly
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
  2020-11-30  1:53 ` [PATCH 01/27] linker_lists: Fix alignment issue Simon Glass
  2020-11-30  1:53 ` [PATCH 02/27] efi: Drop unwanted message in efi_uc_destroy() Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 04/27] dm: core: Update uclass_find_next_free_req_seq() args Simon Glass
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

At present various drivers etc. access the device's 'seq' member directly.
This makes it harder to change the meaning of that member. Change access
to go through a function instead.

The drivers/i2c/lpc32xx_i2c.c file is left unchanged for now.

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

 arch/arm/include/asm/mach-imx/mxc_i2c.h  |  2 +-
 arch/x86/cpu/broadwell/cpu_full.c        |  2 +-
 arch/x86/cpu/ivybridge/model_206ax.c     |  2 +-
 board/xilinx/versal/board.c              | 12 ++++----
 board/xilinx/zynqmp/zynqmp.c             | 12 ++++----
 cmd/axi.c                                |  4 +--
 cmd/cpu.c                                |  2 +-
 cmd/i2c.c                                |  4 +--
 cmd/misc.c                               |  2 +-
 cmd/osd.c                                |  4 +--
 cmd/pci.c                                |  7 +++--
 cmd/pmic.c                               |  4 +--
 cmd/remoteproc.c                         |  2 +-
 cmd/w1.c                                 |  4 +--
 drivers/core/device.c                    |  2 +-
 drivers/core/dump.c                      |  4 +--
 drivers/core/uclass.c                    |  6 ++--
 drivers/gpio/octeon_gpio.c               |  2 +-
 drivers/i2c/ast_i2c.c                    |  4 +--
 drivers/i2c/davinci_i2c.c                |  2 +-
 drivers/i2c/exynos_hs_i2c.c              |  2 +-
 drivers/i2c/i2c-gpio.c                   |  2 +-
 drivers/i2c/imx_lpi2c.c                  | 12 ++++----
 drivers/i2c/lpc32xx_i2c.c                |  6 +++-
 drivers/i2c/mxc_i2c.c                    | 10 +++----
 drivers/i2c/nx_i2c.c                     |  2 +-
 drivers/i2c/octeon_i2c.c                 |  2 +-
 drivers/i2c/s3c24x0_i2c.c                |  2 +-
 drivers/i2c/tegra_i2c.c                  |  5 ++--
 drivers/mmc/fsl_esdhc_imx.c              |  4 +--
 drivers/mtd/spi/sandbox.c                |  4 +--
 drivers/net/fec_mxc.c                    |  7 +++--
 drivers/net/fsl-mc/mc.c                  |  2 +-
 drivers/net/fsl_mcdmafec.c               |  2 +-
 drivers/net/ftgmac100.c                  |  2 +-
 drivers/net/higmacv300.c                 |  2 +-
 drivers/net/mcffec.c                     |  2 +-
 drivers/net/octeontx/nicvf_main.c        |  9 +++---
 drivers/net/octeontx/smi.c               |  2 +-
 drivers/net/octeontx2/nix.c              |  2 +-
 drivers/net/octeontx2/rvu_pf.c           |  6 ++--
 drivers/net/xilinx_axi_emac.c            |  2 +-
 drivers/net/xilinx_emaclite.c            |  2 +-
 drivers/net/zynq_gem.c                   |  2 +-
 drivers/pci/pci-aardvark.c               |  2 +-
 drivers/pci/pci-uclass.c                 | 36 ++++++++++++------------
 drivers/pci/pci_auto.c                   |  6 ++--
 drivers/pci/pcie_dw_mvebu.c              |  6 ++--
 drivers/pci/pcie_dw_ti.c                 |  6 ++--
 drivers/pci/pcie_ecam_generic.c          |  2 +-
 drivers/pci/pcie_fsl.c                   | 16 +++++------
 drivers/pci/pcie_intel_fpga.c            |  2 +-
 drivers/pci/pcie_layerscape_fixup.c      |  4 +--
 drivers/pci/pcie_layerscape_gen4.c       | 10 +++----
 drivers/pci/pcie_layerscape_gen4_fixup.c |  2 +-
 drivers/pci/pcie_layerscape_rc.c         | 12 ++++----
 drivers/pci/pcie_mediatek.c              |  2 +-
 drivers/pci/pcie_rockchip.c              |  6 ++--
 drivers/serial/serial_mcf.c              |  2 +-
 drivers/serial/serial_s5p.c              |  2 +-
 drivers/spi/altera_spi.c                 |  2 +-
 drivers/spi/cf_spi.c                     | 12 ++++----
 drivers/spi/fsl_dspi.c                   |  6 ++--
 drivers/spi/fsl_espi.c                   |  2 +-
 drivers/spi/octeon_spi.c                 |  2 +-
 drivers/spi/pic32_spi.c                  |  4 +--
 drivers/spi/sandbox_spi.c                |  2 +-
 drivers/spi/tegra114_spi.c               |  2 +-
 drivers/spi/tegra20_sflash.c             |  2 +-
 drivers/spi/tegra20_slink.c              |  2 +-
 drivers/spi/tegra210_qspi.c              |  2 +-
 drivers/spi/xilinx_spi.c                 |  2 +-
 drivers/spi/zynq_qspi.c                  |  2 +-
 drivers/spi/zynq_spi.c                   |  2 +-
 drivers/usb/gadget/max3420_udc.c         |  2 +-
 drivers/usb/host/ehci-mx5.c              |  2 +-
 drivers/usb/host/ehci-mx6.c              |  2 +-
 drivers/usb/host/ehci-omap.c             |  2 +-
 drivers/usb/host/ehci-vf.c               |  2 +-
 drivers/usb/host/usb-sandbox.c           |  2 +-
 drivers/usb/host/usb-uclass.c            |  2 +-
 drivers/video/vidconsole-uclass.c        |  4 +--
 drivers/virtio/virtio-uclass.c           |  2 +-
 drivers/watchdog/ast_wdt.c               |  2 +-
 drivers/watchdog/at91sam9_wdt.c          |  2 +-
 drivers/watchdog/cdns_wdt.c              |  2 +-
 drivers/watchdog/omap_wdt.c              |  2 +-
 drivers/watchdog/orion_wdt.c             |  2 +-
 drivers/watchdog/sbsa_gwdt.c             |  2 +-
 drivers/watchdog/sp805_wdt.c             |  2 +-
 drivers/watchdog/tangier_wdt.c           |  2 +-
 drivers/watchdog/xilinx_tb_wdt.c         |  2 +-
 drivers/watchdog/xilinx_wwdt.c           |  2 +-
 include/dm/device.h                      |  5 ++++
 include/pci.h                            |  2 +-
 include/spi.h                            |  2 +-
 lib/efi_loader/efi_device_path.c         |  4 +--
 net/eth-uclass.c                         | 19 +++++++------
 98 files changed, 211 insertions(+), 197 deletions(-)

diff --git a/arch/arm/include/asm/mach-imx/mxc_i2c.h b/arch/arm/include/asm/mach-imx/mxc_i2c.h
index 81fd9814447..c016aa74741 100644
--- a/arch/arm/include/asm/mach-imx/mxc_i2c.h
+++ b/arch/arm/include/asm/mach-imx/mxc_i2c.h
@@ -42,7 +42,7 @@ struct mxc_i2c_bus {
 	/*
 	 * board file can use this index to locate which i2c_pads_info is for
 	 * i2c_idle_bus. When pinmux is implement, this entry can be
-	 * discarded. Here we do not use dev->seq, because we do not want to
+	 * discarded. Here we do not use dev_seq(dev), because we do not want to
 	 * export device to board file.
 	 */
 	int index;
diff --git a/arch/x86/cpu/broadwell/cpu_full.c b/arch/x86/cpu/broadwell/cpu_full.c
index 706f68f63d6..ff066028fe6 100644
--- a/arch/x86/cpu/broadwell/cpu_full.c
+++ b/arch/x86/cpu/broadwell/cpu_full.c
@@ -638,7 +638,7 @@ static int broadwell_get_count(const struct udevice *dev)
 
 static int cpu_x86_broadwell_probe(struct udevice *dev)
 {
-	if (dev->seq == 0) {
+	if (dev_seq(dev) == 0) {
 		cpu_core_init(dev);
 		return broadwell_init(dev);
 	}
diff --git a/arch/x86/cpu/ivybridge/model_206ax.c b/arch/x86/cpu/ivybridge/model_206ax.c
index 55f7cc2b2ec..598ebcdf084 100644
--- a/arch/x86/cpu/ivybridge/model_206ax.c
+++ b/arch/x86/cpu/ivybridge/model_206ax.c
@@ -425,7 +425,7 @@ static int model_206ax_get_count(const struct udevice *dev)
 
 static int cpu_x86_model_206ax_probe(struct udevice *dev)
 {
-	if (dev->seq == 0)
+	if (dev_seq(dev) == 0)
 		model_206ax_init(dev);
 
 	return 0;
diff --git a/board/xilinx/versal/board.c b/board/xilinx/versal/board.c
index 912c1143a8a..2782a346f07 100644
--- a/board/xilinx/versal/board.c
+++ b/board/xilinx/versal/board.c
@@ -153,9 +153,9 @@ int board_late_init(void)
 			puts("Boot from EMMC but without SD1 enabled!\n");
 			return -1;
 		}
-		debug("mmc1 device found at %p, seq %d\n", dev, dev->seq);
+		debug("mmc1 device found at %p, seq %d\n", dev, dev_seq(dev));
 		mode = "mmc";
-		bootseq = dev->seq;
+		bootseq = dev_seq(dev);
 		break;
 	case SD_MODE:
 		puts("SD_MODE\n");
@@ -164,10 +164,10 @@ int board_late_init(void)
 			puts("Boot from SD0 but without SD0 enabled!\n");
 			return -1;
 		}
-		debug("mmc0 device found at %p, seq %d\n", dev, dev->seq);
+		debug("mmc0 device found at %p, seq %d\n", dev, dev_seq(dev));
 
 		mode = "mmc";
-		bootseq = dev->seq;
+		bootseq = dev_seq(dev);
 		break;
 	case SD1_LSHFT_MODE:
 		puts("LVL_SHFT_");
@@ -179,10 +179,10 @@ int board_late_init(void)
 			puts("Boot from SD1 but without SD1 enabled!\n");
 			return -1;
 		}
-		debug("mmc1 device found at %p, seq %d\n", dev, dev->seq);
+		debug("mmc1 device found at %p, seq %d\n", dev, dev_seq(dev));
 
 		mode = "mmc";
-		bootseq = dev->seq;
+		bootseq = dev_seq(dev);
 		break;
 	default:
 		mode = "";
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index 731285a7367..047b0704859 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -596,10 +596,10 @@ int board_late_init(void)
 			puts("Boot from EMMC but without SD0 enabled!\n");
 			return -1;
 		}
-		debug("mmc0 device found at %p, seq %d\n", dev, dev->seq);
+		debug("mmc0 device found at %p, seq %d\n", dev, dev_seq(dev));
 
 		mode = "mmc";
-		bootseq = dev->seq;
+		bootseq = dev_seq(dev);
 		break;
 	case SD_MODE:
 		puts("SD_MODE\n");
@@ -610,10 +610,10 @@ int board_late_init(void)
 			puts("Boot from SD0 but without SD0 enabled!\n");
 			return -1;
 		}
-		debug("mmc0 device found at %p, seq %d\n", dev, dev->seq);
+		debug("mmc0 device found at %p, seq %d\n", dev, dev_seq(dev));
 
 		mode = "mmc";
-		bootseq = dev->seq;
+		bootseq = dev_seq(dev);
 		env_set("modeboot", "sdboot");
 		break;
 	case SD1_LSHFT_MODE:
@@ -628,10 +628,10 @@ int board_late_init(void)
 			puts("Boot from SD1 but without SD1 enabled!\n");
 			return -1;
 		}
-		debug("mmc1 device found at %p, seq %d\n", dev, dev->seq);
+		debug("mmc1 device found at %p, seq %d\n", dev, dev_seq(dev));
 
 		mode = "mmc";
-		bootseq = dev->seq;
+		bootseq = dev_seq(dev);
 		env_set("modeboot", "sdboot");
 		break;
 	case NAND_MODE:
diff --git a/cmd/axi.c b/cmd/axi.c
index c9d53c049e8..f7e206c04a7 100644
--- a/cmd/axi.c
+++ b/cmd/axi.c
@@ -35,7 +35,7 @@ static void show_bus(struct udevice *bus)
 
 	printf("Bus %d:\t%s", bus->req_seq, bus->name);
 	if (device_active(bus))
-		printf("  (active %d)", bus->seq);
+		printf("  (active %d)", dev_seq(bus));
 	printf("\n");
 	for (device_find_first_child(bus, &dev);
 	     dev;
@@ -147,7 +147,7 @@ static int do_axi_bus_num(struct cmd_tbl *cmdtp, int flag, int argc,
 		struct udevice *bus;
 
 		if (!axi_get_cur_bus(&bus))
-			bus_no = bus->seq;
+			bus_no = dev_seq(bus);
 		else
 			bus_no = -1;
 
diff --git a/cmd/cpu.c b/cmd/cpu.c
index ff553c16c4e..af2a42a6c25 100644
--- a/cmd/cpu.c
+++ b/cmd/cpu.c
@@ -32,7 +32,7 @@ static int print_cpu_list(bool detail)
 		int ret, i;
 
 		ret = cpu_get_desc(dev, buf, sizeof(buf));
-		printf("%3d: %-10s %s\n", dev->seq, dev->name,
+		printf("%3d: %-10s %s\n", dev_seq(dev), dev->name,
 		       ret ? "<no description>" : buf);
 		if (!detail)
 			continue;
diff --git a/cmd/i2c.c b/cmd/i2c.c
index cc01119b210..f97d437af47 100644
--- a/cmd/i2c.c
+++ b/cmd/i2c.c
@@ -1702,7 +1702,7 @@ static void show_bus(struct udevice *bus)
 
 	printf("Bus %d:\t%s", bus->req_seq, bus->name);
 	if (device_active(bus))
-		printf("  (active %d)", bus->seq);
+		printf("  (active %d)", dev_seq(bus));
 	printf("\n");
 	for (device_find_first_child(bus, &dev);
 	     dev;
@@ -1825,7 +1825,7 @@ static int do_i2c_bus_num(struct cmd_tbl *cmdtp, int flag, int argc,
 		struct udevice *bus;
 
 		if (!i2c_get_cur_bus(&bus))
-			bus_no = bus->seq;
+			bus_no = dev_seq(bus);
 		else
 			bus_no = -1;
 #else
diff --git a/cmd/misc.c b/cmd/misc.c
index 653deed7f57..ef540e836f2 100644
--- a/cmd/misc.c
+++ b/cmd/misc.c
@@ -34,7 +34,7 @@ static int do_misc_list(struct cmd_tbl *cmdtp, int flag,
 	for (uclass_first_device(UCLASS_MISC, &dev);
 	     dev;
 	     uclass_next_device(&dev)) {
-		printf("%-20s %5d %10s\n", dev->name, dev->seq,
+		printf("%-20s %5d %10s\n", dev->name, dev_seq(dev),
 		       dev->driver->name);
 	}
 
diff --git a/cmd/osd.c b/cmd/osd.c
index bdad5d8e963..9b8fd5c921e 100644
--- a/cmd/osd.c
+++ b/cmd/osd.c
@@ -77,7 +77,7 @@ static void show_osd(struct udevice *osd)
 {
 	printf("OSD %d:\t%s", osd->req_seq, osd->name);
 	if (device_active(osd))
-		printf("  (active %d)", osd->seq);
+		printf("  (active %d)", dev_seq(osd));
 	printf("\n");
 }
 
@@ -235,7 +235,7 @@ static int do_osd_num(struct cmd_tbl *cmdtp, int flag, int argc,
 		struct udevice *osd;
 
 		if (!osd_get_osd_cur(&osd))
-			osd_no = osd->seq;
+			osd_no = dev_seq(osd);
 		else
 			osd_no = -1;
 		printf("Current osd is %d\n", osd_no);
diff --git a/cmd/pci.c b/cmd/pci.c
index f91a4eb8ed0..0b08b5d76de 100644
--- a/cmd/pci.c
+++ b/cmd/pci.c
@@ -334,7 +334,7 @@ static void pciinfo(struct udevice *bus, bool short_listing)
 {
 	struct udevice *dev;
 
-	pciinfo_header(bus->seq, short_listing);
+	pciinfo_header(dev_seq(bus), short_listing);
 
 	for (device_find_first_child(bus, &dev);
 	     dev;
@@ -343,11 +343,12 @@ static void pciinfo(struct udevice *bus, bool short_listing)
 
 		pplat = dev_get_parent_platdata(dev);
 		if (short_listing) {
-			printf("%02x.%02x.%02x   ", bus->seq,
+			printf("%02x.%02x.%02x   ", dev_seq(bus),
 			       PCI_DEV(pplat->devfn), PCI_FUNC(pplat->devfn));
 			pci_header_show_brief(dev);
 		} else {
-			printf("\nFound PCI device %02x.%02x.%02x:\n", bus->seq,
+			printf("\nFound PCI device %02x.%02x.%02x:\n",
+			       dev_seq(bus),
 			       PCI_DEV(pplat->devfn), PCI_FUNC(pplat->devfn));
 			pci_header_show(dev);
 		}
diff --git a/cmd/pmic.c b/cmd/pmic.c
index 3bda0534a36..0cb44d07409 100644
--- a/cmd/pmic.c
+++ b/cmd/pmic.c
@@ -41,7 +41,7 @@ static int do_dev(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 			return CMD_RET_USAGE;
 		}
 
-		printf("dev: %d @ %s\n", currdev->seq, currdev->name);
+		printf("dev: %d @ %s\n", dev_seq(currdev), currdev->name);
 	}
 
 	return CMD_RET_SUCCESS;
@@ -66,7 +66,7 @@ static int do_list(struct cmd_tbl *cmdtp, int flag, int argc,
 		printf("| %-*.*s| %-*.*s| %s @ %d\n",
 		       LIMIT_DEV, LIMIT_DEV, dev->name,
 		       LIMIT_PARENT, LIMIT_PARENT, dev->parent->name,
-		       dev_get_uclass_name(dev->parent), dev->parent->seq);
+		       dev_get_uclass_name(dev->parent), dev_seq(dev->parent));
 	}
 
 	if (ret)
diff --git a/cmd/remoteproc.c b/cmd/remoteproc.c
index e8b9178e740..c111ef21756 100644
--- a/cmd/remoteproc.c
+++ b/cmd/remoteproc.c
@@ -47,7 +47,7 @@ static int print_remoteproc_list(void)
 			break;
 		}
 		printf("%d - Name:'%s' type:'%s' supports: %s%s%s%s%s%s\n",
-		       dev->seq,
+		       dev_seq(dev),
 		       uc_pdata->name,
 		       type,
 		       ops->load ? "load " : "",
diff --git a/cmd/w1.c b/cmd/w1.c
index 459094bf809..d0f0ee1234b 100644
--- a/cmd/w1.c
+++ b/cmd/w1.c
@@ -21,7 +21,7 @@ static int w1_bus(void)
 		printf("one wire interface not found\n");
 		return CMD_RET_FAILURE;
 	}
-	printf("Bus %d:\t%s", bus->seq, bus->name);
+	printf("Bus %d:\t%s", dev_seq(bus), bus->name);
 	if (device_active(bus))
 		printf("  (active)");
 	printf("\n");
@@ -31,7 +31,7 @@ static int w1_bus(void)
 	     device_find_next_child(&dev)) {
 		ret = device_probe(dev);
 
-		printf("\t%s (%d) uclass %s : ", dev->name, dev->seq,
+		printf("\t%s (%d) uclass %s : ", dev->name, dev_seq(dev),
 		       dev->uclass->uc_drv->name);
 
 		if (ret)
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 79afaf06290..5660310c754 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -661,7 +661,7 @@ int device_find_child_by_seq(const struct udevice *parent, int seq_or_req_seq,
 		return -ENODEV;
 
 	list_for_each_entry(dev, &parent->child_head, sibling_node) {
-		if ((find_req_seq ? dev->req_seq : dev->seq) ==
+		if ((find_req_seq ? dev->req_seq : dev_seq(dev)) ==
 				seq_or_req_seq) {
 			*devp = dev;
 			return 0;
diff --git a/drivers/core/dump.c b/drivers/core/dump.c
index 6debaf97a1d..9f440366734 100644
--- a/drivers/core/dump.c
+++ b/drivers/core/dump.c
@@ -67,8 +67,8 @@ static void dm_display_line(struct udevice *dev, int index)
 	printf("%-3i %c %s @ %08lx", index,
 	       dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
 	       dev->name, (ulong)map_to_sysmem(dev));
-	if (dev->seq != -1 || dev->req_seq != -1)
-		printf(", seq %d, (req %d)", dev->seq, dev->req_seq);
+	if (dev_seq(dev) != -1 || dev->req_seq != -1)
+		printf(", seq %d, (req %d)", dev_seq(dev), dev->req_seq);
 	puts("\n");
 }
 
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index c3f1b73cd6b..699f24843cf 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -311,8 +311,8 @@ int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
 
 	uclass_foreach_dev(dev, uc) {
 		log_debug("   - %d %d '%s'\n",
-			  dev->req_seq, dev->seq, dev->name);
-		if ((find_req_seq ? dev->req_seq : dev->seq) ==
+			  dev->req_seq, dev_seq(dev), dev->name);
+		if ((find_req_seq ? dev->req_seq : dev_seq(dev)) ==
 				seq_or_req_seq) {
 			*devp = dev;
 			log_debug("   - found\n");
@@ -695,7 +695,7 @@ int uclass_resolve_seq(struct udevice *dev)
 	int seq = 0;
 	int ret;
 
-	assert(dev->seq == -1);
+	assert(dev_seq(dev) == -1);
 	ret = uclass_find_device_by_seq(uc_drv->id, dev->req_seq, false, &dup);
 	if (!ret) {
 		dm_warn("Device '%s': seq %d is in use by '%s'\n",
diff --git a/drivers/gpio/octeon_gpio.c b/drivers/gpio/octeon_gpio.c
index 45acaadcdb6..f1c67fd006d 100644
--- a/drivers/gpio/octeon_gpio.c
+++ b/drivers/gpio/octeon_gpio.c
@@ -202,7 +202,7 @@ static int octeon_gpio_probe(struct udevice *dev)
 
 	uc_priv->bank_name  = strdup(dev->name);
 	end = strchr(uc_priv->bank_name, '@');
-	end[0] = 'A' + dev->seq;
+	end[0] = 'A' + dev_seq(dev);
 	end[1] = '\0';
 
 	debug("%s(%s): base address: %p, pin count: %d\n",
diff --git a/drivers/i2c/ast_i2c.c b/drivers/i2c/ast_i2c.c
index 2cdfb5561b7..afd4b44100b 100644
--- a/drivers/i2c/ast_i2c.c
+++ b/drivers/i2c/ast_i2c.c
@@ -110,7 +110,7 @@ static int ast_i2c_probe(struct udevice *dev)
 {
 	struct ast2500_scu *scu;
 
-	debug("Enabling I2C%u\n", dev->seq);
+	debug("Enabling I2C%u\n", dev_seq(dev));
 
 	/*
 	 * Get all I2C devices out of Reset.
@@ -307,7 +307,7 @@ static int ast_i2c_set_speed(struct udevice *dev, unsigned int speed)
 	struct ast_i2c_regs *regs = priv->regs;
 	ulong i2c_rate, divider;
 
-	debug("Setting speed for I2C%d to <%u>\n", dev->seq, speed);
+	debug("Setting speed for I2C%d to <%u>\n", dev_seq(dev), speed);
 	if (!speed) {
 		debug("No valid speed specified\n");
 		return -EINVAL;
diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c
index a54f2151fd3..478385ad683 100644
--- a/drivers/i2c/davinci_i2c.c
+++ b/drivers/i2c/davinci_i2c.c
@@ -470,7 +470,7 @@ static int davinci_i2c_probe(struct udevice *dev)
 {
 	struct i2c_bus *i2c_bus = dev_get_priv(dev);
 
-	i2c_bus->id = dev->seq;
+	i2c_bus->id = dev_seq(dev);
 	i2c_bus->regs = dev_read_addr_ptr(dev);
 
 	i2c_bus->speed = 100000;
diff --git a/drivers/i2c/exynos_hs_i2c.c b/drivers/i2c/exynos_hs_i2c.c
index 5785adedb6d..87fc9c19940 100644
--- a/drivers/i2c/exynos_hs_i2c.c
+++ b/drivers/i2c/exynos_hs_i2c.c
@@ -533,7 +533,7 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev)
 		dev_read_u32_default(dev, "clock-frequency",
 				     I2C_SPEED_STANDARD_RATE);
 	i2c_bus->node = node;
-	i2c_bus->bus_num = dev->seq;
+	i2c_bus->bus_num = dev_seq(dev);
 
 	exynos_pinmux_config(i2c_bus->id, PINMUX_FLAG_HS_MODE);
 
diff --git a/drivers/i2c/i2c-gpio.c b/drivers/i2c/i2c-gpio.c
index 381938c956f..3eb31672bec 100644
--- a/drivers/i2c/i2c-gpio.c
+++ b/drivers/i2c/i2c-gpio.c
@@ -298,7 +298,7 @@ static int i2c_gpio_probe(struct udevice *dev, uint chip, uint chip_flags)
 	i2c_gpio_send_stop(bus, delay);
 
 	debug("%s: bus: %d (%s) chip: %x flags: %x ret: %d\n",
-	      __func__, dev->seq, dev->name, chip, chip_flags, ret);
+	      __func__, dev_seq(dev), dev->name, chip, chip_flags, ret);
 
 	return ret;
 }
diff --git a/drivers/i2c/imx_lpi2c.c b/drivers/i2c/imx_lpi2c.c
index feeed1e9a2f..a4e8ab795d4 100644
--- a/drivers/i2c/imx_lpi2c.c
+++ b/drivers/i2c/imx_lpi2c.c
@@ -289,7 +289,7 @@ static int bus_i2c_set_bus_speed(struct udevice *bus, int speed)
 			return clock_rate;
 		}
 	} else {
-		clock_rate = imx_get_i2cclk(bus->seq);
+		clock_rate = imx_get_i2cclk(dev_seq(bus));
 		if (!clock_rate)
 			return -EPERM;
 	}
@@ -377,7 +377,7 @@ static int bus_i2c_init(struct udevice *bus, int speed)
 	val = readl(&regs->mcr) & ~LPI2C_MCR_MEN_MASK;
 	writel(val | LPI2C_MCR_MEN(1), &regs->mcr);
 
-	debug("i2c : controller bus %d, speed %d:\n", bus->seq, speed);
+	debug("i2c : controller bus %d, speed %d:\n", dev_seq(bus), speed);
 
 	return ret;
 }
@@ -452,11 +452,11 @@ static int imx_lpi2c_probe(struct udevice *bus)
 		return -EINVAL;
 
 	i2c_bus->base = addr;
-	i2c_bus->index = bus->seq;
+	i2c_bus->index = dev_seq(bus);
 	i2c_bus->bus = bus;
 
 	/* power up i2c resource */
-	ret = init_i2c_power(bus->seq);
+	ret = init_i2c_power(dev_seq(bus));
 	if (ret) {
 		debug("init_i2c_power err = %d\n", ret);
 		return ret;
@@ -486,7 +486,7 @@ static int imx_lpi2c_probe(struct udevice *bus)
 		}
 	} else {
 		/* To i.MX7ULP, only i2c4-7 can be handled by A7 core */
-		ret = enable_i2c_clk(1, bus->seq);
+		ret = enable_i2c_clk(1, dev_seq(bus));
 		if (ret < 0)
 			return ret;
 	}
@@ -496,7 +496,7 @@ static int imx_lpi2c_probe(struct udevice *bus)
 		return ret;
 
 	debug("i2c : controller bus %d@0x%lx , speed %d: ",
-	      bus->seq, i2c_bus->base,
+	      dev_seq(bus), i2c_bus->base,
 	      i2c_bus->speed);
 
 	return 0;
diff --git a/drivers/i2c/lpc32xx_i2c.c b/drivers/i2c/lpc32xx_i2c.c
index 6af2e975cf3..4858479b142 100644
--- a/drivers/i2c/lpc32xx_i2c.c
+++ b/drivers/i2c/lpc32xx_i2c.c
@@ -282,7 +282,11 @@ U_BOOT_I2C_ADAP_COMPLETE(lpc32xx_2, lpc32xx_i2c_init, NULL,
 static int lpc32xx_i2c_probe(struct udevice *bus)
 {
 	struct lpc32xx_i2c_dev *dev = dev_get_platdata(bus);
-	bus->seq = dev->index;
+
+	/*
+	 * FIXME: This is not permitted
+	 *	dev_seq(bus) = dev->index;
+	 */
 
 	__i2c_init(dev->base, dev->speed, 0, dev->index);
 	return 0;
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 7609594bd01..d7f8e821aca 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -914,7 +914,7 @@ static int mxc_i2c_probe(struct udevice *bus)
 	}
 
 	i2c_bus->base = addr;
-	i2c_bus->index = bus->seq;
+	i2c_bus->index = dev_seq(bus);
 	i2c_bus->bus = bus;
 
 	/* Enable clk */
@@ -930,7 +930,7 @@ static int mxc_i2c_probe(struct udevice *bus)
 		return ret;
 	}
 #else
-	ret = enable_i2c_clk(1, bus->seq);
+	ret = enable_i2c_clk(1, dev_seq(bus));
 	if (ret < 0)
 		return ret;
 #endif
@@ -942,7 +942,7 @@ static int mxc_i2c_probe(struct udevice *bus)
 	ret = fdt_stringlist_search(fdt, node, "pinctrl-names", "gpio");
 	if (ret < 0) {
 		debug("i2c bus %d@0x%2lx, no gpio pinctrl state.\n",
-		      bus->seq, i2c_bus->base);
+		      dev_seq(bus), i2c_bus->base);
 	} else {
 		ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
 				"scl-gpios", 0, &i2c_bus->scl_gpio,
@@ -955,7 +955,7 @@ static int mxc_i2c_probe(struct udevice *bus)
 		    ret || ret2) {
 			dev_err(bus,
 				"i2c bus %d at %lu, fail to request scl/sda gpio\n",
-				bus->seq, i2c_bus->base);
+				dev_seq(bus), i2c_bus->base);
 			return -EINVAL;
 		}
 	}
@@ -966,7 +966,7 @@ static int mxc_i2c_probe(struct udevice *bus)
 	 */
 
 	debug("i2c : controller bus %d at %lu , speed %d: ",
-	      bus->seq, i2c_bus->base,
+	      dev_seq(bus), i2c_bus->base,
 	      i2c_bus->speed);
 
 	return 0;
diff --git a/drivers/i2c/nx_i2c.c b/drivers/i2c/nx_i2c.c
index ca14a0ecac7..3f0e7124b72 100644
--- a/drivers/i2c/nx_i2c.c
+++ b/drivers/i2c/nx_i2c.c
@@ -240,7 +240,7 @@ static int nx_i2c_probe(struct udevice *dev)
 		return -EINVAL;
 	bus->regs = (struct nx_i2c_regs *)addr;
 
-	bus->bus_num = dev->seq;
+	bus->bus_num = dev_seq(dev);
 
 	/* i2c node parsing */
 	i2c_process_node(dev);
diff --git a/drivers/i2c/octeon_i2c.c b/drivers/i2c/octeon_i2c.c
index 23dcb1563ea..38839e45758 100644
--- a/drivers/i2c/octeon_i2c.c
+++ b/drivers/i2c/octeon_i2c.c
@@ -811,7 +811,7 @@ static int octeon_i2c_probe(struct udevice *dev)
 	if (ret)
 		return ret;
 
-	debug("TWSI bus %d at %p\n", dev->seq, twsi->base);
+	debug("TWSI bus %d at %p\n", dev_seq(dev), twsi->base);
 
 	/* Start with standard speed, real speed set via DT or cmd */
 	return twsi_init(twsi->base, i2c_slave_addr);
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c
index cb45d3c100f..29ba217e709 100644
--- a/drivers/i2c/s3c24x0_i2c.c
+++ b/drivers/i2c/s3c24x0_i2c.c
@@ -318,7 +318,7 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev)
 		dev_read_u32_default(dev, "clock-frequency",
 				     I2C_SPEED_STANDARD_RATE);
 	i2c_bus->node = node;
-	i2c_bus->bus_num = dev->seq;
+	i2c_bus->bus_num = dev_seq(dev);
 
 	exynos_pinmux_config(i2c_bus->id, 0);
 
diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c
index 65b3734348b..19212020e84 100644
--- a/drivers/i2c/tegra_i2c.c
+++ b/drivers/i2c/tegra_i2c.c
@@ -362,7 +362,7 @@ static int tegra_i2c_probe(struct udevice *dev)
 	int ret;
 	bool is_dvc;
 
-	i2c_bus->id = dev->seq;
+	i2c_bus->id = dev_seq(dev);
 	i2c_bus->type = dev_get_driver_data(dev);
 	i2c_bus->regs = (struct i2c_ctlr *)dev_read_addr(dev);
 	if ((ulong)i2c_bus->regs == FDT_ADDR_T_NONE) {
@@ -408,7 +408,8 @@ static int tegra_i2c_probe(struct udevice *dev)
 	}
 	i2c_init_controller(i2c_bus);
 	debug("%s: controller bus %d at %p, speed %d: ",
-	      is_dvc ? "dvc" : "i2c", dev->seq, i2c_bus->regs, i2c_bus->speed);
+	      is_dvc ? "dvc" : "i2c", dev_seq(dev), i2c_bus->regs,
+	      i2c_bus->speed);
 
 	return 0;
 }
diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index 22040c67a84..2d4a817a264 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -1542,7 +1542,7 @@ static int fsl_esdhc_probe(struct udevice *dev)
 	 * work as expected.
 	 */
 
-	init_clk_usdhc(dev->seq);
+	init_clk_usdhc(dev_seq(dev));
 
 #if CONFIG_IS_ENABLED(CLK)
 	/* Assigned clock already set clock */
@@ -1559,7 +1559,7 @@ static int fsl_esdhc_probe(struct udevice *dev)
 
 	priv->sdhc_clk = clk_get_rate(&priv->per_clk);
 #else
-	priv->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK + dev->seq);
+	priv->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK + dev_seq(dev));
 	if (priv->sdhc_clk <= 0) {
 		dev_err(dev, "Unable to get clk for %s\n", dev->name);
 		return -EINVAL;
diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 1d0c1cb3fa2..1a362616694 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -131,7 +131,7 @@ static int sandbox_sf_probe(struct udevice *dev)
 	int ret = 0;
 	int cs = -1;
 
-	debug("%s: bus %d, looking for emul=%p: ", __func__, bus->seq, dev);
+	debug("%s: bus %d, looking for emul=%p: ", __func__, dev_seq(bus), dev);
 	ret = sandbox_spi_get_emul(state, bus, dev, &emul);
 	if (ret) {
 		printf("Error: Unknown chip select for device '%s'\n",
@@ -565,7 +565,7 @@ int sandbox_spi_get_emul(struct sandbox_state *state,
 			 struct udevice **emulp)
 {
 	struct sandbox_spi_info *info;
-	int busnum = bus->seq;
+	int busnum = dev_seq(bus);
 	int cs = spi_chip_select(slave);
 	int ret;
 
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index bb55be9a267..4560dd80015 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -1451,7 +1451,7 @@ static int fecmxc_probe(struct udevice *dev)
 
 	fec_reg_setup(priv);
 
-	priv->dev_id = dev->seq;
+	priv->dev_id = dev_seq(dev);
 
 #ifdef CONFIG_DM_ETH_PHY
 	bus = eth_phy_get_mdio_bus(dev);
@@ -1459,9 +1459,10 @@ static int fecmxc_probe(struct udevice *dev)
 
 	if (!bus) {
 #ifdef CONFIG_FEC_MXC_MDIO_BASE
-		bus = fec_get_miibus((ulong)CONFIG_FEC_MXC_MDIO_BASE, dev->seq);
+		bus = fec_get_miibus((ulong)CONFIG_FEC_MXC_MDIO_BASE,
+				     dev_seq(dev));
 #else
-		bus = fec_get_miibus((ulong)priv->eth, dev->seq);
+		bus = fec_get_miibus((ulong)priv->eth, dev_seq(dev));
 #endif
 	}
 	if (!bus) {
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index 84db6be624a..7497e9b735e 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -187,7 +187,7 @@ static int mc_fixup_mac_addr(void *blob, int nodeoffset,
 #ifdef CONFIG_DM_ETH
 	struct eth_pdata *plat = dev_get_platdata(eth_dev);
 	unsigned char *enetaddr = plat->enetaddr;
-	int eth_index = eth_dev->seq;
+	int eth_index = dev_seq(eth_dev);
 #else
 	unsigned char *enetaddr = eth_dev->enetaddr;
 	int eth_index = eth_dev->index;
diff --git a/drivers/net/fsl_mcdmafec.c b/drivers/net/fsl_mcdmafec.c
index e27f7e5321a..6eaa60ac187 100644
--- a/drivers/net/fsl_mcdmafec.c
+++ b/drivers/net/fsl_mcdmafec.c
@@ -502,7 +502,7 @@ static int mcdmafec_probe(struct udevice *dev)
 	int retval;
 	const u32 *val;
 
-	info->index = dev->seq;
+	info->index = dev_seq(dev);
 	info->iobase = pdata->iobase;
 	info->miibase = pdata->iobase;
 	info->phy_addr = -1;
diff --git a/drivers/net/ftgmac100.c b/drivers/net/ftgmac100.c
index 00bda24f1fd..2ed012d5dd0 100644
--- a/drivers/net/ftgmac100.c
+++ b/drivers/net/ftgmac100.c
@@ -171,7 +171,7 @@ static int ftgmac100_mdio_init(struct udevice *dev)
 	bus->write = ftgmac100_mdio_write;
 	bus->priv  = priv;
 
-	ret = mdio_register_seq(bus, dev->seq);
+	ret = mdio_register_seq(bus, dev_seq(dev));
 	if (ret) {
 		free(bus);
 		return ret;
diff --git a/drivers/net/higmacv300.c b/drivers/net/higmacv300.c
index 2aae7f4863c..00c07770290 100644
--- a/drivers/net/higmacv300.c
+++ b/drivers/net/higmacv300.c
@@ -528,7 +528,7 @@ static int higmac_probe(struct udevice *dev)
 	bus->priv = priv;
 	priv->bus = bus;
 
-	ret = mdio_register_seq(bus, dev->seq);
+	ret = mdio_register_seq(bus, dev_seq(dev));
 	if (ret)
 		return ret;
 
diff --git a/drivers/net/mcffec.c b/drivers/net/mcffec.c
index f94a2d8123c..43b7dbb1a01 100644
--- a/drivers/net/mcffec.c
+++ b/drivers/net/mcffec.c
@@ -524,7 +524,7 @@ static int mcffec_probe(struct udevice *dev)
 	int retval, fec_idx;
 	const u32 *val;
 
-	info->index = dev->seq;
+	info->index = dev_seq(dev);
 	info->iobase = pdata->iobase;
 	info->phy_addr = -1;
 
diff --git a/drivers/net/octeontx/nicvf_main.c b/drivers/net/octeontx/nicvf_main.c
index e13c8b95569..800df8a500b 100644
--- a/drivers/net/octeontx/nicvf_main.c
+++ b/drivers/net/octeontx/nicvf_main.c
@@ -452,11 +452,12 @@ int nicvf_write_hwaddr(struct udevice *dev)
 	 * u-boot framework updates MAC to random address.
 	 * Use this hook to update mac address in environment.
 	 */
-	if (!eth_env_get_enetaddr_by_index("eth", dev->seq, ethaddr)) {
-		eth_env_set_enetaddr_by_index("eth", dev->seq, pdata->enetaddr);
+	if (!eth_env_get_enetaddr_by_index("eth", dev_seq(dev), ethaddr)) {
+		eth_env_set_enetaddr_by_index("eth", dev_seq(dev),
+					      pdata->enetaddr);
 		debug("%s: pMAC %pM\n", __func__, pdata->enetaddr);
 	}
-	eth_env_get_enetaddr_by_index("eth", dev->seq, ethaddr);
+	eth_env_get_enetaddr_by_index("eth", dev_seq(dev), ethaddr);
 	if (memcmp(ethaddr, pdata->enetaddr, ARP_HLEN)) {
 		debug("%s: pMAC %pM\n", __func__, pdata->enetaddr);
 		nicvf_hw_set_mac_addr(nic, dev);
@@ -540,7 +541,7 @@ int nicvf_initialize(struct udevice *dev)
 
 	if (is_valid_ethaddr(ethaddr)) {
 		memcpy(pdata->enetaddr, ethaddr, ARP_HLEN);
-		eth_env_set_enetaddr_by_index("eth", dev->seq, ethaddr);
+		eth_env_set_enetaddr_by_index("eth", dev_seq(dev), ethaddr);
 	}
 	debug("%s enetaddr %pM ethaddr %pM\n", __func__,
 	      pdata->enetaddr, ethaddr);
diff --git a/drivers/net/octeontx/smi.c b/drivers/net/octeontx/smi.c
index 8e2c3ca5a30..d4baddb7ef5 100644
--- a/drivers/net/octeontx/smi.c
+++ b/drivers/net/octeontx/smi.c
@@ -335,7 +335,7 @@ int octeontx_smi_probe(struct udevice *dev)
 		priv = malloc(sizeof(*priv));
 		if (!bus || !priv) {
 			printf("Failed to allocate OcteonTX MDIO bus # %u\n",
-			       dev->seq);
+			       dev_seq(dev));
 			return -1;
 		}
 
diff --git a/drivers/net/octeontx2/nix.c b/drivers/net/octeontx2/nix.c
index 0a3e8e4af0b..54e1875ce19 100644
--- a/drivers/net/octeontx2/nix.c
+++ b/drivers/net/octeontx2/nix.c
@@ -736,7 +736,7 @@ int nix_lf_setup_mac(struct udevice *dev)
 	 */
 	if (memcmp(nix->lmac->mac_addr, pdata->enetaddr, ARP_HLEN)) {
 		memcpy(nix->lmac->mac_addr, pdata->enetaddr, 6);
-		eth_env_set_enetaddr_by_index("eth", rvu->dev->seq,
+		eth_env_set_enetaddr_by_index("eth", dev_seq(rvu->dev),
 					      pdata->enetaddr);
 		cgx_lmac_mac_filter_setup(nix->lmac);
 		/* Update user given MAC address to ATF for update
diff --git a/drivers/net/octeontx2/rvu_pf.c b/drivers/net/octeontx2/rvu_pf.c
index 201ecf2c168..853914968bb 100644
--- a/drivers/net/octeontx2/rvu_pf.c
+++ b/drivers/net/octeontx2/rvu_pf.c
@@ -34,7 +34,7 @@ int rvu_pf_init(struct rvu_pf *rvu)
 	/* to make post_probe happy */
 	if (is_valid_ethaddr(nix->lmac->mac_addr)) {
 		memcpy(pdata->enetaddr, nix->lmac->mac_addr, 6);
-		eth_env_set_enetaddr_by_index("eth", rvu->dev->seq,
+		eth_env_set_enetaddr_by_index("eth", dev_seq(rvu->dev),
 					      pdata->enetaddr);
 	}
 
@@ -59,7 +59,7 @@ int rvu_pf_probe(struct udevice *dev)
 	debug("%s: name: %s\n", __func__, dev->name);
 
 	rvu->pf_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_2, PCI_REGION_MEM);
-	rvu->pfid = dev->seq + 1; // RVU PF's start from 1;
+	rvu->pfid = dev_seq(dev) + 1; // RVU PF's start from 1;
 	rvu->dev = dev;
 	if (!rvu_af_dev) {
 		printf("%s: Error: Could not find RVU AF device\n",
@@ -80,7 +80,7 @@ int rvu_pf_probe(struct udevice *dev)
 	 * modify device name to include index/sequence number,
 	 * for better readability, this is 1:1 mapping with eth0/1/2.. names.
 	 */
-	sprintf(name, "rvu_pf#%d", dev->seq);
+	sprintf(name, "rvu_pf#%d", dev_seq(dev));
 	device_set_name(dev, name);
 	debug("%s: name: %s\n", __func__, dev->name);
 	return err;
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c
index 8af37112046..3fe9a617f7b 100644
--- a/drivers/net/xilinx_axi_emac.c
+++ b/drivers/net/xilinx_axi_emac.c
@@ -697,7 +697,7 @@ static int axi_emac_probe(struct udevice *dev)
 	priv->bus->write = axiemac_miiphy_write;
 	priv->bus->priv = priv;
 
-	ret = mdio_register_seq(priv->bus, dev->seq);
+	ret = mdio_register_seq(priv->bus, dev_seq(dev));
 	if (ret)
 		return ret;
 
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
index 64c18bae74b..256d073da4a 100644
--- a/drivers/net/xilinx_emaclite.c
+++ b/drivers/net/xilinx_emaclite.c
@@ -568,7 +568,7 @@ static int emaclite_probe(struct udevice *dev)
 	emaclite->bus->write = emaclite_miiphy_write;
 	emaclite->bus->priv = emaclite;
 
-	ret = mdio_register_seq(emaclite->bus, dev->seq);
+	ret = mdio_register_seq(emaclite->bus, dev_seq(dev));
 	if (ret)
 		return ret;
 
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 8afec8bbfcf..75a6f8f280b 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -705,7 +705,7 @@ static int zynq_gem_probe(struct udevice *dev)
 	priv->bus->write = zynq_gem_miiphy_write;
 	priv->bus->priv = priv;
 
-	ret = mdio_register_seq(priv->bus, dev->seq);
+	ret = mdio_register_seq(priv->bus, dev_seq(dev));
 	if (ret)
 		goto err2;
 
diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c
index babb84ca937..0ce60ddf7db 100644
--- a/drivers/pci/pci-aardvark.c
+++ b/drivers/pci/pci-aardvark.c
@@ -638,7 +638,7 @@ static int pcie_advk_probe(struct udevice *dev)
 		dev_warn(pcie->dev, "PCIE Reset on GPIO support is missing\n");
 	}
 
-	pcie->first_busno = dev->seq;
+	pcie->first_busno = dev_seq(dev);
 	pcie->dev = pci_get_controller(dev);
 
 	return pcie_advk_setup_hw(pcie);
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 9230cfe88b5..99dcd342efe 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -65,7 +65,7 @@ pci_dev_t dm_pci_get_bdf(const struct udevice *dev)
 	if (!device_active(bus))
 		log_err("PCI: Device '%s' on unprobed bus '%s'\n", dev->name,
 			bus->name);
-	return PCI_ADD_BUS(bus->seq, pplat->devfn);
+	return PCI_ADD_BUS(dev_seq(bus), pplat->devfn);
 }
 
 /**
@@ -81,8 +81,8 @@ static int pci_get_bus_max(void)
 
 	ret = uclass_get(UCLASS_PCI, &uc);
 	uclass_foreach_dev(bus, uc) {
-		if (bus->seq > ret)
-			ret = bus->seq;
+		if (dev_seq(bus) > ret)
+			ret = dev_seq(bus);
 	}
 
 	debug("%s: ret=%d\n", __func__, ret);
@@ -513,7 +513,7 @@ static void set_vga_bridge_bits(struct udevice *dev)
 	struct udevice *parent = dev->parent;
 	u16 bc;
 
-	while (parent->seq != 0) {
+	while (dev_seq(parent) != 0) {
 		dm_pci_read_config16(parent, PCI_BRIDGE_CONTROL, &bc);
 		bc |= PCI_BRIDGE_CTL_VGA;
 		dm_pci_write_config16(parent, PCI_BRIDGE_CONTROL, bc);
@@ -529,7 +529,7 @@ int pci_auto_config_devices(struct udevice *bus)
 	struct udevice *dev;
 	int ret;
 
-	sub_bus = bus->seq;
+	sub_bus = dev_seq(bus);
 	debug("%s: start\n", __func__);
 	pciauto_config_init(hose);
 	for (ret = device_find_first_child(bus, &dev);
@@ -645,9 +645,9 @@ int dm_pci_hose_probe_bus(struct udevice *bus)
 	}
 
 	if (!ea_pos) {
-		if (sub_bus != bus->seq) {
+		if (sub_bus != dev_seq(bus)) {
 			debug("%s: Internal error, bus '%s' got seq %d, expected %d\n",
-			      __func__, bus->name, bus->seq, sub_bus);
+			      __func__, bus->name, dev_seq(bus), sub_bus);
 			return -EPIPE;
 		}
 		sub_bus = pci_get_bus_max();
@@ -771,7 +771,7 @@ static int pci_find_and_bind_driver(struct udevice *parent,
 		return -EPERM;
 
 	/* Bind a generic driver so that the device can be used */
-	sprintf(name, "pci_%x:%x.%x", parent->seq, PCI_DEV(bdf),
+	sprintf(name, "pci_%x:%x.%x", dev_seq(parent), PCI_DEV(bdf),
 		PCI_FUNC(bdf));
 	str = strdup(name);
 	if (!str)
@@ -803,9 +803,9 @@ int pci_bind_bus_devices(struct udevice *bus)
 	int ret;
 
 	found_multi = false;
-	end = PCI_BDF(bus->seq, PCI_MAX_PCI_DEVICES - 1,
+	end = PCI_BDF(dev_seq(bus), PCI_MAX_PCI_DEVICES - 1,
 		      PCI_MAX_PCI_FUNCTIONS - 1);
-	for (bdf = PCI_BDF(bus->seq, 0, 0); bdf <= end;
+	for (bdf = PCI_BDF(dev_seq(bus), 0, 0); bdf <= end;
 	     bdf += PCI_BDF(0, 0, 1)) {
 		struct pci_child_platdata *pplat;
 		struct udevice *dev;
@@ -832,7 +832,7 @@ int pci_bind_bus_devices(struct udevice *bus)
 			found_multi = header_type & 0x80;
 
 		debug("%s: bus %d/%s: found device %x, function %d", __func__,
-		      bus->seq, bus->name, PCI_DEV(bdf), PCI_FUNC(bdf));
+		      dev_seq(bus), bus->name, PCI_DEV(bdf), PCI_FUNC(bdf));
 		pci_bus_read_config(bus, bdf, PCI_DEVICE_ID, &device,
 				    PCI_SIZE_16);
 		pci_bus_read_config(bus, bdf, PCI_CLASS_REVISION, &class,
@@ -1010,7 +1010,7 @@ static int pci_uclass_pre_probe(struct udevice *bus)
 {
 	struct pci_controller *hose;
 
-	debug("%s, bus=%d/%s, parent=%s\n", __func__, bus->seq, bus->name,
+	debug("%s, bus=%d/%s, parent=%s\n", __func__, dev_seq(bus), bus->name,
 	      bus->parent->name);
 	hose = bus->uclass_priv;
 
@@ -1025,8 +1025,8 @@ static int pci_uclass_pre_probe(struct udevice *bus)
 		hose->ctlr = parent_hose->bus;
 	}
 	hose->bus = bus;
-	hose->first_busno = bus->seq;
-	hose->last_busno = bus->seq;
+	hose->first_busno = dev_seq(bus);
+	hose->last_busno = dev_seq(bus);
 	if (dev_of_valid(bus)) {
 		hose->skip_auto_config_until_reloc =
 			dev_read_bool(bus,
@@ -1041,7 +1041,7 @@ static int pci_uclass_post_probe(struct udevice *bus)
 	struct pci_controller *hose = dev_get_uclass_priv(bus);
 	int ret;
 
-	debug("%s: probing bus %d\n", __func__, bus->seq);
+	debug("%s: probing bus %d\n", __func__, dev_seq(bus));
 	ret = pci_bind_bus_devices(bus);
 	if (ret)
 		return ret;
@@ -1068,7 +1068,7 @@ static int pci_uclass_post_probe(struct udevice *bus)
 	 * Note we only call this 1) after U-Boot is relocated, and 2)
 	 * root bus has finished probing.
 	 */
-	if ((gd->flags & GD_FLG_RELOC) && bus->seq == 0 && ll_boot_init()) {
+	if ((gd->flags & GD_FLG_RELOC) && dev_seq(bus) == 0 && ll_boot_init()) {
 		ret = fsp_init_phase_pci();
 		if (ret)
 			return ret;
@@ -1732,7 +1732,7 @@ int pci_sriov_init(struct udevice *pdev, int vf_en)
 				    &class, PCI_SIZE_16);
 
 		debug("%s: bus %d/%s: found VF %x:%x\n", __func__,
-		      bus->seq, bus->name, PCI_DEV(bdf), PCI_FUNC(bdf));
+		      dev_seq(bus), bus->name, PCI_DEV(bdf), PCI_FUNC(bdf));
 
 		/* Find this device in the device tree */
 		ret = pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), &dev);
@@ -1763,7 +1763,7 @@ int pci_sriov_init(struct udevice *pdev, int vf_en)
 		pplat->virtid = vf * vf_stride + vf_offset;
 
 		debug("%s: bus %d/%s: found VF %x:%x %x:%x class %lx id %x\n",
-		      __func__, dev->seq, dev->name, PCI_DEV(bdf),
+		      __func__, dev_seq(dev), dev->name, PCI_DEV(bdf),
 		      PCI_FUNC(bdf), vendor, device, class, pplat->virtid);
 		bdf += PCI_BDF(0, 0, vf_stride);
 	}
diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c
index 3f46b7697d7..4d797ec034b 100644
--- a/drivers/pci/pci_auto.c
+++ b/drivers/pci/pci_auto.c
@@ -189,8 +189,8 @@ void dm_pciauto_prescan_setup_bridge(struct udevice *dev, int sub_bus)
 
 	/* Configure bus number registers */
 	dm_pci_write_config8(dev, PCI_PRIMARY_BUS,
-			     PCI_BUS(dm_pci_get_bdf(dev)) - ctlr->seq);
-	dm_pci_write_config8(dev, PCI_SECONDARY_BUS, sub_bus - ctlr->seq);
+			     PCI_BUS(dm_pci_get_bdf(dev)) - dev_seq(ctlr));
+	dm_pci_write_config8(dev, PCI_SECONDARY_BUS, sub_bus - dev_seq(ctlr));
 	dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, 0xff);
 
 	if (pci_mem) {
@@ -265,7 +265,7 @@ void dm_pciauto_postscan_setup_bridge(struct udevice *dev, int sub_bus)
 	pci_io = ctlr_hose->pci_io;
 
 	/* Configure bus number registers */
-	dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, sub_bus - ctlr->seq);
+	dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, sub_bus - dev_seq(ctlr));
 
 	if (pci_mem) {
 		/* Round memory allocator to 1MB boundary */
diff --git a/drivers/pci/pcie_dw_mvebu.c b/drivers/pci/pcie_dw_mvebu.c
index c773f8d28d2..8fbc8fb7d0a 100644
--- a/drivers/pci/pcie_dw_mvebu.c
+++ b/drivers/pci/pcie_dw_mvebu.c
@@ -500,13 +500,13 @@ static int pcie_dw_mvebu_probe(struct udevice *dev)
 	debug("PCIE Reset on GPIO support is missing\n");
 #endif /* DM_GPIO */
 
-	pcie->first_busno = dev->seq;
+	pcie->first_busno = dev_seq(dev);
 
 	/* Don't register host if link is down */
 	if (!pcie_dw_mvebu_pcie_link_up(pcie->ctrl_base, LINK_SPEED_GEN_3)) {
-		printf("PCIE-%d: Link down\n", dev->seq);
+		printf("PCIE-%d: Link down\n", dev_seq(dev));
 	} else {
-		printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n", dev->seq,
+		printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n", dev_seq(dev),
 		       pcie_dw_get_link_speed(pcie->ctrl_base),
 		       pcie_dw_get_link_width(pcie->ctrl_base),
 		       hose->first_busno);
diff --git a/drivers/pci/pcie_dw_ti.c b/drivers/pci/pcie_dw_ti.c
index 742dd93633e..e0635e07c21 100644
--- a/drivers/pci/pcie_dw_ti.c
+++ b/drivers/pci/pcie_dw_ti.c
@@ -634,7 +634,7 @@ static int pcie_dw_ti_probe(struct udevice *dev)
 	generic_phy_init(&phy1);
 	generic_phy_power_on(&phy1);
 
-	pci->first_busno = dev->seq;
+	pci->first_busno = dev_seq(dev);
 	pci->dev = dev;
 
 	pcie_dw_setup_host(pci);
@@ -644,11 +644,11 @@ static int pcie_dw_ti_probe(struct udevice *dev)
 		pcie_am654_set_mode(pci, DW_PCIE_RC_TYPE);
 
 	if (!pcie_dw_ti_pcie_link_up(pci, LINK_SPEED_GEN_2)) {
-		printf("PCIE-%d: Link down\n", dev->seq);
+		printf("PCIE-%d: Link down\n", dev_seq(dev));
 		return -ENODEV;
 	}
 
-	printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n", dev->seq,
+	printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n", dev_seq(dev),
 	       pcie_dw_get_link_speed(pci),
 	       pcie_dw_get_link_width(pci),
 	       hose->first_busno);
diff --git a/drivers/pci/pcie_ecam_generic.c b/drivers/pci/pcie_ecam_generic.c
index 890b6a8fb69..96afa4263df 100644
--- a/drivers/pci/pcie_ecam_generic.c
+++ b/drivers/pci/pcie_ecam_generic.c
@@ -146,7 +146,7 @@ static int pci_generic_ecam_probe(struct udevice *dev)
 {
 	struct generic_ecam_pcie *pcie = dev_get_priv(dev);
 
-	pcie->first_busno = dev->seq;
+	pcie->first_busno = dev_seq(dev);
 
 	return 0;
 }
diff --git a/drivers/pci/pcie_fsl.c b/drivers/pci/pcie_fsl.c
index fb50b8f5180..da6a6b15534 100644
--- a/drivers/pci/pcie_fsl.c
+++ b/drivers/pci/pcie_fsl.c
@@ -29,16 +29,16 @@ static int fsl_pcie_addr_valid(struct fsl_pcie *pcie, pci_dev_t bdf)
 	if (!pcie->enabled)
 		return -ENXIO;
 
-	if (PCI_BUS(bdf) < bus->seq)
+	if (PCI_BUS(bdf) < dev_seq(bus))
 		return -EINVAL;
 
-	if (PCI_BUS(bdf) > bus->seq && (!fsl_pcie_link_up(pcie) || pcie->mode))
+	if (PCI_BUS(bdf) > dev_seq(bus) && (!fsl_pcie_link_up(pcie) || pcie->mode))
 		return -EINVAL;
 
-	if (PCI_BUS(bdf) == bus->seq && (PCI_DEV(bdf) > 0 || PCI_FUNC(bdf) > 0))
+	if (PCI_BUS(bdf) == dev_seq(bus) && (PCI_DEV(bdf) > 0 || PCI_FUNC(bdf) > 0))
 		return -EINVAL;
 
-	if (PCI_BUS(bdf) == (bus->seq + 1) && (PCI_DEV(bdf) > 0))
+	if (PCI_BUS(bdf) == (dev_seq(bus) + 1) && (PCI_DEV(bdf) > 0))
 		return -EINVAL;
 
 	return 0;
@@ -57,7 +57,7 @@ static int fsl_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
 		return 0;
 	}
 
-	bdf = bdf - PCI_BDF(bus->seq, 0, 0);
+	bdf = bdf - PCI_BDF(dev_seq(bus), 0, 0);
 	val = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000;
 	out_be32(&regs->cfg_addr, val);
 
@@ -93,7 +93,7 @@ static int fsl_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
 	if (fsl_pcie_addr_valid(pcie, bdf))
 		return 0;
 
-	bdf = bdf - PCI_BDF(bus->seq, 0, 0);
+	bdf = bdf - PCI_BDF(dev_seq(bus), 0, 0);
 	val = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000;
 	out_be32(&regs->cfg_addr, val);
 
@@ -123,7 +123,7 @@ static int fsl_pcie_hose_read_config(struct fsl_pcie *pcie, uint offset,
 	int ret;
 	struct udevice *bus = pcie->bus;
 
-	ret = fsl_pcie_read_config(bus, PCI_BDF(bus->seq, 0, 0),
+	ret = fsl_pcie_read_config(bus, PCI_BDF(dev_seq(bus), 0, 0),
 				   offset, valuep, size);
 
 	return ret;
@@ -134,7 +134,7 @@ static int fsl_pcie_hose_write_config(struct fsl_pcie *pcie, uint offset,
 {
 	struct udevice *bus = pcie->bus;
 
-	return fsl_pcie_write_config(bus, PCI_BDF(bus->seq, 0, 0),
+	return fsl_pcie_write_config(bus, PCI_BDF(dev_seq(bus), 0, 0),
 				     offset, value, size);
 }
 
diff --git a/drivers/pci/pcie_intel_fpga.c b/drivers/pci/pcie_intel_fpga.c
index 9f102c64c60..cafb02195f0 100644
--- a/drivers/pci/pcie_intel_fpga.c
+++ b/drivers/pci/pcie_intel_fpga.c
@@ -369,7 +369,7 @@ static int pcie_intel_fpga_probe(struct udevice *dev)
 	struct intel_fpga_pcie *pcie = dev_get_priv(dev);
 
 	pcie->bus = pci_get_controller(dev);
-	pcie->first_busno = dev->seq;
+	pcie->first_busno = dev_seq(dev);
 
 	/* clear all interrupts */
 	cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
diff --git a/drivers/pci/pcie_layerscape_fixup.c b/drivers/pci/pcie_layerscape_fixup.c
index c75cf26e0a5..a58e7a3892a 100644
--- a/drivers/pci/pcie_layerscape_fixup.c
+++ b/drivers/pci/pcie_layerscape_fixup.c
@@ -479,7 +479,7 @@ static int fdt_fixup_pci_vfs(void *blob, struct extra_iommu_entry *entry,
 	for (bus = dev; device_is_on_pci_bus(bus);)
 		bus = bus->parent;
 
-	bdf = entry->bdf - PCI_BDF(bus->seq, 0, 0) + (vf_offset << 8);
+	bdf = entry->bdf - PCI_BDF(dev_seq(bus), 0, 0) + (vf_offset << 8);
 
 	for (i = 0; i < entry->num_vfs; i++) {
 		if (fdt_fixup_pcie_device_ls(blob, bdf, pcie_rc) < 0)
@@ -518,7 +518,7 @@ static void fdt_fixup_pcie_ls(void *blob)
 		pcie_rc = dev_get_priv(bus);
 
 		/* the DT fixup must be relative to the hose first_busno */
-		bdf = dm_pci_get_bdf(dev) - PCI_BDF(bus->seq, 0, 0);
+		bdf = dm_pci_get_bdf(dev) - PCI_BDF(dev_seq(bus), 0, 0);
 
 		if (fdt_fixup_pcie_device_ls(blob, bdf, pcie_rc) < 0)
 			break;
diff --git a/drivers/pci/pcie_layerscape_gen4.c b/drivers/pci/pcie_layerscape_gen4.c
index 428bfcab09f..d6efdd3ed63 100644
--- a/drivers/pci/pcie_layerscape_gen4.c
+++ b/drivers/pci/pcie_layerscape_gen4.c
@@ -191,13 +191,13 @@ static int ls_pcie_g4_addr_valid(struct ls_pcie_g4 *pcie, pci_dev_t bdf)
 	if (!pcie->enabled)
 		return -ENXIO;
 
-	if (PCI_BUS(bdf) < bus->seq)
+	if (PCI_BUS(bdf) < dev_seq(bus))
 		return -EINVAL;
 
-	if ((PCI_BUS(bdf) > bus->seq) && (!ls_pcie_g4_link_up(pcie)))
+	if ((PCI_BUS(bdf) > dev_seq(bus)) && (!ls_pcie_g4_link_up(pcie)))
 		return -EINVAL;
 
-	if (PCI_BUS(bdf) <= (bus->seq + 1) && (PCI_DEV(bdf) > 0))
+	if (PCI_BUS(bdf) <= (dev_seq(bus) + 1) && (PCI_DEV(bdf) > 0))
 		return -EINVAL;
 
 	return 0;
@@ -209,7 +209,7 @@ void *ls_pcie_g4_conf_address(struct ls_pcie_g4 *pcie, pci_dev_t bdf,
 	struct udevice *bus = pcie->bus;
 	u32 target;
 
-	if (PCI_BUS(bdf) == bus->seq) {
+	if (PCI_BUS(bdf) == dev_seq(bus)) {
 		if (offset < INDIRECT_ADDR_BNDRY) {
 			ccsr_set_page(pcie, 0);
 			return pcie->ccsr + offset;
@@ -219,7 +219,7 @@ void *ls_pcie_g4_conf_address(struct ls_pcie_g4 *pcie, pci_dev_t bdf,
 		return pcie->ccsr + OFFSET_TO_PAGE_ADDR(offset);
 	}
 
-	target = PAB_TARGET_BUS(PCI_BUS(bdf) - bus->seq) |
+	target = PAB_TARGET_BUS(PCI_BUS(bdf) - dev_seq(bus)) |
 		 PAB_TARGET_DEV(PCI_DEV(bdf)) |
 		 PAB_TARGET_FUNC(PCI_FUNC(bdf));
 
diff --git a/drivers/pci/pcie_layerscape_gen4_fixup.c b/drivers/pci/pcie_layerscape_gen4_fixup.c
index 148b5d17ed0..e9ee15558e5 100644
--- a/drivers/pci/pcie_layerscape_gen4_fixup.c
+++ b/drivers/pci/pcie_layerscape_gen4_fixup.c
@@ -166,7 +166,7 @@ static void fdt_fixup_pcie_ls_gen4(void *blob)
 		}
 
 		/* the DT fixup must be relative to the hose first_busno */
-		bdf = dm_pci_get_bdf(dev) - PCI_BDF(bus->seq, 0, 0);
+		bdf = dm_pci_get_bdf(dev) - PCI_BDF(dev_seq(bus), 0, 0);
 		/* map PCI b.d.f to streamID in LUT */
 		ls_pcie_g4_lut_set_mapping(pcie, index, bdf >> 8, streamid);
 		/* update msi-map in device tree */
diff --git a/drivers/pci/pcie_layerscape_rc.c b/drivers/pci/pcie_layerscape_rc.c
index 25c6ddebce0..241acbdc449 100644
--- a/drivers/pci/pcie_layerscape_rc.c
+++ b/drivers/pci/pcie_layerscape_rc.c
@@ -130,13 +130,13 @@ static int ls_pcie_addr_valid(struct ls_pcie_rc *pcie_rc, pci_dev_t bdf)
 	if (!pcie_rc->enabled)
 		return -ENXIO;
 
-	if (PCI_BUS(bdf) < bus->seq)
+	if (PCI_BUS(bdf) < dev_seq(bus))
 		return -EINVAL;
 
-	if ((PCI_BUS(bdf) > bus->seq) && (!ls_pcie_link_up(pcie)))
+	if ((PCI_BUS(bdf) > dev_seq(bus)) && (!ls_pcie_link_up(pcie)))
 		return -EINVAL;
 
-	if (PCI_BUS(bdf) <= (bus->seq + 1) && (PCI_DEV(bdf) > 0))
+	if (PCI_BUS(bdf) <= (dev_seq(bus) + 1) && (PCI_DEV(bdf) > 0))
 		return -EINVAL;
 
 	return 0;
@@ -152,16 +152,16 @@ int ls_pcie_conf_address(const struct udevice *bus, pci_dev_t bdf,
 	if (ls_pcie_addr_valid(pcie_rc, bdf))
 		return -EINVAL;
 
-	if (PCI_BUS(bdf) == bus->seq) {
+	if (PCI_BUS(bdf) == dev_seq(bus)) {
 		*paddress = pcie->dbi + offset;
 		return 0;
 	}
 
-	busdev = PCIE_ATU_BUS(PCI_BUS(bdf) - bus->seq) |
+	busdev = PCIE_ATU_BUS(PCI_BUS(bdf) - dev_seq(bus)) |
 		 PCIE_ATU_DEV(PCI_DEV(bdf)) |
 		 PCIE_ATU_FUNC(PCI_FUNC(bdf));
 
-	if (PCI_BUS(bdf) == bus->seq + 1) {
+	if (PCI_BUS(bdf) == dev_seq(bus) + 1) {
 		ls_pcie_cfg0_set_busdev(pcie_rc, busdev);
 		*paddress = pcie_rc->cfg0 + offset;
 	} else {
diff --git a/drivers/pci/pcie_mediatek.c b/drivers/pci/pcie_mediatek.c
index 55b6a40f254..5bd11661c3c 100644
--- a/drivers/pci/pcie_mediatek.c
+++ b/drivers/pci/pcie_mediatek.c
@@ -261,7 +261,7 @@ static struct mtk_pcie_port *mtk_pcie_find_port(const struct udevice *bus,
 			return NULL;
 		}
 
-		while (dev->parent->seq != 0)
+		while (dev_seq(dev->parent) != 0)
 			dev = dev->parent;
 
 		pplat = dev_get_parent_platdata(dev);
diff --git a/drivers/pci/pcie_rockchip.c b/drivers/pci/pcie_rockchip.c
index 04609f12962..96173b81cc3 100644
--- a/drivers/pci/pcie_rockchip.c
+++ b/drivers/pci/pcie_rockchip.c
@@ -373,7 +373,7 @@ static int rockchip_pcie_init_port(struct udevice *dev)
 	/* Configure Address Translation. */
 	ret = rockchip_pcie_atr_init(priv);
 	if (ret) {
-		dev_err(dev, "PCIE-%d: ATR init failed\n", dev->seq);
+		dev_err(dev, "PCIE-%d: ATR init failed\n", dev_seq(dev));
 		goto err_power_off_phy;
 	}
 
@@ -528,7 +528,7 @@ static int rockchip_pcie_probe(struct udevice *dev)
 	struct pci_controller *hose = dev_get_uclass_priv(ctlr);
 	int ret;
 
-	priv->first_busno = dev->seq;
+	priv->first_busno = dev_seq(dev);
 	priv->dev = dev;
 
 	ret = rockchip_pcie_parse_dt(dev);
@@ -544,7 +544,7 @@ static int rockchip_pcie_probe(struct udevice *dev)
 		return ret;
 
 	dev_info(dev, "PCIE-%d: Link up (Bus%d)\n",
-		 dev->seq, hose->first_busno);
+		 dev_seq(dev), hose->first_busno);
 
 	return 0;
 }
diff --git a/drivers/serial/serial_mcf.c b/drivers/serial/serial_mcf.c
index 402fd5343c1..dee1706a218 100644
--- a/drivers/serial/serial_mcf.c
+++ b/drivers/serial/serial_mcf.c
@@ -85,7 +85,7 @@ static int coldfire_serial_probe(struct udevice *dev)
 {
 	struct coldfire_serial_platdata *plat = dev->platdata;
 
-	plat->port = dev->seq;
+	plat->port = dev_seq(dev);
 
 	return mcf_serial_init_common((uart_t *)plat->base,
 						plat->port, plat->baudrate);
diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c
index 9bb2be21e7b..57eb6963b61 100644
--- a/drivers/serial/serial_s5p.c
+++ b/drivers/serial/serial_s5p.c
@@ -187,7 +187,7 @@ static int s5p_serial_ofdata_to_platdata(struct udevice *dev)
 
 	plat->reg = (struct s5p_uart *)addr;
 	plat->port_id = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-					"id", dev->seq);
+					"id", dev_seq(dev));
 	return 0;
 }
 
diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c
index 61372c52b05..1529002cac1 100644
--- a/drivers/spi/altera_spi.c
+++ b/drivers/spi/altera_spi.c
@@ -98,7 +98,7 @@ static int altera_spi_xfer(struct udevice *dev, unsigned int bitlen,
 	uint32_t reg, data, start;
 
 	debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
-	      bus->seq, slave_plat->cs, bitlen, bytes, flags);
+	      dev_seq(bus), slave_plat->cs, bitlen, bytes, flags);
 
 	if (bitlen == 0)
 		goto done;
diff --git a/drivers/spi/cf_spi.c b/drivers/spi/cf_spi.c
index 8fa6d351075..8f1c8b8c0fb 100644
--- a/drivers/spi/cf_spi.c
+++ b/drivers/spi/cf_spi.c
@@ -240,7 +240,7 @@ static int coldfire_spi_set_speed(struct udevice *bus, uint max_hz)
 	cfspi->baudrate = max_hz;
 
 	/* Read current setup */
-	bus_setup = readl(&dspi->ctar[bus->seq]);
+	bus_setup = readl(&dspi->ctar[dev_seq(bus)]);
 
 	tmp = (prescaler[3] * scaler[15]);
 	/* Maximum and minimum baudrate it can handle */
@@ -294,7 +294,7 @@ static int coldfire_spi_set_speed(struct udevice *bus, uint max_hz)
 
 	bus_setup &= ~(DSPI_CTAR_PBR(0x03) | DSPI_CTAR_BR(0x0f));
 	bus_setup |= (DSPI_CTAR_PBR(best_i) | DSPI_CTAR_BR(best_j));
-	writel(bus_setup, &dspi->ctar[bus->seq]);
+	writel(bus_setup, &dspi->ctar[dev_seq(bus)]);
 
 	return 0;
 }
@@ -318,7 +318,7 @@ static int coldfire_spi_set_mode(struct udevice *bus, uint mode)
 	if (cfspi->mode & SPI_MODE_MOD) {
 		if ((cfspi->mode & SPI_MODE_XFER_SZ_MASK) == 0)
 			bus_setup |=
-			    readl(&dspi->ctar[bus->seq]) & MCF_FRM_SZ_16BIT;
+			    readl(&dspi->ctar[dev_seq(bus)]) & MCF_FRM_SZ_16BIT;
 		else
 			bus_setup |=
 			    ((cfspi->mode & SPI_MODE_XFER_SZ_MASK) >> 1);
@@ -329,14 +329,14 @@ static int coldfire_spi_set_mode(struct udevice *bus, uint mode)
 		bus_setup |= (cfspi->mode & SPI_MODE_DLY_SCA_MASK) >> 4;
 	} else {
 		bus_setup |=
-			(readl(&dspi->ctar[bus->seq]) & MCF_CTAR_MODE_MASK);
+			(readl(&dspi->ctar[dev_seq(bus)]) & MCF_CTAR_MODE_MASK);
 	}
 
 	cfspi->charbit =
-		((readl(&dspi->ctar[bus->seq]) & MCF_FRM_SZ_16BIT) ==
+		((readl(&dspi->ctar[dev_seq(bus)]) & MCF_FRM_SZ_16BIT) ==
 			MCF_FRM_SZ_16BIT) ? 16 : 8;
 
-	setbits_be32(&dspi->ctar[bus->seq], bus_setup);
+	setbits_be32(&dspi->ctar[dev_seq(bus)], bus_setup);
 
 	return 0;
 }
diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c
index b22c9b3a09d..71b045e04cb 100644
--- a/drivers/spi/fsl_dspi.c
+++ b/drivers/spi/fsl_dspi.c
@@ -511,7 +511,7 @@ static int fsl_dspi_probe(struct udevice *bus)
 		DSPI_MCR_CRXF | DSPI_MCR_CTXF;
 	fsl_dspi_init_mcr(priv, mcr_cfg_val);
 
-	debug("%s probe done, bus-num %d.\n", bus->name, bus->seq);
+	debug("%s probe done, bus-num %d.\n", bus->name, dev_seq(bus));
 
 	return 0;
 }
@@ -527,7 +527,7 @@ static int fsl_dspi_claim_bus(struct udevice *dev)
 	priv = dev_get_priv(bus);
 
 	/* processor special preparation work */
-	cpu_dspi_claim_bus(bus->seq, slave_plat->cs);
+	cpu_dspi_claim_bus(dev_seq(bus), slave_plat->cs);
 
 	/* configure transfer mode */
 	fsl_dspi_cfg_ctar_mode(priv, slave_plat->cs, priv->mode);
@@ -559,7 +559,7 @@ static int fsl_dspi_release_bus(struct udevice *dev)
 	dspi_halt(priv, 1);
 
 	/* processor special release work */
-	cpu_dspi_release_bus(bus->seq, slave_plat->cs);
+	cpu_dspi_release_bus(dev_seq(bus), slave_plat->cs);
 
 	return 0;
 }
diff --git a/drivers/spi/fsl_espi.c b/drivers/spi/fsl_espi.c
index 5c76fd962e9..5cd6577b85a 100644
--- a/drivers/spi/fsl_espi.c
+++ b/drivers/spi/fsl_espi.c
@@ -527,7 +527,7 @@ static int fsl_espi_probe(struct udevice *bus)
 	fsl->max_transfer_length = ESPI_MAX_DATA_TRANSFER_LEN;
 	fsl->speed_hz = plat->speed_hz;
 
-	debug("%s probe done, bus-num %d.\n", bus->name, bus->seq);
+	debug("%s probe done, bus-num %d.\n", bus->name, dev_seq(bus));
 
 	return 0;
 }
diff --git a/drivers/spi/octeon_spi.c b/drivers/spi/octeon_spi.c
index 7e88e5580f7..249b9690bea 100644
--- a/drivers/spi/octeon_spi.c
+++ b/drivers/spi/octeon_spi.c
@@ -593,7 +593,7 @@ static int octeon_spi_probe(struct udevice *dev)
 	if (ret)
 		return ret;
 
-	debug("SPI bus %s %d at %p\n", dev->name, dev->seq, priv->base);
+	debug("SPI bus %s %d at %p\n", dev->name, dev_seq(dev), priv->base);
 
 	return 0;
 }
diff --git a/drivers/spi/pic32_spi.c b/drivers/spi/pic32_spi.c
index 52e9eff743c..97c2f939c0f 100644
--- a/drivers/spi/pic32_spi.c
+++ b/drivers/spi/pic32_spi.c
@@ -247,7 +247,7 @@ static int pic32_spi_xfer(struct udevice *slave, unsigned int bitlen,
 	slave_plat = dev_get_parent_platdata(slave);
 
 	debug("spi_xfer: bus:%i cs:%i flags:%lx\n",
-	      bus->seq, slave_plat->cs, flags);
+	      dev_seq(bus), slave_plat->cs, flags);
 	debug("msg tx %p, rx %p submitted of %d byte(s)\n",
 	      tx_buf, rx_buf, len);
 
@@ -384,7 +384,7 @@ static int pic32_spi_probe(struct udevice *bus)
 	fdt_size_t size;
 	int ret;
 
-	debug("%s: %d, bus: %i\n", __func__, __LINE__, bus->seq);
+	debug("%s: %d, bus: %i\n", __func__, __LINE__, dev_seq(bus));
 	addr = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
 	if (addr == FDT_ADDR_T_NONE)
 		return -EINVAL;
diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c
index 755f1768614..3c780bae71b 100644
--- a/drivers/spi/sandbox_spi.c
+++ b/drivers/spi/sandbox_spi.c
@@ -72,7 +72,7 @@ static int sandbox_spi_xfer(struct udevice *slave, unsigned int bitlen,
 		return -EINVAL;
 	}
 
-	busnum = bus->seq;
+	busnum = dev_seq(bus);
 	cs = spi_chip_select(slave);
 	if (busnum >= CONFIG_SANDBOX_SPI_MAX_BUS ||
 	    cs >= CONFIG_SANDBOX_SPI_MAX_CS) {
diff --git a/drivers/spi/tegra114_spi.c b/drivers/spi/tegra114_spi.c
index 0e8198c5a02..0c99dfde201 100644
--- a/drivers/spi/tegra114_spi.c
+++ b/drivers/spi/tegra114_spi.c
@@ -231,7 +231,7 @@ static int tegra114_spi_xfer(struct udevice *dev, unsigned int bitlen,
 	int ret;
 
 	debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
-	      __func__, bus->seq, spi_chip_select(dev), dout, din, bitlen);
+	      __func__, dev_seq(bus), spi_chip_select(dev), dout, din, bitlen);
 	if (bitlen % 8)
 		return -1;
 	num_bytes = bitlen / 8;
diff --git a/drivers/spi/tegra20_sflash.c b/drivers/spi/tegra20_sflash.c
index 771744dfe43..722a1203462 100644
--- a/drivers/spi/tegra20_sflash.c
+++ b/drivers/spi/tegra20_sflash.c
@@ -217,7 +217,7 @@ static int tegra20_sflash_xfer(struct udevice *dev, unsigned int bitlen,
 	int ret;
 
 	debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
-	      __func__, bus->seq, spi_chip_select(dev), dout, din, bitlen);
+	      __func__, dev_seq(bus), spi_chip_select(dev), dout, din, bitlen);
 	if (bitlen % 8)
 		return -1;
 	num_bytes = bitlen / 8;
diff --git a/drivers/spi/tegra20_slink.c b/drivers/spi/tegra20_slink.c
index f9846ee3665..d051e93c533 100644
--- a/drivers/spi/tegra20_slink.c
+++ b/drivers/spi/tegra20_slink.c
@@ -211,7 +211,7 @@ static int tegra30_spi_xfer(struct udevice *dev, unsigned int bitlen,
 	int ret;
 
 	debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
-	      __func__, bus->seq, spi_chip_select(dev), dout, din, bitlen);
+	      __func__, dev_seq(bus), spi_chip_select(dev), dout, din, bitlen);
 	if (bitlen % 8)
 		return -1;
 	num_bytes = bitlen / 8;
diff --git a/drivers/spi/tegra210_qspi.c b/drivers/spi/tegra210_qspi.c
index ae16b45dcb4..ce08637c711 100644
--- a/drivers/spi/tegra210_qspi.c
+++ b/drivers/spi/tegra210_qspi.c
@@ -223,7 +223,7 @@ static int tegra210_qspi_xfer(struct udevice *dev, unsigned int bitlen,
 	int num_bytes, tm, ret;
 
 	debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
-	      __func__, bus->seq, spi_chip_select(dev), dout, din, bitlen);
+	      __func__, dev_seq(bus), spi_chip_select(dev), dout, din, bitlen);
 	if (bitlen % 8)
 		return -1;
 	num_bytes = bitlen / 8;
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c
index 47a5571aecd..5b630073401 100644
--- a/drivers/spi/xilinx_spi.c
+++ b/drivers/spi/xilinx_spi.c
@@ -255,7 +255,7 @@ static int xilinx_spi_xfer(struct udevice *dev, unsigned int bitlen,
 	int ret;
 
 	debug("spi_xfer: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n",
-	      bus->seq, slave_plat->cs, bitlen, bytes, flags);
+	      dev_seq(bus), slave_plat->cs, bitlen, bytes, flags);
 
 	if (bitlen == 0)
 		goto done;
diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c
index f2eddec950a..7e2d4e088ee 100644
--- a/drivers/spi/zynq_qspi.c
+++ b/drivers/spi/zynq_qspi.c
@@ -568,7 +568,7 @@ static int zynq_qspi_xfer(struct udevice *dev, unsigned int bitlen,
 	priv->len = bitlen / 8;
 
 	debug("zynq_qspi_xfer: bus:%i cs:%i bitlen:%i len:%i flags:%lx\n",
-	      bus->seq, slave_plat->cs, bitlen, priv->len, flags);
+	      dev_seq(bus), slave_plat->cs, bitlen, priv->len, flags);
 
 	/*
 	 * Festering sore.
diff --git a/drivers/spi/zynq_spi.c b/drivers/spi/zynq_spi.c
index cb911c34f68..ad7cec86e44 100644
--- a/drivers/spi/zynq_spi.c
+++ b/drivers/spi/zynq_spi.c
@@ -242,7 +242,7 @@ static int zynq_spi_xfer(struct udevice *dev, unsigned int bitlen,
 	u32 ts, status;
 
 	debug("spi_xfer: bus:%i cs:%i bitlen:%i len:%i flags:%lx\n",
-	      bus->seq, slave_plat->cs, bitlen, len, flags);
+	      dev_seq(bus), slave_plat->cs, bitlen, len, flags);
 
 	if (bitlen % 8) {
 		debug("spi_xfer: Non byte aligned SPI transfer\n");
diff --git a/drivers/usb/gadget/max3420_udc.c b/drivers/usb/gadget/max3420_udc.c
index b38b9dc68f7..156bb1ebebd 100644
--- a/drivers/usb/gadget/max3420_udc.c
+++ b/drivers/usb/gadget/max3420_udc.c
@@ -821,7 +821,7 @@ static int max3420_udc_probe(struct udevice *dev)
 	struct max3420_udc *udc = dev_get_priv(dev);
 	struct dm_spi_slave_platdata *slave_pdata;
 	struct udevice *bus = dev->parent;
-	int busnum = bus->seq;
+	int busnum = dev_seq(bus);
 	unsigned int cs;
 	uint speed, mode;
 	struct udevice *spid;
diff --git a/drivers/usb/host/ehci-mx5.c b/drivers/usb/host/ehci-mx5.c
index caafa688993..51377487d4b 100644
--- a/drivers/usb/host/ehci-mx5.c
+++ b/drivers/usb/host/ehci-mx5.c
@@ -321,7 +321,7 @@ static int ehci_usb_probe(struct udevice *dev)
 	mdelay(1);
 
 	priv->ehci = ehci;
-	priv->portnr = dev->seq;
+	priv->portnr = dev_seq(dev);
 	priv->init_type = type;
 
 	ret = device_get_supply_regulator(dev, "vbus-supply",
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index 37b59758bb3..8fa136f4eeb 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -596,7 +596,7 @@ static int ehci_usb_probe(struct udevice *dev)
 	}
 
 	priv->ehci = ehci;
-	priv->portnr = dev->seq;
+	priv->portnr = dev_seq(dev);
 	priv->init_type = type;
 
 #if CONFIG_IS_ENABLED(DM_REGULATOR)
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 82b99eeef1e..a2c0caf1bcc 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -383,7 +383,7 @@ static int omap_ehci_probe(struct udevice *dev)
 	struct ehci_hcor *hcor;
 
 	priv->ehci = dev_read_addr_ptr(dev);
-	priv->portnr = dev->seq;
+	priv->portnr = dev_seq(dev);
 	priv->init_type = plat->init_type;
 
 	hccr = (struct ehci_hccr *)&priv->ehci->hccapbase;
diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index 2768d409749..92b70ba1b30 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -222,7 +222,7 @@ static int vf_usb_ofdata_to_platdata(struct udevice *dev)
 	int node = dev_of_offset(dev);
 	const char *mode;
 
-	priv->portnr = dev->seq;
+	priv->portnr = dev_seq(dev);
 
 	priv->ehci = dev_read_addr_ptr(dev);
 	mode = fdt_getprop(dt_blob, node, "dr_mode", NULL);
diff --git a/drivers/usb/host/usb-sandbox.c b/drivers/usb/host/usb-sandbox.c
index beb62ebc0c2..cc357d9ef40 100644
--- a/drivers/usb/host/usb-sandbox.c
+++ b/drivers/usb/host/usb-sandbox.c
@@ -23,7 +23,7 @@ static void usbmon_trace(struct udevice *bus, ulong pipe,
 	type = (pipe & USB_PIPE_TYPE_MASK) >> USB_PIPE_TYPE_SHIFT;
 	debug("0 0 S %c%c:%d:%03ld:%ld", types[type],
 	      pipe & USB_DIR_IN ? 'i' : 'o',
-	      bus->seq,
+	      dev_seq(bus),
 	      (pipe & USB_PIPE_DEV_MASK) >> USB_PIPE_DEV_SHIFT,
 	      (pipe & USB_PIPE_EP_MASK) >> USB_PIPE_EP_SHIFT);
 	if (setup) {
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 2f8c9037c12..453c2bbb0b6 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -701,7 +701,7 @@ int usb_scan_device(struct udevice *parent, int port,
 			return ret;
 		ret = usb_find_and_bind_driver(parent, &udev->descriptor,
 					       iface,
-					       udev->controller_dev->seq,
+					       dev_seq(udev->controller_dev),
 					       udev->devnum, port, &dev);
 		if (ret)
 			return ret;
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index 3a07f36ce27..9fa124b3c03 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -606,9 +606,9 @@ static int vidconsole_post_probe(struct udevice *dev)
 	if (!priv->tab_width_frac)
 		priv->tab_width_frac = VID_TO_POS(priv->x_charsize) * 8;
 
-	if (dev->seq) {
+	if (dev_seq(dev)) {
 		snprintf(sdev->name, sizeof(sdev->name), "vidconsole%d",
-			 dev->seq);
+			 dev_seq(dev));
 	} else {
 		strcpy(sdev->name, "vidconsole");
 	}
diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c
index 2636cbedfe2..53c17429725 100644
--- a/drivers/virtio/virtio-uclass.c
+++ b/drivers/virtio/virtio-uclass.c
@@ -240,7 +240,7 @@ static int virtio_uclass_post_probe(struct udevice *udev)
 	}
 
 	snprintf(dev_name, sizeof(dev_name), "%s#%d",
-		 virtio_drv_name[uc_priv->device], udev->seq);
+		 virtio_drv_name[uc_priv->device], dev_seq(udev));
 	str = strdup(dev_name);
 	if (!str)
 		return -ENOMEM;
diff --git a/drivers/watchdog/ast_wdt.c b/drivers/watchdog/ast_wdt.c
index 9b83d2ad442..c9c4a1fdc5f 100644
--- a/drivers/watchdog/ast_wdt.c
+++ b/drivers/watchdog/ast_wdt.c
@@ -113,7 +113,7 @@ static const struct udevice_id ast_wdt_ids[] = {
 
 static int ast_wdt_probe(struct udevice *dev)
 {
-	debug("%s() wdt%u\n", __func__, dev->seq);
+	debug("%s() wdt%u\n", __func__, dev_seq(dev));
 	ast_wdt_stop(dev);
 
 	return 0;
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index 33f5c351d5b..3455a80228d 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -108,7 +108,7 @@ static int at91_wdt_probe(struct udevice *dev)
 	if (!priv->regs)
 		return -EINVAL;
 
-	debug("%s: Probing wdt%u\n", __func__, dev->seq);
+	debug("%s: Probing wdt%u\n", __func__, dev_seq(dev));
 
 	return 0;
 }
diff --git a/drivers/watchdog/cdns_wdt.c b/drivers/watchdog/cdns_wdt.c
index 2abd5524f61..1e703f07f70 100644
--- a/drivers/watchdog/cdns_wdt.c
+++ b/drivers/watchdog/cdns_wdt.c
@@ -223,7 +223,7 @@ static int cdns_wdt_stop(struct udevice *dev)
  */
 static int cdns_wdt_probe(struct udevice *dev)
 {
-	debug("%s: Probing wdt%u\n", __func__, dev->seq);
+	debug("%s: Probing wdt%u\n", __func__, dev_seq(dev));
 
 	return 0;
 }
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 9059a4c6105..8c87b50c5d2 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -242,7 +242,7 @@ static int omap3_wdt_probe(struct udevice *dev)
 		return -EINVAL;
 
 	priv->wdt_trgr_pattern = 0x1234;
-	debug("%s: Probing wdt%u\n", __func__, dev->seq);
+	debug("%s: Probing wdt%u\n", __func__, dev_seq(dev));
 	return 0;
 }
 
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index d33e2ac3dc1..c3576916d32 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -158,7 +158,7 @@ static int orion_wdt_probe(struct udevice *dev)
 	struct orion_wdt_priv *priv = dev_get_priv(dev);
 	int ret;
 
-	debug("%s: Probing wdt%u\n", __func__, dev->seq);
+	debug("%s: Probing wdt%u\n", __func__, dev_seq(dev));
 	orion_wdt_stop(dev);
 
 	ret = clk_get_by_name(dev, "fixed", &priv->clk);
diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
index 2eae431ba6c..e93e0ee3d54 100644
--- a/drivers/watchdog/sbsa_gwdt.c
+++ b/drivers/watchdog/sbsa_gwdt.c
@@ -88,7 +88,7 @@ static int sbsa_gwdt_expire_now(struct udevice *dev, ulong flags)
 
 static int sbsa_gwdt_probe(struct udevice *dev)
 {
-	debug("%s: Probing wdt%u (sbsa-gwdt)\n", __func__, dev->seq);
+	debug("%s: Probing wdt%u (sbsa-gwdt)\n", __func__, dev_seq(dev));
 
 	return 0;
 }
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 23fef2147f8..aaf93d545e4 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -105,7 +105,7 @@ static int sp805_wdt_expire_now(struct udevice *dev, ulong flags)
 
 static int sp805_wdt_probe(struct udevice *dev)
 {
-	debug("%s: Probing wdt%u (sp805-wdt)\n", __func__, dev->seq);
+	debug("%s: Probing wdt%u (sp805-wdt)\n", __func__, dev_seq(dev));
 
 	return 0;
 }
diff --git a/drivers/watchdog/tangier_wdt.c b/drivers/watchdog/tangier_wdt.c
index 358a9b90fdd..bdc65597dcf 100644
--- a/drivers/watchdog/tangier_wdt.c
+++ b/drivers/watchdog/tangier_wdt.c
@@ -80,7 +80,7 @@ static const struct udevice_id tangier_wdt_ids[] = {
 
 static int tangier_wdt_probe(struct udevice *dev)
 {
-	debug("%s: Probing wdt%u\n", __func__, dev->seq);
+	debug("%s: Probing wdt%u\n", __func__, dev_seq(dev));
 	return 0;
 }
 
diff --git a/drivers/watchdog/xilinx_tb_wdt.c b/drivers/watchdog/xilinx_tb_wdt.c
index ea4311c8ce1..721ccdb0f6d 100644
--- a/drivers/watchdog/xilinx_tb_wdt.c
+++ b/drivers/watchdog/xilinx_tb_wdt.c
@@ -85,7 +85,7 @@ static int xlnx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
 
 static int xlnx_wdt_probe(struct udevice *dev)
 {
-	debug("%s: Probing wdt%u\n", __func__, dev->seq);
+	debug("%s: Probing wdt%u\n", __func__, dev_seq(dev));
 
 	return 0;
 }
diff --git a/drivers/watchdog/xilinx_wwdt.c b/drivers/watchdog/xilinx_wwdt.c
index d8a585a4830..df55e088bbf 100644
--- a/drivers/watchdog/xilinx_wwdt.c
+++ b/drivers/watchdog/xilinx_wwdt.c
@@ -128,7 +128,7 @@ static int xlnx_wwdt_probe(struct udevice *dev)
 	struct xlnx_wwdt_platdata *platdata = dev_get_platdata(dev);
 	struct xlnx_wwdt_priv *wdt = dev_get_priv(dev);
 
-	dev_dbg(dev, "%s: Probing wdt%u\n", __func__, dev->seq);
+	dev_dbg(dev, "%s: Probing wdt%u\n", __func__, dev_seq(dev));
 
 	ret = regmap_init_mem(dev_ofnode(dev), &wdt->regs);
 	if (ret) {
diff --git a/include/dm/device.h b/include/dm/device.h
index 25a77d08b9d..9a171e523f3 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -182,6 +182,11 @@ static inline bool dev_has_of_node(struct udevice *dev)
 	return ofnode_valid(dev->node);
 }
 
+static inline int dev_seq(const struct udevice *dev)
+{
+	return dev->seq;
+}
+
 /**
  * struct udevice_id - Lists the compatible strings supported by a driver
  * @compatible: Compatible string
diff --git a/include/pci.h b/include/pci.h
index d1ccf6c9636..f8dadf9d5ad 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -934,7 +934,7 @@ struct dm_pci_ops {
 	 * PCI buses must support reading and writing configuration values
 	 * so that the bus can be scanned and its devices configured.
 	 *
-	 * Normally PCI_BUS(@bdf) is the same as @bus->seq, but not always.
+	 * Normally PCI_BUS(@bdf) is the same as @dev_seq(bus), but not always.
 	 * If bridges exist it is possible to use the top-level bus to
 	 * access a sub-bus. In that case @bus will be the top-level bus
 	 * and PCI_BUS(bdf) will be a different (higher) value
diff --git a/include/spi.h b/include/spi.h
index ef8c1f6692e..e90110dd13c 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -116,7 +116,7 @@ enum spi_polarity {
  *			claimed.
  * @bus:		ID of the bus that the slave is attached to. For
  *			driver model this is the sequence number of the SPI
- *			bus (bus->seq) so does not need to be stored
+ *			bus (dev_seq(bus)) so does not need to be stored
  * @cs:			ID of the chip select connected to the slave.
  * @mode:		SPI mode to use for this slave (see SPI mode flags)
  * @wordlen:		Size of SPI word in number of bits
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 8a5c13c4241..2726c5e42fd 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -624,7 +624,7 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
 				DEVICE_PATH_SUB_TYPE_MSG_SD :
 				DEVICE_PATH_SUB_TYPE_MSG_MMC;
 			sddp->dp.length   = sizeof(*sddp);
-			sddp->slot_number = dev->seq;
+			sddp->slot_number = dev_seq(dev);
 			return &sddp[1];
 			}
 #endif
@@ -677,7 +677,7 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
 			DEVICE_PATH_SUB_TYPE_MSG_SD :
 			DEVICE_PATH_SUB_TYPE_MSG_MMC;
 		sddp->dp.length   = sizeof(*sddp);
-		sddp->slot_number = dev->seq;
+		sddp->slot_number = dev_seq(dev);
 
 		return &sddp[1];
 	}
diff --git a/net/eth-uclass.c b/net/eth-uclass.c
index e14695c0f16..e6a3cd1ee6a 100644
--- a/net/eth-uclass.c
+++ b/net/eth-uclass.c
@@ -137,7 +137,7 @@ struct udevice *eth_get_dev_by_name(const char *devname)
 			continue;
 		/* Check for the name or the sequence number to match */
 		if (strcmp(it->name, devname) == 0 ||
-		    (endp > startp && it->seq == seq))
+		    (endp > startp && dev_seq(it) == seq))
 			return it;
 	}
 
@@ -189,7 +189,7 @@ void eth_halt_state_only(void)
 int eth_get_dev_index(void)
 {
 	if (eth_get_dev())
-		return eth_get_dev()->seq;
+		return dev_seq(eth_get_dev());
 	return -1;
 }
 
@@ -202,7 +202,7 @@ static int eth_write_hwaddr(struct udevice *dev)
 		return -EINVAL;
 
 	/* seq is valid since the device is active */
-	if (eth_get_ops(dev)->write_hwaddr && !eth_mac_skip(dev->seq)) {
+	if (eth_get_ops(dev)->write_hwaddr && !eth_mac_skip(dev_seq(dev))) {
 		pdata = dev->platdata;
 		if (!is_valid_ethaddr(pdata->enetaddr)) {
 			printf("\nError: %s address %pM illegal value\n",
@@ -434,11 +434,11 @@ int eth_initialize(void)
 
 		bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
 		do {
-			if (dev->seq != -1) {
+			if (dev_seq(dev) != -1) {
 				if (num_devices)
 					printf(", ");
 
-				printf("eth%d: %s", dev->seq, dev->name);
+				printf("eth%d: %s", dev_seq(dev), dev->name);
 
 				if (ethprime && dev == prime_dev)
 					printf(" [PRIME]");
@@ -446,7 +446,7 @@ int eth_initialize(void)
 
 			eth_write_hwaddr(dev);
 
-			if (dev->seq != -1)
+			if (dev_seq(dev) != -1)
 				num_devices++;
 			uclass_next_device_check(&dev);
 		} while (dev);
@@ -547,7 +547,7 @@ static int eth_post_probe(struct udevice *dev)
 			eth_get_ops(dev)->read_rom_hwaddr(dev);
 	}
 
-	eth_env_get_enetaddr_by_index("eth", dev->seq, env_enetaddr);
+	eth_env_get_enetaddr_by_index("eth", dev_seq(dev), env_enetaddr);
 	if (!is_zero_ethaddr(env_enetaddr)) {
 		if (!is_zero_ethaddr(pdata->enetaddr) &&
 		    memcmp(pdata->enetaddr, env_enetaddr, ARP_HLEN)) {
@@ -562,13 +562,14 @@ static int eth_post_probe(struct udevice *dev)
 		/* Override the ROM MAC address */
 		memcpy(pdata->enetaddr, env_enetaddr, ARP_HLEN);
 	} else if (is_valid_ethaddr(pdata->enetaddr)) {
-		eth_env_set_enetaddr_by_index("eth", dev->seq, pdata->enetaddr);
+		eth_env_set_enetaddr_by_index("eth", dev_seq(dev),
+					      pdata->enetaddr);
 	} else if (is_zero_ethaddr(pdata->enetaddr) ||
 		   !is_valid_ethaddr(pdata->enetaddr)) {
 #ifdef CONFIG_NET_RANDOM_ETHADDR
 		net_random_ethaddr(pdata->enetaddr);
 		printf("\nWarning: %s (eth%d) using random MAC address - %pM\n",
-		       dev->name, dev->seq, pdata->enetaddr);
+		       dev->name, dev_seq(dev), pdata->enetaddr);
 #else
 		printf("\nError: %s address not set.\n",
 		       dev->name);
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 04/27] dm: core: Update uclass_find_next_free_req_seq() args
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (2 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 03/27] dm: Avoid accessing seq directly Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 05/27] dm: core: Add a new sequence number for devices Simon Glass
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

At present this is passed a uclass ID and it has to do a lookup. The
callers all have the uclass pointer, except for the I2C uclass where the
code will soon be deleted.

Update the argument to a uclass * instead of an ID since it is more
efficient.

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

 drivers/core/device.c            | 4 ++--
 drivers/core/uclass.c            | 8 +-------
 drivers/i2c/designware_i2c_pci.c | 8 +++++++-
 include/dm/uclass-internal.h     | 4 ++--
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 5660310c754..5febdb67503 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -89,10 +89,10 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
 #if CONFIG_IS_ENABLED(OF_PRIOR_STAGE)
 			if (dev->req_seq == -1)
 				dev->req_seq =
-					uclass_find_next_free_req_seq(drv->id);
+					uclass_find_next_free_req_seq(uc);
 #endif
 		} else {
-			dev->req_seq = uclass_find_next_free_req_seq(drv->id);
+			dev->req_seq = uclass_find_next_free_req_seq(uc);
 		}
 	}
 
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 699f24843cf..cdf0674cd82 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -272,17 +272,11 @@ int uclass_find_device_by_name(enum uclass_id id, const char *name,
 	return -ENODEV;
 }
 
-int uclass_find_next_free_req_seq(enum uclass_id id)
+int uclass_find_next_free_req_seq(struct uclass *uc)
 {
-	struct uclass *uc;
 	struct udevice *dev;
-	int ret;
 	int max = -1;
 
-	ret = uclass_get(id, &uc);
-	if (ret)
-		return ret;
-
 	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
 		if ((dev->req_seq != -1) && (dev->req_seq > max))
 			max = dev->req_seq;
diff --git a/drivers/i2c/designware_i2c_pci.c b/drivers/i2c/designware_i2c_pci.c
index d0d869c81a1..04921a304ac 100644
--- a/drivers/i2c/designware_i2c_pci.c
+++ b/drivers/i2c/designware_i2c_pci.c
@@ -90,7 +90,9 @@ static int designware_i2c_pci_probe(struct udevice *dev)
 
 static int designware_i2c_pci_bind(struct udevice *dev)
 {
+	struct uclass *uc;
 	char name[20];
+	int ret;
 
 	if (dev_of_valid(dev))
 		return 0;
@@ -108,7 +110,11 @@ static int designware_i2c_pci_bind(struct udevice *dev)
 	 * be possible. We cannot use static data in drivers since they may be
 	 * used in SPL or before relocation.
 	 */
-	dev->req_seq = uclass_find_next_free_req_seq(UCLASS_I2C);
+	ret = uclass_get(UCLASS_I2C, &uc);
+	if (ret)
+		return ret;
+
+	dev->req_seq = uclass_find_next_free_req_seq(uc);
 	sprintf(name, "i2c_designware#%u", dev->req_seq);
 	device_set_name(dev, name);
 
diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h
index 6e3f15c2b08..2c21871e0fd 100644
--- a/include/dm/uclass-internal.h
+++ b/include/dm/uclass-internal.h
@@ -19,10 +19,10 @@
  * maximum req_seq of the uclass + 1.
  * This allows assiging req_seq number in the binding order.
  *
- * @id:		Id number of the uclass
+ * @uc:		uclass to check
  * @return	The next free req_seq number
  */
-int uclass_find_next_free_req_seq(enum uclass_id id);
+int uclass_find_next_free_req_seq(struct uclass *uc);
 
 /**
  * uclass_get_device_tail() - handle the end of a get_device call
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 05/27] dm: core: Add a new sequence number for devices
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (3 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 04/27] dm: core: Update uclass_find_next_free_req_seq() args Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 06/27] dm: test: Add support for new sequence numbers Simon Glass
                   ` (23 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

At present each device has two sequence numbers, with 'req_seq' being
set up at bind time and 'seq' at probe time. The idea is that devices
can 'request' a sequence number and then the conflicts are resolved when
the device is probed.

This makes things complicated in a few cases, since we don't really know
what the sequence number will end up being. We want to honour the
bind-time requests if at all possible, but in fact the only source of
these at present is the devicetree aliases. Since we have the devicetree
available at bind time, we may as well just use it, in the hope that the
required processing will turn out to be useful later (i.e. the device
actually gets used).

Add a new 'sqq' member, the bind-time sequence number. It operates in
parallel to the old values for now. All devices get a valid sqq value,
i.e. it is never -1.

Drop an #ifdef while we are here.

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

 drivers/core/device.c             | 22 ++++++++++++-----
 drivers/core/root.c               | 21 +++++++++++++---
 drivers/core/uclass.c             | 40 +++++++++++++++++++++++++++++++
 include/asm-generic/global_data.h |  2 ++
 include/dm/device.h               |  8 +++++++
 include/dm/uclass.h               |  8 +++++++
 6 files changed, 92 insertions(+), 9 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 5febdb67503..2f449b3e8fa 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -41,6 +41,7 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
 	struct udevice *dev;
 	struct uclass *uc;
 	int size, ret = 0;
+	bool auto_seq = false;
 
 	if (devp)
 		*devp = NULL;
@@ -73,6 +74,7 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
 
 	dev->seq = -1;
 	dev->req_seq = -1;
+	dev->sqq = -1;
 	if (CONFIG_IS_ENABLED(DM_SEQ_ALIAS) &&
 	    (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS)) {
 		/*
@@ -84,16 +86,24 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
 		 */
 		if (CONFIG_IS_ENABLED(OF_CONTROL) &&
 		    !CONFIG_IS_ENABLED(OF_PLATDATA)) {
-			if (uc->uc_drv->name && ofnode_valid(node))
+			if (uc->uc_drv->name && ofnode_valid(node)) {
+				dev_read_alias_seq(dev, &dev->sqq);
 				dev_read_alias_seq(dev, &dev->req_seq);
-#if CONFIG_IS_ENABLED(OF_PRIOR_STAGE)
-			if (dev->req_seq == -1)
-				dev->req_seq =
-					uclass_find_next_free_req_seq(uc);
-#endif
+			}
+			if (CONFIG_IS_ENABLED(OF_PRIOR_STAGE)) {
+				if (dev->req_seq == -1) {
+					auto_seq = true;
+					dev->req_seq =
+						uclass_find_next_free_req_seq(
+							uc);
+				}
+			}
 		} else {
+			auto_seq = true;
 			dev->req_seq = uclass_find_next_free_req_seq(uc);
 		}
+		if (auto_seq && !(gd->flags & GD_FLG_DM_NO_SEQ))
+			dev->sqq = uclass_find_next_free_req_seq(uc);
 	}
 
 	if (drv->platdata_auto_alloc_size) {
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 6f8168bb92d..66aabc4b19b 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -308,25 +308,40 @@ int dm_init_and_scan(bool pre_reloc_only)
 		debug("dm_init() failed: %d\n", ret);
 		return ret;
 	}
+	gd->flags |= GD_FLG_DM_NO_SEQ;
 	ret = dm_scan_platdata(pre_reloc_only);
 	if (ret) {
 		debug("dm_scan_platdata() failed: %d\n", ret);
-		return ret;
+		goto fail;
 	}
 
 	if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
 		ret = dm_extended_scan(pre_reloc_only);
 		if (ret) {
 			debug("dm_extended_scan() failed: %d\n", ret);
-			return ret;
+			goto fail;
 		}
 	}
 
 	ret = dm_scan_other(pre_reloc_only);
 	if (ret)
-		return ret;
+		goto fail;
+
+	/*
+	 * Now that all the alisas have been used to claim sequence numbers, we
+	 * can allocate every non-aliased device a sequence number
+	 */
+	uclass_alloc_all_seqs();
+
+	/*
+	 * From now on, assign sequence numbers when binding, to ensure that
+	 * every new device has a sequence number too
+	 */
+	gd->flags &= ~GD_FLG_DM_NO_SEQ;
 
 	return 0;
+fail:
+	return ret;
 }
 
 #ifdef CONFIG_ACPIGEN
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index cdf0674cd82..d4de88bfb57 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -288,6 +288,46 @@ int uclass_find_next_free_req_seq(struct uclass *uc)
 	return max + 1;
 }
 
+static int uclass_find_first_free_seq(struct uclass *uc)
+{
+	struct udevice *dev;
+	bool in_use = true;
+	int cur;
+
+	/* Increment cur until we get to a value not used in the devices */
+	for (cur = 0; in_use;) {
+		in_use = false;
+		list_for_each_entry(dev, &uc->dev_head, uclass_node) {
+			if (dev->sqq == cur) {
+				in_use = true;
+				cur++;
+				break;
+			}
+		}
+	}
+
+	return cur;
+}
+
+static void uclass_alloc_seqs(struct uclass *uc)
+{
+	struct udevice *dev;
+
+	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
+		if (dev->sqq == -1)
+			dev->sqq = uclass_find_first_free_seq(uc);
+	}
+}
+
+void uclass_alloc_all_seqs(void)
+{
+	struct uclass *uc;
+
+	list_for_each_entry(uc, &gd->uclass_root, sibling_node) {
+		uclass_alloc_seqs(uc);
+	}
+}
+
 int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
 			      bool find_req_seq, struct udevice **devp)
 {
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 87d827d0f43..0179567a2bb 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -547,6 +547,8 @@ enum gd_flags {
 	 * @GD_FLG_SMP_READY: SMP initialization is complete
 	 */
 	GD_FLG_SMP_READY = 0x40000,
+	/** @GD_FLG_DM_NO_SEQ: Don't assign devices a sequence number on bind */
+	GD_FLG_DM_NO_SEQ = 0x80000,
 };
 
 #endif /* __ASSEMBLY__ */
diff --git a/include/dm/device.h b/include/dm/device.h
index 9a171e523f3..80cd0955362 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -131,6 +131,13 @@ enum {
  * @child_head: List of children of this device
  * @sibling_node: Next device in list of all devices
  * @flags: Flags for this device DM_FLAG_...
+ * @sqq: Allocated sequence number for this device (-1 = none). This is set up
+ * when the device is bound and is unique within the device's uclass. If the
+ * device has an alias in the devicetree then that is used to set the sequence
+ * number. Otherwise, the next available number is used. Sequence numbers are
+ * used by certain commands that need device to be numbered (e.g. 'mmc dev')
+ *
+ * The following two fields are deprecated:
  * @req_seq: Requested sequence number for this device (-1 = any)
  * @seq: Allocated sequence number for this device (-1 = none). This is set up
  * when the device is probed and will be unique within the device's uclass.
@@ -156,6 +163,7 @@ struct udevice {
 	struct list_head child_head;
 	struct list_head sibling_node;
 	uint32_t flags;
+	int sqq;
 	int req_seq;
 	int seq;
 #ifdef CONFIG_DEVRES
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index 71883043046..d1906236976 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -380,6 +380,14 @@ int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data,
  */
 int uclass_resolve_seq(struct udevice *dev);
 
+/**
+ * uclass_alloc_all_seqs() - Make sure that all devices have sequence numbers
+ *
+ * This updates any sequence numbers that are unallocated (set to -1) to the
+ * next available number in the uclass, above all existing numbers
+ */
+void uclass_alloc_all_seqs(void);
+
 /**
  * uclass_id_foreach_dev() - Helper function to iteration through devices
  *
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 06/27] dm: test: Add support for new sequence numbers
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (4 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 05/27] dm: core: Add a new sequence number for devices Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 07/27] dm: core: Switch binding to use " Simon Glass
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

Tests need to rebuild the driver model data structures to avoid being
affected by the operation of an earlier test. Do the same for the new
bind-time sequence numbers.

Also add a test that the new sequence numbers work as expected. Every
device should get one.

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

 test/dm/core.c      | 19 +++++++++++++++++++
 test/dm/test-main.c |  6 ++++++
 2 files changed, 25 insertions(+)

diff --git a/test/dm/core.c b/test/dm/core.c
index 71ebb36d88b..0514813b817 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -1066,3 +1066,22 @@ static int dm_test_inactive_child(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_inactive_child, UT_TESTF_SCAN_PDATA);
+
+/* Make sure all bound devices have a sequence number */
+static int dm_test_all_have_seq(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	struct uclass *uc;
+
+	list_for_each_entry(uc, &gd->uclass_root, sibling_node) {
+		list_for_each_entry(dev, &uc->dev_head, uclass_node) {
+			if (dev->sqq == -1)
+				printf("Device '%s' has no seq (%d)\n",
+				       dev->name, dev->sqq);
+			ut_assert(dev->sqq != -1);
+		}
+	}
+
+	return 0;
+}
+DM_TEST(dm_test_all_have_seq, UT_TESTF_SCAN_PDATA);
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index 4814e186cb7..4ff7a01d5aa 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -88,6 +88,7 @@ static int dm_do_test(struct unit_test_state *uts, struct unit_test *test,
 	ut_assertok(dm_test_init(uts, of_live));
 
 	uts->start = mallinfo();
+	gd->flags |= GD_FLG_DM_NO_SEQ;
 	if (test->flags & UT_TESTF_SCAN_PDATA)
 		ut_assertok(dm_scan_platdata(false));
 	if (test->flags & UT_TESTF_PROBE_TEST)
@@ -95,6 +96,8 @@ static int dm_do_test(struct unit_test_state *uts, struct unit_test *test,
 	if (!CONFIG_IS_ENABLED(OF_PLATDATA) &&
 	    (test->flags & UT_TESTF_SCAN_FDT))
 		ut_assertok(dm_extended_scan(false));
+	uclass_alloc_all_seqs();
+	gd->flags &= ~GD_FLG_DM_NO_SEQ;
 
 	/*
 	 * Silence the console and rely on console recording to get
@@ -208,12 +211,15 @@ int dm_test_main(const char *test_name)
 		printf("Failures: %d\n", uts->fail_count);
 
 	/* Put everything back to normal so that sandbox works as expected */
+	gd->flags |= GD_FLG_DM_NO_SEQ;
 	gd_set_of_root(uts->of_root);
 	gd->dm_root = NULL;
 	ut_assertok(dm_init(CONFIG_IS_ENABLED(OF_LIVE)));
 	dm_scan_platdata(false);
 	if (!CONFIG_IS_ENABLED(OF_PLATDATA))
 		dm_scan_fdt(false);
+	uclass_alloc_all_seqs();
+	gd->flags &= ~GD_FLG_DM_NO_SEQ;
 
 	return uts->fail_count ? CMD_RET_FAILURE : 0;
 }
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 07/27] dm: core: Switch binding to use new sequence numbers
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (5 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 06/27] dm: test: Add support for new sequence numbers Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 08/27] dm: Fix return value in dev_read_alias_seq() Simon Glass
                   ` (21 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

Update the core logic to use the new approach. For now the old code is
left as is. Update one test so it still passes.

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

 drivers/core/device.c | 5 +----
 test/dm/bus.c         | 3 ++-
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 2f449b3e8fa..bd58a9e946d 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -667,12 +667,9 @@ int device_find_child_by_seq(const struct udevice *parent, int seq_or_req_seq,
 	struct udevice *dev;
 
 	*devp = NULL;
-	if (seq_or_req_seq == -1)
-		return -ENODEV;
 
 	list_for_each_entry(dev, &parent->child_head, sibling_node) {
-		if ((find_req_seq ? dev->req_seq : dev_seq(dev)) ==
-				seq_or_req_seq) {
+		if (dev->sqq == seq_or_req_seq) {
 			*devp = dev;
 			return 0;
 		}
diff --git a/test/dm/bus.c b/test/dm/bus.c
index 27b72666457..e1fa67d91e1 100644
--- a/test/dm/bus.c
+++ b/test/dm/bus.c
@@ -160,9 +160,10 @@ static int dm_test_bus_children_funcs(struct unit_test_state *uts)
 	ut_asserteq(-ENODEV, device_find_child_by_seq(bus, -1, true, &dev));
 	ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
 	ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
-	ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 0, false, &dev));
+	ut_asserteq(0, device_find_child_by_seq(bus, 0, false, &dev));
 	ut_assertok(device_get_child_by_seq(bus, 0, &dev));
 	ut_assert(dev->flags & DM_FLAG_ACTIVATED);
+	ut_asserteq(0, device_find_child_by_seq(bus, 0, false, &dev));
 
 	/* There is no device with sequence number 2 */
 	ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, false, &dev));
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 08/27] dm: Fix return value in dev_read_alias_seq()
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (6 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 07/27] dm: core: Switch binding to use " Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 09/27] dm: test: Drop assumptions of no sequence numbers Simon Glass
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

This should return 0 on success but currently does not. Fix it.

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

 drivers/core/read.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/core/read.c b/drivers/core/read.c
index 076125824ca..fc74d64814f 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -281,8 +281,10 @@ int dev_read_alias_seq(const struct udevice *dev, int *devnump)
 
 	if (ofnode_is_np(node)) {
 		ret = of_alias_get_id(ofnode_to_np(node), uc_name);
-		if (ret >= 0)
+		if (ret >= 0) {
 			*devnump = ret;
+			ret = 0;
+		}
 	} else {
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 		ret = fdtdec_get_alias_seq(gd->fdt_blob, uc_name,
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 09/27] dm: test: Drop assumptions of no sequence numbers
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (7 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 08/27] dm: Fix return value in dev_read_alias_seq() Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 10/27] octeon: Don't attempt to set the sequence number Simon Glass
                   ` (19 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

Drop code in a few tests which assumes that sequence numbers are only
valid when a device is probed.

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

 test/dm/blk.c | 3 ---
 test/dm/i2c.c | 3 ---
 test/dm/spi.c | 3 ---
 3 files changed, 9 deletions(-)

diff --git a/test/dm/blk.c b/test/dm/blk.c
index f34c13f7511..ea5e0955d98 100644
--- a/test/dm/blk.c
+++ b/test/dm/blk.c
@@ -19,9 +19,6 @@ static int dm_test_blk_base(struct unit_test_state *uts)
 {
 	struct udevice *blk1, *blk3, *dev;
 
-	/* Make sure there are no block devices */
-	ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_BLK, 0, &dev));
-
 	/* Create two, one the parent of the other */
 	ut_assertok(blk_create_device(gd->dm_root, "sandbox_host_blk", "test",
 				      IF_TYPE_HOST, 1, 512, 2, &blk1));
diff --git a/test/dm/i2c.c b/test/dm/i2c.c
index 681ce45107c..d74f5f9fbc7 100644
--- a/test/dm/i2c.c
+++ b/test/dm/i2c.c
@@ -28,9 +28,6 @@ static int dm_test_i2c_find(struct unit_test_state *uts)
 	struct udevice *bus, *dev;
 	const int no_chip = 0x10;
 
-	ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_I2C, busnum,
-						       false, &bus));
-
 	/*
 	 * The post_bind() method will bind devices to chip selects. Check
 	 * this then remove the emulation and the slave device.
diff --git a/test/dm/spi.c b/test/dm/spi.c
index fb180aed1f0..b767cf9c4a0 100644
--- a/test/dm/spi.c
+++ b/test/dm/spi.c
@@ -26,9 +26,6 @@ static int dm_test_spi_find(struct unit_test_state *uts)
 	struct spi_cs_info info;
 	ofnode node;
 
-	ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_SPI, busnum,
-						       false, &bus));
-
 	/*
 	 * The post_bind() method will bind devices to chip selects. Check
 	 * this then remove the emulation and the slave device.
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 10/27] octeon: Don't attempt to set the sequence number
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (8 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 09/27] dm: test: Drop assumptions of no sequence numbers Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 11/27] i2c: Update for new sequence numbers Simon Glass
                   ` (18 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

Several Octeon drivers operate by setting the sequence number of their
device. This should not be needed with the new sequence number setup. Also
it is not permitted. Drop it.

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

 drivers/i2c/octeon_i2c.c     | 1 -
 drivers/mmc/octeontx_hsmmc.c | 2 --
 drivers/net/octeontx/smi.c   | 1 -
 3 files changed, 4 deletions(-)

diff --git a/drivers/i2c/octeon_i2c.c b/drivers/i2c/octeon_i2c.c
index 38839e45758..85ad357eca9 100644
--- a/drivers/i2c/octeon_i2c.c
+++ b/drivers/i2c/octeon_i2c.c
@@ -791,7 +791,6 @@ static int octeon_i2c_probe(struct udevice *dev)
 		pci_dev_t bdf = dm_pci_get_bdf(dev);
 
 		debug("TWSI PCI device: %x\n", bdf);
-		dev->req_seq = PCI_FUNC(bdf);
 
 		twsi->base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
 					    PCI_REGION_MEM);
diff --git a/drivers/mmc/octeontx_hsmmc.c b/drivers/mmc/octeontx_hsmmc.c
index 38ca3736841..a91aaf31461 100644
--- a/drivers/mmc/octeontx_hsmmc.c
+++ b/drivers/mmc/octeontx_hsmmc.c
@@ -3731,7 +3731,6 @@ U_BOOT_DRIVER(octeontx_hsmmc_slot) = {
  */
 static int octeontx_mmc_host_probe(struct udevice *dev)
 {
-	pci_dev_t bdf = dm_pci_get_bdf(dev);
 	struct octeontx_mmc_host *host = dev_get_priv(dev);
 	union mio_emm_int emm_int;
 	u8 rev;
@@ -3757,7 +3756,6 @@ static int octeontx_mmc_host_probe(struct udevice *dev)
 		return -1;
 	}
 	host->node = dev->node;
-	dev->req_seq = PCI_FUNC(bdf);
 	host->last_slotid = -1;
 	if (otx_is_platform(PLATFORM_ASIM))
 		host->is_asim = true;
diff --git a/drivers/net/octeontx/smi.c b/drivers/net/octeontx/smi.c
index d4baddb7ef5..d1582b968bf 100644
--- a/drivers/net/octeontx/smi.c
+++ b/drivers/net/octeontx/smi.c
@@ -319,7 +319,6 @@ int octeontx_smi_probe(struct udevice *dev)
 	pci_dev_t bdf = dm_pci_get_bdf(dev);
 
 	debug("SMI PCI device: %x\n", bdf);
-	dev->req_seq = PCI_FUNC(bdf);
 	if (!dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM)) {
 		printf("Failed to map PCI region for bdf %x\n", bdf);
 		return -1;
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 11/27] i2c: Update for new sequence numbers
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (9 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 10/27] octeon: Don't attempt to set the sequence number Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 12/27] net: Update to use " Simon Glass
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

Use the new sequence number in all cases. Drop the logic to check for a
valid number in designware_i2c, since it will always be valid.

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

 drivers/i2c/designware_i2c_pci.c   | 22 +---------------------
 drivers/i2c/i2c-uclass.c           |  8 +-------
 drivers/i2c/i2c-versatile.c        |  5 -----
 drivers/i2c/intel_i2c.c            | 12 +-----------
 drivers/i2c/muxes/i2c-mux-uclass.c |  4 ++--
 drivers/i2c/mvtwsi.c               |  4 ++--
 6 files changed, 7 insertions(+), 48 deletions(-)

diff --git a/drivers/i2c/designware_i2c_pci.c b/drivers/i2c/designware_i2c_pci.c
index 04921a304ac..9237726b475 100644
--- a/drivers/i2c/designware_i2c_pci.c
+++ b/drivers/i2c/designware_i2c_pci.c
@@ -90,32 +90,12 @@ static int designware_i2c_pci_probe(struct udevice *dev)
 
 static int designware_i2c_pci_bind(struct udevice *dev)
 {
-	struct uclass *uc;
 	char name[20];
-	int ret;
 
 	if (dev_of_valid(dev))
 		return 0;
 
-	/*
-	 * Create a unique device name for PCI type devices
-	 * ToDo:
-	 * Setting req_seq in the driver is probably not recommended.
-	 * But without a DT alias the number is not configured. And
-	 * using this driver is impossible for PCIe I2C devices.
-	 * This can be removed, once a better (correct) way for this
-	 * is found and implemented.
-	 *
-	 * TODO(sjg at chromium.org): Perhaps if uclasses had platdata this would
-	 * be possible. We cannot use static data in drivers since they may be
-	 * used in SPL or before relocation.
-	 */
-	ret = uclass_get(UCLASS_I2C, &uc);
-	if (ret)
-		return ret;
-
-	dev->req_seq = uclass_find_next_free_req_seq(uc);
-	sprintf(name, "i2c_designware#%u", dev->req_seq);
+	sprintf(name, "i2c_designware#%u", dev_seq(dev));
 	device_set_name(dev, name);
 
 	return 0;
diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index 5c4626b0442..2625bd72dc8 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -700,13 +700,7 @@ static int i2c_post_bind(struct udevice *dev)
 	if (!priv)
 		return -ENOMEM;
 
-	debug("%s: %s, req_seq=%d\n", __func__, dev->name, dev->req_seq);
-
-	/* if there is no alias ID, use the first free */
-	if (dev->req_seq == -1)
-		dev->req_seq = ++priv->max_id;
-
-	debug("%s: %s, new req_seq=%d\n", __func__, dev->name, dev->req_seq);
+	debug("%s: %s, seq=%d\n", __func__, dev->name, dev_seq(dev));
 
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 	ret = dm_scan_fdt_dev(dev);
diff --git a/drivers/i2c/i2c-versatile.c b/drivers/i2c/i2c-versatile.c
index 62831522bd3..69042d54205 100644
--- a/drivers/i2c/i2c-versatile.c
+++ b/drivers/i2c/i2c-versatile.c
@@ -252,11 +252,6 @@ static int versatile_i2c_probe(struct udevice *dev)
 
 	priv->base = (phys_addr_t)dev_read_addr(dev);
 	priv->delay = 25;	/* 25us * 4 = 100kHz */
-	/*
-	 * U-Boot still doesn't assign automatically
-	 * sequence numbers to devices
-	 */
-	dev->req_seq = 1;
 
 	return 0;
 }
diff --git a/drivers/i2c/intel_i2c.c b/drivers/i2c/intel_i2c.c
index 3b79cb40cd3..66d017a2615 100644
--- a/drivers/i2c/intel_i2c.c
+++ b/drivers/i2c/intel_i2c.c
@@ -269,21 +269,11 @@ static int intel_i2c_probe(struct udevice *dev)
 
 static int intel_i2c_bind(struct udevice *dev)
 {
-	static int num_cards __attribute__ ((section(".data")));
 	char name[20];
 
 	/* Create a unique device name for PCI type devices */
 	if (device_is_on_pci_bus(dev)) {
-		/*
-		 * ToDo:
-		 * Setting req_seq in the driver is probably not recommended.
-		 * But without a DT alias the number is not configured. And
-		 * using this driver is impossible for PCIe I2C devices.
-		 * This can be removed, once a better (correct) way for this
-		 * is found and implemented.
-		 */
-		dev->req_seq = num_cards;
-		sprintf(name, "intel_i2c#%u", num_cards++);
+		sprintf(name, "intel_i2c#%u", dev_seq(dev));
 		device_set_name(dev, name);
 	}
 
diff --git a/drivers/i2c/muxes/i2c-mux-uclass.c b/drivers/i2c/muxes/i2c-mux-uclass.c
index 26897554b0f..9a8cf8fb172 100644
--- a/drivers/i2c/muxes/i2c-mux-uclass.c
+++ b/drivers/i2c/muxes/i2c-mux-uclass.c
@@ -87,8 +87,8 @@ static int i2c_mux_post_bind(struct udevice *mux)
 
 		ret = device_bind_driver_to_node(mux, "i2c_mux_bus_drv",
 						 full_name, node, &dev);
-		debug("   - bind ret=%d, %s, req_seq %d\n", ret,
-		      dev ? dev->name : NULL, dev->req_seq);
+		debug("   - bind ret=%d, %s, seq %d\n", ret,
+		      dev ? dev->name : NULL, dev_seq(dev));
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
index fdb8fd42e5c..5cec4d68c90 100644
--- a/drivers/i2c/mvtwsi.c
+++ b/drivers/i2c/mvtwsi.c
@@ -823,8 +823,8 @@ static int mvtwsi_i2c_bind(struct udevice *bus)
 	struct mvtwsi_registers *twsi = dev_read_addr_ptr(bus);
 
 	/* Disable the hidden slave in i2c0 of these platforms */
-	if ((IS_ENABLED(CONFIG_ARMADA_38X) || IS_ENABLED(CONFIG_ARCH_KIRKWOOD))
-			&& bus->req_seq == 0)
+	if ((IS_ENABLED(CONFIG_ARMADA_38X) ||
+	    IS_ENABLED(CONFIG_ARCH_KIRKWOOD)) && !dev_seq(bus))
 		twsi_disable_i2c_slave(twsi);
 
 	return 0;
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 12/27] net: Update to use new sequence numbers
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (10 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 11/27] i2c: Update for new sequence numbers Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 13/27] pci: " Simon Glass
                   ` (16 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

Checking for seq == -1 is effectively checking that the device is
activated. The new sequence numbers are never -1 for a bound device, so
update the check.

Also drop the note about valid sequence numbers so it is accurate with the
new approach.

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

 drivers/net/dwc_eth_qos.c | 2 +-
 net/eth-uclass.c          | 7 ++-----
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index db1102562f6..74893f5e8b1 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1155,7 +1155,7 @@ static int eqos_read_rom_hwaddr(struct udevice *dev)
 	struct eth_pdata *pdata = dev_get_platdata(dev);
 
 #ifdef CONFIG_ARCH_IMX8M
-	imx_get_mac_from_fuse(dev->req_seq, pdata->enetaddr);
+	imx_get_mac_from_fuse(dev_seq(dev), pdata->enetaddr);
 #endif
 	return !is_valid_ethaddr(pdata->enetaddr);
 }
diff --git a/net/eth-uclass.c b/net/eth-uclass.c
index e6a3cd1ee6a..5c1ee57fb59 100644
--- a/net/eth-uclass.c
+++ b/net/eth-uclass.c
@@ -126,9 +126,6 @@ struct udevice *eth_get_dev_by_name(const char *devname)
 
 	uclass_foreach_dev(it, uc) {
 		/*
-		 * We need the seq to be valid, so try to probe it.
-		 * If the probe fails, the seq will not match since it will be
-		 * -1 instead of what we are looking for.
 		 * We don't care about errors from probe here. Either they won't
 		 * match an alias or it will match a literal name and we'll pick
 		 * up the error when we try to probe again in eth_set_dev().
@@ -434,7 +431,7 @@ int eth_initialize(void)
 
 		bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
 		do {
-			if (dev_seq(dev) != -1) {
+			if (device_active(dev)) {
 				if (num_devices)
 					printf(", ");
 
@@ -446,7 +443,7 @@ int eth_initialize(void)
 
 			eth_write_hwaddr(dev);
 
-			if (dev_seq(dev) != -1)
+			if (device_active(dev))
 				num_devices++;
 			uclass_next_device_check(&dev);
 		} while (dev);
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 13/27] pci: Update to use new sequence numbers
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (11 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 12/27] net: Update to use " Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 14/27] spi: Update for " Simon Glass
                   ` (15 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

Now that we know the sequence number at bind time, there is no need for
special-case code in dm_pci_hose_probe_bus().

Note: the PCI_CAP_ID_EA code may need a look, but there are no test
failures so I have left it as is.

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

 drivers/pci/pci-uclass.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 99dcd342efe..abc3de84db3 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -632,7 +632,7 @@ int dm_pci_hose_probe_bus(struct udevice *bus)
 				    &reg);
 		sub_bus = reg;
 	} else {
-		sub_bus = pci_get_bus_max() + 1;
+		sub_bus = dev_seq(bus);
 	}
 	debug("%s: bus = %d/%s\n", __func__, sub_bus, bus->name);
 	dm_pciauto_prescan_setup_bridge(bus, sub_bus);
@@ -644,14 +644,6 @@ int dm_pci_hose_probe_bus(struct udevice *bus)
 		return ret;
 	}
 
-	if (!ea_pos) {
-		if (sub_bus != dev_seq(bus)) {
-			debug("%s: Internal error, bus '%s' got seq %d, expected %d\n",
-			      __func__, bus->name, dev_seq(bus), sub_bus);
-			return -EPIPE;
-		}
-		sub_bus = pci_get_bus_max();
-	}
 	dm_pciauto_postscan_setup_bridge(bus, sub_bus);
 
 	return sub_bus;
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 14/27] spi: Update for new sequence numbers
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (12 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 13/27] pci: " Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 15/27] usb: ehci-mx6: Drop assignment of sequence number Simon Glass
                   ` (14 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

Use the new sequence number in all cases. Drop the rockchip case because
the sequence number should be 0 anyway, and assigning to the sequence
number is not permitted.

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

 drivers/spi/fsl_dspi.c | 2 +-
 drivers/spi/rk_spi.c   | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c
index 71b045e04cb..67807b2e109 100644
--- a/drivers/spi/fsl_dspi.c
+++ b/drivers/spi/fsl_dspi.c
@@ -569,7 +569,7 @@ static int fsl_dspi_release_bus(struct udevice *dev)
  */
 static int fsl_dspi_bind(struct udevice *bus)
 {
-	debug("%s assigned req_seq %d.\n", bus->name, bus->req_seq);
+	debug("%s assigned seq %d.\n", bus->name, dev_seq(bus));
 	return 0;
 }
 
diff --git a/drivers/spi/rk_spi.c b/drivers/spi/rk_spi.c
index c5363c24190..3f71ec99b11 100644
--- a/drivers/spi/rk_spi.c
+++ b/drivers/spi/rk_spi.c
@@ -186,7 +186,6 @@ static int conv_of_platdata(struct udevice *dev)
 	ret = clk_get_by_driver_info(dev, dtplat->clocks, &priv->clk);
 	if (ret < 0)
 		return ret;
-	dev->req_seq = 0;
 
 	return 0;
 }
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 15/27] usb: ehci-mx6: Drop assignment of sequence number
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (13 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 14/27] spi: Update for " Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 16/27] usb: Update for new sequence numbers Simon Glass
                   ` (13 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

This hack cannot work in the new sequence-numbering scheme. Remove it
while we wait for the maintainer to complete DM conversion as noted in
the existing comment.

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

 drivers/usb/host/ehci-mx6.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index 8fa136f4eeb..d7a6ee6d0e6 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -569,10 +569,16 @@ static int ehci_usb_bind(struct udevice *dev)
 	 * With these changes in place, the ad-hoc indexing goes away and
 	 * the driver is fully converted to DT probing.
 	 */
-	u32 controller_spacing = is_mx7() ? 0x10000 : 0x200;
-	fdt_addr_t addr = devfdt_get_addr_index(dev, 0);
 
-	dev->req_seq = (addr - USB_BASE_ADDR) / controller_spacing;
+	/*
+	 * FIXME: This cannot work with the new sequence numbers.
+	 * Please complete the DM conversion.
+	 *
+	 * u32 controller_spacing = is_mx7() ? 0x10000 : 0x200;
+	 * fdt_addr_t addr = devfdt_get_addr_index(dev, 0);
+	 *
+	 * dev->req_seq = (addr - USB_BASE_ADDR) / controller_spacing;
+	 */
 
 	return 0;
 }
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 16/27] usb: Update for new sequence numbers
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (14 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 15/27] usb: ehci-mx6: Drop assignment of sequence number Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 17/27] x86: Drop unnecessary mp_init logic Simon Glass
                   ` (12 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

Use the new sequence number in all cases. Since all devices are assigned
a number when bound, this hack should not be needed.

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

 drivers/usb/host/ehci-vf.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index 92b70ba1b30..dd82669b284 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -296,16 +296,14 @@ static const struct ehci_ops vf_ehci_ops = {
 
 static int vf_usb_bind(struct udevice *dev)
 {
-	static int num_controllers;
-
 	/*
 	 * Without this hack, if we return ENODEV for USB Controller 0, on
 	 * probe for the next controller, USB Controller 1 will be given a
 	 * sequence number of 0. This conflicts with our requirement of
 	 * sequence numbers while initialising the peripherals.
+	 *
+	 * FIXME: Check that this still works OK with the new sequence numbers
 	 */
-	dev->req_seq = num_controllers;
-	num_controllers++;
 
 	return 0;
 }
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 17/27] x86: Drop unnecessary mp_init logic
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (15 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 16/27] usb: Update for new sequence numbers Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 18/27] x86: Simplify acpi_device_infer_name() Simon Glass
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

Now that sequence numbers are set up when devices are bound, this code is
not needed. Also, we should use dev_seq() instead of req_seq. Update the
whole file accordingly.

Also fix up APL cpu while we are here.

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

 arch/x86/cpu/apollolake/cpu.c |  2 +-
 arch/x86/cpu/mp_init.c        | 23 +++++++----------------
 arch/x86/include/asm/mp.h     |  2 +-
 3 files changed, 9 insertions(+), 18 deletions(-)

diff --git a/arch/x86/cpu/apollolake/cpu.c b/arch/x86/cpu/apollolake/cpu.c
index d37f91d1ce1..328f79255f8 100644
--- a/arch/x86/cpu/apollolake/cpu.c
+++ b/arch/x86/cpu/apollolake/cpu.c
@@ -63,7 +63,7 @@ static int apl_get_info(const struct udevice *dev, struct cpu_info *info)
 
 static int acpi_cpu_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx)
 {
-	uint core_id = dev->req_seq;
+	uint core_id = dev_seq(dev);
 	int cores_per_package;
 	int ret;
 
diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index d2f1ee38cf0..5bb7abdf873 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -87,7 +87,7 @@ DECLARE_GLOBAL_DATA_PTR;
  *			intel,apic-id = <2>;
  *		};
  *
- * Here the 'reg' property is the CPU number and then is placed in dev->req_seq
+ * Here the 'reg' property is the CPU number and then is placed in dev_seq(cpu)
  * so that we can index into ap_callbacks[] using that. The APIC ID is different
  * and may not be sequential (it typically is if hyperthreading is supported).
  *
@@ -135,7 +135,7 @@ struct mp_flight_plan {
  *
  * @func: Function to run
  * @arg: Argument to pass to the function
- * @logical_cpu_number: Either a CPU number (i.e. dev->req_seq) or a special
+ * @logical_cpu_number: Either a CPU number (i.e. dev_seq(cpu) or a special
  *	value like MP_SELECT_BSP. It tells the AP whether it should process this
  *	callback
  */
@@ -152,7 +152,7 @@ static struct mp_flight_plan mp_info;
  * ap_callbacks - Callback mailbox array
  *
  * Array of callback, one entry for each available CPU, indexed by the CPU
- * number, which is dev->req_seq. The entry for the main CPU is never used.
+ * number, which is dev_seq(cpu). The entry for the main CPU is never used.
  * When this is NULL, there is no pending work for the CPU to run. When
  * non-NULL it points to the mp_callback structure. This is shared between all
  * CPUs, so should only be written by the main CPU.
@@ -562,7 +562,7 @@ static int get_bsp(struct udevice **devp, int *cpu_countp)
 	if (cpu_countp)
 		*cpu_countp = ret;
 
-	return dev->req_seq >= 0 ? dev->req_seq : 0;
+	return dev_seq(dev) >= 0 ? dev_seq(dev) : 0;
 }
 
 /**
@@ -614,7 +614,7 @@ static void store_callback(struct mp_callback **slot, struct mp_callback *val)
 static int run_ap_work(struct mp_callback *callback, struct udevice *bsp,
 		       int num_cpus, uint expire_ms)
 {
-	int cur_cpu = bsp->req_seq;
+	int cur_cpu = dev_seq(bsp);
 	int num_aps = num_cpus - 1; /* number of non-BSPs to get this message */
 	int cpus_accepted;
 	ulong start;
@@ -679,7 +679,7 @@ static int ap_wait_for_instruction(struct udevice *cpu, void *unused)
 	if (!IS_ENABLED(CONFIG_SMP_AP_WORK))
 		return 0;
 
-	per_cpu_slot = &ap_callbacks[cpu->req_seq];
+	per_cpu_slot = &ap_callbacks[dev_seq(cpu)];
 
 	while (1) {
 		struct mp_callback *cb = read_callback(per_cpu_slot);
@@ -694,7 +694,7 @@ static int ap_wait_for_instruction(struct udevice *cpu, void *unused)
 		mfence();
 		if (lcb.logical_cpu_number == MP_SELECT_ALL ||
 		    lcb.logical_cpu_number == MP_SELECT_APS ||
-		    cpu->req_seq == lcb.logical_cpu_number)
+		    dev_seq(cpu) == lcb.logical_cpu_number)
 			lcb.func(lcb.arg);
 
 		/* Indicate we are finished */
@@ -839,7 +839,6 @@ int mp_init(void)
 	int num_aps, num_cpus;
 	atomic_t *ap_count;
 	struct udevice *cpu;
-	struct uclass *uc;
 	int ret;
 
 	if (IS_ENABLED(CONFIG_QFW)) {
@@ -848,14 +847,6 @@ int mp_init(void)
 			return ret;
 	}
 
-	/*
-	 * Multiple APs are brought up simultaneously and they may get the same
-	 * seq num in the uclass_resolve_seq() during device_probe(). To avoid
-	 * this, set req_seq to the reg number in the device tree in advance.
-	 */
-	uclass_id_foreach_dev(UCLASS_CPU, cpu, uc)
-		cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
-
 	ret = get_bsp(&cpu, &num_cpus);
 	if (ret < 0) {
 		debug("Cannot init boot CPU: err=%d\n", ret);
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index 5f9b8c65643..1e4e35321de 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -114,7 +114,7 @@ typedef void (*mp_run_func)(void *arg);
  * Running on anything other than the boot CPU is only supported if
  * CONFIG_SMP_AP_WORK is enabled
  *
- * @cpu_select: CPU to run on (its dev->req_seq value), or MP_SELECT_ALL for
+ * @cpu_select: CPU to run on (its dev_seq() value), or MP_SELECT_ALL for
  *	all, or MP_SELECT_BSP for BSP
  * @func: Function to run
  * @arg: Argument to pass to the function
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 18/27] x86: Simplify acpi_device_infer_name()
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (16 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 17/27] x86: Drop unnecessary mp_init logic Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 19/27] gpio: Update for new sequence numbers Simon Glass
                   ` (10 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

There is no-longer any need to check if sequence numbers are valid, since
this is ensured by driver model. Drop the unwanted logic.

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

 lib/acpi/acpi_device.c | 27 +++------------------------
 test/dm/acpi.c         |  6 +-----
 2 files changed, 4 insertions(+), 29 deletions(-)

diff --git a/lib/acpi/acpi_device.c b/lib/acpi/acpi_device.c
index c3439a59883..ba0e6bf9ea8 100644
--- a/lib/acpi/acpi_device.c
+++ b/lib/acpi/acpi_device.c
@@ -784,16 +784,6 @@ static const char *acpi_name_from_id(enum uclass_id id)
 	}
 }
 
-static int acpi_check_seq(const struct udevice *dev)
-{
-	if (dev->req_seq == -1) {
-		log_warning("Device '%s' has no seq\n", dev->name);
-		return log_msg_ret("no seq", -ENXIO);
-	}
-
-	return dev->req_seq;
-}
-
 /* If you change this function, add test cases to dm_test_acpi_get_name() */
 int acpi_device_infer_name(const struct udevice *dev, char *out_name)
 {
@@ -826,29 +816,18 @@ int acpi_device_infer_name(const struct udevice *dev, char *out_name)
 		}
 	}
 	if (!name) {
-		int num;
-
 		switch (id) {
 		/* DSDT: acpi/lpss.asl */
 		case UCLASS_SERIAL:
-			num = acpi_check_seq(dev);
-			if (num < 0)
-				return num;
-			sprintf(out_name, "URT%d", num);
+			sprintf(out_name, "URT%d", dev_seq(dev));
 			name = out_name;
 			break;
 		case UCLASS_I2C:
-			num = acpi_check_seq(dev);
-			if (num < 0)
-				return num;
-			sprintf(out_name, "I2C%d", num);
+			sprintf(out_name, "I2C%d", dev_seq(dev));
 			name = out_name;
 			break;
 		case UCLASS_SPI:
-			num = acpi_check_seq(dev);
-			if (num < 0)
-				return num;
-			sprintf(out_name, "SPI%d", num);
+			sprintf(out_name, "SPI%d", dev_seq(dev));
 			name = out_name;
 			break;
 		default:
diff --git a/test/dm/acpi.c b/test/dm/acpi.c
index f5eddac10d0..021f776845e 100644
--- a/test/dm/acpi.c
+++ b/test/dm/acpi.c
@@ -123,7 +123,7 @@ UCLASS_DRIVER(testacpi) = {
 static int dm_test_acpi_get_name(struct unit_test_state *uts)
 {
 	char name[ACPI_NAME_MAX];
-	struct udevice *dev, *dev2, *i2c, *spi, *serial, *timer, *sound;
+	struct udevice *dev, *dev2, *i2c, *spi, *timer, *sound;
 	struct udevice *pci, *root;
 
 	/* Test getting the name from the driver */
@@ -146,10 +146,6 @@ static int dm_test_acpi_get_name(struct unit_test_state *uts)
 	ut_assertok(acpi_get_name(spi, name));
 	ut_asserteq_str("SPI0", name);
 
-	/* The uart has no sequence number, so this should fail */
-	ut_assertok(uclass_first_device(UCLASS_SERIAL, &serial));
-	ut_asserteq(-ENXIO, acpi_get_name(serial, name));
-
 	/* ACPI doesn't know about the timer */
 	ut_assertok(uclass_first_device(UCLASS_TIMER, &timer));
 	ut_asserteq(-ENOENT, acpi_get_name(timer, name));
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 19/27] gpio: Update for new sequence numbers
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (17 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 18/27] x86: Simplify acpi_device_infer_name() Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 20/27] pinctrl: " Simon Glass
                   ` (9 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

Use the dev_seq() sequence number in all cases.

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

 drivers/gpio/imx_rgpio2p.c | 2 +-
 drivers/gpio/iproc_gpio.c  | 2 +-
 drivers/gpio/mvebu_gpio.c  | 2 +-
 drivers/gpio/mxc_gpio.c    | 2 +-
 drivers/gpio/vybrid_gpio.c | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpio/imx_rgpio2p.c b/drivers/gpio/imx_rgpio2p.c
index 1e876f69147..428844db0cc 100644
--- a/drivers/gpio/imx_rgpio2p.c
+++ b/drivers/gpio/imx_rgpio2p.c
@@ -183,7 +183,7 @@ static int imx_rgpio2p_bind(struct udevice *dev)
 		return -ENOMEM;
 
 	plat->regs = (struct gpio_regs *)addr;
-	plat->bank_index = dev->req_seq;
+	plat->bank_index = dev_seq(dev);
 	dev->platdata = plat;
 
 	return 0;
diff --git a/drivers/gpio/iproc_gpio.c b/drivers/gpio/iproc_gpio.c
index cc26a1306b6..2371d0d0d77 100644
--- a/drivers/gpio/iproc_gpio.c
+++ b/drivers/gpio/iproc_gpio.c
@@ -252,7 +252,7 @@ static int iproc_gpio_ofdata_to_platdata(struct udevice *dev)
 		return ret;
 	}
 
-	snprintf(name, sizeof(name), "GPIO%d", dev->req_seq);
+	snprintf(name, sizeof(name), "GPIO%d", dev_seq(dev));
 	plat->name = strdup(name);
 	if (!plat->name)
 		return -ENOMEM;
diff --git a/drivers/gpio/mvebu_gpio.c b/drivers/gpio/mvebu_gpio.c
index 65eaa71c201..3639388e2f7 100644
--- a/drivers/gpio/mvebu_gpio.c
+++ b/drivers/gpio/mvebu_gpio.c
@@ -92,7 +92,7 @@ static int mvebu_gpio_probe(struct udevice *dev)
 
 	priv->regs = dev_read_addr_ptr(dev);
 	uc_priv->gpio_count = MVEBU_GPIOS_PER_BANK;
-	priv->name[0] = 'A' + dev->req_seq;
+	priv->name[0] = 'A' + dev_seq(dev);
 	uc_priv->bank_name = priv->name;
 
 	return 0;
diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c
index 88b920a0746..28ca57149c1 100644
--- a/drivers/gpio/mxc_gpio.c
+++ b/drivers/gpio/mxc_gpio.c
@@ -318,7 +318,7 @@ static int mxc_gpio_ofdata_to_platdata(struct udevice *dev)
 
 		plat->regs = (struct gpio_regs *)addr;
 	}
-	plat->bank_index = dev->req_seq;
+	plat->bank_index = dev_seq(dev);
 
 	return 0;
 }
diff --git a/drivers/gpio/vybrid_gpio.c b/drivers/gpio/vybrid_gpio.c
index 4efff5c3643..0474d2df2da 100644
--- a/drivers/gpio/vybrid_gpio.c
+++ b/drivers/gpio/vybrid_gpio.c
@@ -114,7 +114,7 @@ static int vybrid_gpio_odata_to_platdata(struct udevice *dev)
 		return -EINVAL;
 
 	plat->base = base_addr;
-	plat->chip = dev->req_seq;
+	plat->chip = dev_seq(dev);
 	plat->port_name = fdt_get_name(gd->fdt_blob, dev_of_offset(dev), NULL);
 
 	return 0;
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 20/27] pinctrl: Update for new sequence numbers
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (18 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 19/27] gpio: Update for new sequence numbers Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 21/27] dm: Switch over to use new sequence number for dev_seq() Simon Glass
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

Use the dev_seq() sequence number in all cases.

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

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

diff --git a/drivers/pinctrl/exynos/pinctrl-exynos.c b/drivers/pinctrl/exynos/pinctrl-exynos.c
index 4cdc071d559..64d78213a86 100644
--- a/drivers/pinctrl/exynos/pinctrl-exynos.c
+++ b/drivers/pinctrl/exynos/pinctrl-exynos.c
@@ -133,7 +133,7 @@ int exynos_pinctrl_probe(struct udevice *dev)
 
 	priv->base = base;
 	priv->pin_ctrl = (struct samsung_pin_ctrl *)dev_get_driver_data(dev) +
-				dev->req_seq;
+				dev_seq(dev);
 
 	return 0;
 }
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 21/27] dm: Switch over to use new sequence number for dev_seq()
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (19 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 20/27] pinctrl: " Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 22/27] dm: Drop uclass_resolve_seq() Simon Glass
                   ` (7 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

Update this function to use the new sequence number and fix up the test
that deals with this.

For networking, the sequence number has changed, so update to code to
suit.

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

 arch/sandbox/dts/test.dts |  2 +-
 drivers/core/uclass.c     |  6 ++----
 include/configs/sandbox.h |  2 +-
 include/dm/device.h       |  2 +-
 test/dm/eth.c             | 14 ++++++-------
 test/dm/test-fdt.c        | 42 +++++++++++++++++----------------------
 6 files changed, 30 insertions(+), 38 deletions(-)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index f3b766271d3..fb838049be5 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -33,7 +33,7 @@
 		testfdt6 = "/e-test";
 		testbus3 = "/some-bus";
 		testfdt0 = "/some-bus/c-test at 0";
-		testfdt1 = "/some-bus/c-test at 1";
+		testfdt12 = "/some-bus/c-test at 1";
 		testfdt3 = "/b-test";
 		testfdt5 = "/some-bus/c-test at 5";
 		testfdt8 = "/a-test";
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index d4de88bfb57..e28eea05f62 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -346,8 +346,7 @@ int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
 	uclass_foreach_dev(dev, uc) {
 		log_debug("   - %d %d '%s'\n",
 			  dev->req_seq, dev_seq(dev), dev->name);
-		if ((find_req_seq ? dev->req_seq : dev_seq(dev)) ==
-				seq_or_req_seq) {
+		if (dev_seq(dev) == seq_or_req_seq) {
 			*devp = dev;
 			log_debug("   - found\n");
 			return 0;
@@ -732,8 +731,7 @@ int uclass_resolve_seq(struct udevice *dev)
 	assert(dev_seq(dev) == -1);
 	ret = uclass_find_device_by_seq(uc_drv->id, dev->req_seq, false, &dup);
 	if (!ret) {
-		dm_warn("Device '%s': seq %d is in use by '%s'\n",
-			dev->name, dev->req_seq, dup->name);
+		/* Do nothing here for now */
 	} else if (ret == -ENODEV) {
 		/* Our requested sequence number is available */
 		if (dev->req_seq != -1)
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index e0708fe5739..70433bf5760 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -95,7 +95,7 @@
 #define SANDBOX_ETH_SETTINGS		"ethaddr=00:00:11:22:33:44\0" \
 					"eth3addr=00:00:11:22:33:45\0" \
 					"eth5addr=00:00:11:22:33:46\0" \
-					"eth6addr=00:00:11:22:33:47\0" \
+					"eth1addr=00:00:11:22:33:47\0" \
 					"ipaddr=1.2.3.4\0"
 
 #define MEM_LAYOUT_ENV_SETTINGS \
diff --git a/include/dm/device.h b/include/dm/device.h
index 80cd0955362..3362569dc98 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -192,7 +192,7 @@ static inline bool dev_has_of_node(struct udevice *dev)
 
 static inline int dev_seq(const struct udevice *dev)
 {
-	return dev->seq;
+	return dev->sqq;
 }
 
 /**
diff --git a/test/dm/eth.c b/test/dm/eth.c
index fa8a69da701..8e0d784a92d 100644
--- a/test/dm/eth.c
+++ b/test/dm/eth.c
@@ -49,7 +49,7 @@ static int dm_test_eth_alias(struct unit_test_state *uts)
 	ut_assertok(net_loop(PING));
 	ut_asserteq_str("eth at 10002000", env_get("ethact"));
 
-	env_set("ethact", "eth6");
+	env_set("ethact", "eth1");
 	ut_assertok(net_loop(PING));
 	ut_asserteq_str("eth at 10004000", env_get("ethact"));
 
@@ -106,7 +106,7 @@ static int dm_test_eth_act(struct unit_test_state *uts)
 	const char *ethname[DM_TEST_ETH_NUM] = {"eth at 10002000", "eth at 10003000",
 						"sbe5", "eth at 10004000"};
 	const char *addrname[DM_TEST_ETH_NUM] = {"ethaddr", "eth5addr",
-						 "eth3addr", "eth6addr"};
+						 "eth3addr", "eth1addr"};
 	char ethaddr[DM_TEST_ETH_NUM][18];
 	int i;
 
@@ -189,15 +189,15 @@ static int dm_test_eth_rotate(struct unit_test_state *uts)
 
 	/* Invalidate eth1's MAC address */
 	memset(ethaddr, '\0', sizeof(ethaddr));
-	strncpy(ethaddr, env_get("eth6addr"), 17);
-	/* Must disable access protection for eth6addr before clearing */
-	env_set(".flags", "eth6addr");
-	env_set("eth6addr", NULL);
+	strncpy(ethaddr, env_get("eth1addr"), 17);
+	/* Must disable access protection for eth1addr before clearing */
+	env_set(".flags", "eth1addr");
+	env_set("eth1addr", NULL);
 
 	retval = _dm_test_eth_rotate1(uts);
 
 	/* Restore the env */
-	env_set("eth6addr", ethaddr);
+	env_set("eth1addr", ethaddr);
 	env_set("ethrotate", NULL);
 
 	if (!retval) {
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 673ffb4de94..75b72313e86 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -329,6 +329,7 @@ DM_TEST(dm_test_fdt_pre_reloc, 0);
 static int dm_test_fdt_uclass_seq(struct unit_test_state *uts)
 {
 	struct udevice *dev;
+	int i;
 
 	/* A few basic santiy tests */
 	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 3, true, &dev));
@@ -337,7 +338,14 @@ static int dm_test_fdt_uclass_seq(struct unit_test_state *uts)
 	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 8, true, &dev));
 	ut_asserteq_str("a-test", dev->name);
 
-	ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 5,
+	/*
+	 * c-test at 0 has the testfdt0 alias but is not bound since some-bus does
+	 * not bind its children. So d-test gets it.
+	 */
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 0, true, &dev));
+	ut_asserteq_str("d-test", dev->name);
+
+	ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 9,
 						       true, &dev));
 	ut_asserteq_ptr(NULL, dev);
 
@@ -345,9 +353,6 @@ static int dm_test_fdt_uclass_seq(struct unit_test_state *uts)
 	ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 6, &dev));
 	ut_asserteq_str("e-test", dev->name);
 
-	ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 7,
-						       true, &dev));
-
 	/*
 	 * Note that c-test nodes are not probed since it is not a top-level
 	 * node
@@ -363,29 +368,18 @@ static int dm_test_fdt_uclass_seq(struct unit_test_state *uts)
 	ut_asserteq_str("d-test", dev->name);
 
 	/*
-	 * d-test actually gets 9, because thats the next free one after the
-	 * aliases.
+	 * g-test actually gets 2, because that number doesn't have an alias,
+	 * so it is free
 	 */
-	ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 9, &dev));
-	ut_asserteq_str("d-test", dev->name);
+	ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 2, &dev));
+	ut_asserteq_str("g-test", dev->name);
 
-	/* initially no one wants seq 10 */
-	ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_TEST_FDT, 10,
+	/* There should be no holes in our sequence numbers */
+	for (i = 0; i < 9; i++) {
+		ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, i, true,
 						      &dev));
-	ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
-	ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 4, &dev));
-
-	/* But now that it is probed, we can find it */
-	ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 10, &dev));
-	ut_asserteq_str("f-test", dev->name);
-
-	/*
-	 * And we should still have holes in our sequence numbers, that is 2
-	 * and 4 should not be used.
-	 */
-	ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 2,
-						       true, &dev));
-	ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 4,
+	}
+	ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 9,
 						       true, &dev));
 
 	return 0;
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 22/27] dm: Drop uclass_resolve_seq()
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (20 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 21/27] dm: Switch over to use new sequence number for dev_seq() Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 23/27] dm: Drop the unused arg in uclass_find_device_by_seq() Simon Glass
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

This function is not needed anymore. Drop it.

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

 drivers/core/device.c |  8 --------
 drivers/core/uclass.c | 39 ---------------------------------------
 include/dm/uclass.h   | 15 ---------------
 3 files changed, 62 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index bd58a9e946d..df188620149 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -427,7 +427,6 @@ int device_probe(struct udevice *dev)
 {
 	const struct driver *drv;
 	int ret;
-	int seq;
 
 	if (!dev)
 		return -EINVAL;
@@ -458,13 +457,6 @@ int device_probe(struct udevice *dev)
 			return 0;
 	}
 
-	seq = uclass_resolve_seq(dev);
-	if (seq < 0) {
-		ret = seq;
-		goto fail;
-	}
-	dev->seq = seq;
-
 	dev->flags |= DM_FLAG_ACTIVATED;
 
 	/*
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index e28eea05f62..b63ebb5d1e7 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -720,45 +720,6 @@ int uclass_unbind_device(struct udevice *dev)
 }
 #endif
 
-int uclass_resolve_seq(struct udevice *dev)
-{
-	struct uclass *uc = dev->uclass;
-	struct uclass_driver *uc_drv = uc->uc_drv;
-	struct udevice *dup;
-	int seq = 0;
-	int ret;
-
-	assert(dev_seq(dev) == -1);
-	ret = uclass_find_device_by_seq(uc_drv->id, dev->req_seq, false, &dup);
-	if (!ret) {
-		/* Do nothing here for now */
-	} else if (ret == -ENODEV) {
-		/* Our requested sequence number is available */
-		if (dev->req_seq != -1)
-			return dev->req_seq;
-	} else {
-		return ret;
-	}
-
-	if (CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(DM_SEQ_ALIAS) &&
-	    (uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS)) {
-		/*
-		 * dev_read_alias_highest_id() will return -1 if there no
-		 * alias. Thus we can always add one.
-		 */
-		seq = dev_read_alias_highest_id(uc_drv->name) + 1;
-	}
-
-	for (; seq < DM_MAX_SEQ; seq++) {
-		ret = uclass_find_device_by_seq(uc_drv->id, seq, false, &dup);
-		if (ret == -ENODEV)
-			break;
-		if (ret)
-			return ret;
-	}
-	return seq;
-}
-
 int uclass_pre_probe_device(struct udevice *dev)
 {
 	struct uclass_driver *uc_drv;
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index d1906236976..69a073a2733 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -365,21 +365,6 @@ int uclass_next_device_check(struct udevice **devp);
 int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data,
 				struct udevice **devp);
 
-/**
- * uclass_resolve_seq() - Resolve a device's sequence number
- *
- * On entry dev->seq is -1, and dev->req_seq may be -1 (to allocate a
- * sequence number automatically, or >= 0 to select a particular number.
- * If the requested sequence number is in use, then this device will
- * be allocated another one.
- *
- * Note that the device's seq value is not changed by this function.
- *
- * @dev: Device for which to allocate sequence number
- * @return sequence number allocated, or -ve on error
- */
-int uclass_resolve_seq(struct udevice *dev);
-
 /**
  * uclass_alloc_all_seqs() - Make sure that all devices have sequence numbers
  *
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 23/27] dm: Drop the unused arg in uclass_find_device_by_seq()
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (21 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 22/27] dm: Drop uclass_resolve_seq() Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:53 ` [PATCH 24/27] dm: core: Simplify uclass_find_next_free_req_seq() Simon Glass
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

Now that there is only one sequence number (rather than both requested and
assigned ones) we can simplify this function. Also update its caller to
simplify the logic.

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

 arch/arm/mach-k3/am6_init.c     |  2 +-
 arch/arm/mach-k3/j721e_init.c   |  2 +-
 arch/arm/mach-k3/sysfw-loader.c |  2 +-
 drivers/core/device.c           | 16 +++++--------
 drivers/core/uclass.c           | 22 ++++++------------
 drivers/spi/spi-uclass.c        |  4 ++--
 drivers/usb/host/usb-uclass.c   |  4 ++--
 include/dm/device.h             | 18 +++++----------
 include/dm/uclass-internal.h    | 18 +++++----------
 net/eth-uclass.c                |  2 +-
 test/dm/bus.c                   | 16 ++++++-------
 test/dm/test-fdt.c              | 40 ++++++++++++++++-----------------
 12 files changed, 58 insertions(+), 88 deletions(-)

diff --git a/arch/arm/mach-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c
index 603834e5078..0fed5aec59d 100644
--- a/arch/arm/mach-k3/am6_init.c
+++ b/arch/arm/mach-k3/am6_init.c
@@ -208,7 +208,7 @@ void board_init_f(ulong dummy)
 	 * firmware (SYSFW) image for various purposes and SYSFW depends on us
 	 * to initialize its pin settings.
 	 */
-	ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, true, &dev);
+	ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev);
 	if (!ret)
 		pinctrl_select_state(dev, "default");
 
diff --git a/arch/arm/mach-k3/j721e_init.c b/arch/arm/mach-k3/j721e_init.c
index a36e4ed603b..0201690f93c 100644
--- a/arch/arm/mach-k3/j721e_init.c
+++ b/arch/arm/mach-k3/j721e_init.c
@@ -167,7 +167,7 @@ void board_init_f(ulong dummy)
 	 * firmware (SYSFW) image for various purposes and SYSFW depends on us
 	 * to initialize its pin settings.
 	 */
-	ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, true, &dev);
+	ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev);
 	if (!ret)
 		pinctrl_select_state(dev, "default");
 
diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-k3/sysfw-loader.c
index 78c158c63f7..708d9c8508e 100644
--- a/arch/arm/mach-k3/sysfw-loader.c
+++ b/arch/arm/mach-k3/sysfw-loader.c
@@ -223,7 +223,7 @@ static void *k3_sysfw_get_spi_addr(void)
 	int ret;
 
 	ret = uclass_find_device_by_seq(UCLASS_SPI, CONFIG_SF_DEFAULT_BUS,
-					true, &dev);
+					&dev);
 	if (ret)
 		return NULL;
 
diff --git a/drivers/core/device.c b/drivers/core/device.c
index df188620149..d57a8bc1343 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -653,15 +653,15 @@ int device_get_child_count(const struct udevice *parent)
 	return count;
 }
 
-int device_find_child_by_seq(const struct udevice *parent, int seq_or_req_seq,
-			     bool find_req_seq, struct udevice **devp)
+int device_find_child_by_seq(const struct udevice *parent, int seq,
+			     struct udevice **devp)
 {
 	struct udevice *dev;
 
 	*devp = NULL;
 
 	list_for_each_entry(dev, &parent->child_head, sibling_node) {
-		if (dev->sqq == seq_or_req_seq) {
+		if (dev->sqq == seq) {
 			*devp = dev;
 			return 0;
 		}
@@ -677,14 +677,8 @@ int device_get_child_by_seq(const struct udevice *parent, int seq,
 	int ret;
 
 	*devp = NULL;
-	ret = device_find_child_by_seq(parent, seq, false, &dev);
-	if (ret == -ENODEV) {
-		/*
-		 * We didn't find it in probed devices. See if there is one
-		 * that will request this seq if probed.
-		 */
-		ret = device_find_child_by_seq(parent, seq, true, &dev);
-	}
+	ret = device_find_child_by_seq(parent, seq, &dev);
+
 	return device_get_device_tail(dev, ret, devp);
 }
 
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index b63ebb5d1e7..48d81221c38 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -328,25 +328,23 @@ void uclass_alloc_all_seqs(void)
 	}
 }
 
-int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
-			      bool find_req_seq, struct udevice **devp)
+int uclass_find_device_by_seq(enum uclass_id id, int seq, struct udevice **devp)
 {
 	struct uclass *uc;
 	struct udevice *dev;
 	int ret;
 
 	*devp = NULL;
-	log_debug("%d %d\n", find_req_seq, seq_or_req_seq);
-	if (seq_or_req_seq == -1)
+	log_debug("%d\n", seq);
+	if (seq == -1)
 		return -ENODEV;
 	ret = uclass_get(id, &uc);
 	if (ret)
 		return ret;
 
 	uclass_foreach_dev(dev, uc) {
-		log_debug("   - %d %d '%s'\n",
-			  dev->req_seq, dev_seq(dev), dev->name);
-		if (dev_seq(dev) == seq_or_req_seq) {
+		log_debug("   - %d '%s'\n", dev->sqq, dev->name);
+		if (dev->sqq == seq) {
 			*devp = dev;
 			log_debug("   - found\n");
 			return 0;
@@ -506,14 +504,8 @@ int uclass_get_device_by_seq(enum uclass_id id, int seq, struct udevice **devp)
 	int ret;
 
 	*devp = NULL;
-	ret = uclass_find_device_by_seq(id, seq, false, &dev);
-	if (ret == -ENODEV) {
-		/*
-		 * We didn't find it in probed devices. See if there is one
-		 * that will request this seq if probed.
-		 */
-		ret = uclass_find_device_by_seq(id, seq, true, &dev);
-	}
+	ret = uclass_find_device_by_seq(id, seq, &dev);
+
 	return uclass_get_device_tail(dev, ret, devp);
 }
 
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 55a8eed8901..08f165837d2 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -273,7 +273,7 @@ int spi_cs_is_valid(unsigned int busnum, unsigned int cs)
 	struct udevice *bus;
 	int ret;
 
-	ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, false, &bus);
+	ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, &bus);
 	if (ret) {
 		debug("%s: No bus %d\n", __func__, busnum);
 		return ret;
@@ -302,7 +302,7 @@ int spi_find_bus_and_cs(int busnum, int cs, struct udevice **busp,
 	struct udevice *bus, *dev;
 	int ret;
 
-	ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, false, &bus);
+	ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, &bus);
 	if (ret) {
 		debug("%s: No bus %d\n", __func__, busnum);
 		return ret;
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 453c2bbb0b6..de8a244625e 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -394,7 +394,7 @@ int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp)
 	int ret;
 
 	/* Find the old device and remove it */
-	ret = uclass_find_device_by_seq(UCLASS_USB, 0, true, &dev);
+	ret = uclass_find_device_by_seq(UCLASS_USB, 0, &dev);
 	if (ret)
 		return ret;
 	ret = device_remove(dev, DM_REMOVE_NORMAL);
@@ -417,7 +417,7 @@ int usb_remove_ehci_gadget(struct ehci_ctrl **ctlrp)
 	int ret;
 
 	/* Find the old device and remove it */
-	ret = uclass_find_device_by_seq(UCLASS_USB, 0, true, &dev);
+	ret = uclass_find_device_by_seq(UCLASS_USB, 0, &dev);
 	if (ret)
 		return ret;
 	ret = device_remove(dev, DM_REMOVE_NORMAL);
diff --git a/include/dm/device.h b/include/dm/device.h
index 3362569dc98..073c5438fc2 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -452,24 +452,16 @@ int device_get_child_count(const struct udevice *parent);
 /**
  * device_find_child_by_seq() - Find a child device based on a sequence
  *
- * This searches for a device with the given seq or req_seq.
- *
- * For seq, if an active device has this sequence it will be returned.
- * If there is no such device then this will return -ENODEV.
- *
- * For req_seq, if a device (whether activated or not) has this req_seq
- * value, that device will be returned. This is a strong indication that
- * the device will receive that sequence when activated.
+ * This searches for a device with the given seq.
  *
  * @parent: Parent device
- * @seq_or_req_seq: Sequence number to find (0=first)
- * @find_req_seq: true to find req_seq, false to find seq
+ * @seq: Sequence number to find (0=first)
  * @devp: Returns pointer to device (there is only one per for each seq).
  * Set to NULL if none is found
- * @return 0 if OK, -ve on error
+ * @return 0 if OK, -ENODEV if not found
  */
-int device_find_child_by_seq(const struct udevice *parent, int seq_or_req_seq,
-			     bool find_req_seq, struct udevice **devp);
+int device_find_child_by_seq(const struct udevice *parent, int seq,
+			     struct udevice **devp);
 
 /**
  * device_get_child_by_seq() - Get a child device based on a sequence
diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h
index 2c21871e0fd..9c23d3f223e 100644
--- a/include/dm/uclass-internal.h
+++ b/include/dm/uclass-internal.h
@@ -103,25 +103,17 @@ int uclass_find_device_by_name(enum uclass_id id, const char *name,
 /**
  * uclass_find_device_by_seq() - Find uclass device based on ID and sequence
  *
- * This searches for a device with the given seq or req_seq.
- *
- * For seq, if an active device has this sequence it will be returned.
- * If there is no such device then this will return -ENODEV.
- *
- * For req_seq, if a device (whether activated or not) has this req_seq
- * value, that device will be returned. This is a strong indication that
- * the device will receive that sequence when activated.
+ * This searches for a device with the given seq.
  *
  * The device is NOT probed, it is merely returned.
  *
  * @id: ID to look up
- * @seq_or_req_seq: Sequence number to find (0=first)
- * @find_req_seq: true to find req_seq, false to find seq
+ * @seq: Sequence number to find (0=first)
  * @devp: Returns pointer to device (there is only one per for each seq)
- * @return 0 if OK, -ve on error
+ * @return 0 if OK, -ENODEV if not found
  */
-int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
-			      bool find_req_seq, struct udevice **devp);
+int uclass_find_device_by_seq(enum uclass_id id, int seq,
+			      struct udevice **devp);
 
 /**
  * uclass_find_device_by_of_offset() - Find a uclass device by device tree node
diff --git a/net/eth-uclass.c b/net/eth-uclass.c
index 5c1ee57fb59..4b4aaecf366 100644
--- a/net/eth-uclass.c
+++ b/net/eth-uclass.c
@@ -232,7 +232,7 @@ static int on_ethaddr(const char *name, const char *value, enum env_op op,
 	/* look for an index after "eth" */
 	index = simple_strtoul(name + 3, NULL, 10);
 
-	retval = uclass_find_device_by_seq(UCLASS_ETH, index, false, &dev);
+	retval = uclass_find_device_by_seq(UCLASS_ETH, index, &dev);
 	if (!retval) {
 		struct eth_pdata *pdata = dev->platdata;
 		switch (op) {
diff --git a/test/dm/bus.c b/test/dm/bus.c
index e1fa67d91e1..27dd066350e 100644
--- a/test/dm/bus.c
+++ b/test/dm/bus.c
@@ -157,17 +157,17 @@ static int dm_test_bus_children_funcs(struct unit_test_state *uts)
 	ut_asserteq_str("c-test at 5", dev->name);
 
 	/* Device with sequence number 0 should be accessible */
-	ut_asserteq(-ENODEV, device_find_child_by_seq(bus, -1, true, &dev));
-	ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
+	ut_asserteq(-ENODEV, device_find_child_by_seq(bus, -1, &dev));
+	ut_assertok(device_find_child_by_seq(bus, 0, &dev));
 	ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
-	ut_asserteq(0, device_find_child_by_seq(bus, 0, false, &dev));
+	ut_asserteq(0, device_find_child_by_seq(bus, 0, &dev));
 	ut_assertok(device_get_child_by_seq(bus, 0, &dev));
 	ut_assert(dev->flags & DM_FLAG_ACTIVATED);
-	ut_asserteq(0, device_find_child_by_seq(bus, 0, false, &dev));
+	ut_asserteq(0, device_find_child_by_seq(bus, 0, &dev));
 
 	/* There is no device with sequence number 2 */
-	ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, false, &dev));
-	ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, true, &dev));
+	ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, &dev));
+	ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, &dev));
 	ut_asserteq(-ENODEV, device_get_child_by_seq(bus, 2, &dev));
 
 	/* Looking for something that is not a child */
@@ -221,7 +221,7 @@ static int dm_test_bus_children_iterators(struct unit_test_state *uts)
 	ut_asserteq_ptr(dev, NULL);
 
 	/* Move to the next child without using device_find_first_child() */
-	ut_assertok(device_find_child_by_seq(bus, 5, true, &dev));
+	ut_assertok(device_find_child_by_seq(bus, 5, &dev));
 	ut_asserteq_str("c-test at 5", dev->name);
 	ut_assertok(device_find_next_child(&dev));
 	ut_asserteq_str("c-test at 0", dev->name);
@@ -246,7 +246,7 @@ static int test_bus_parent_data(struct unit_test_state *uts)
 	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
 
 	/* Check that parent data is allocated */
-	ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
+	ut_assertok(device_find_child_by_seq(bus, 0, &dev));
 	ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
 	ut_assertok(device_get_child_by_seq(bus, 0, &dev));
 	parent_data = dev_get_parent_priv(dev);
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 75b72313e86..50267f2fc26 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -332,21 +332,21 @@ static int dm_test_fdt_uclass_seq(struct unit_test_state *uts)
 	int i;
 
 	/* A few basic santiy tests */
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 3, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 3, &dev));
 	ut_asserteq_str("b-test", dev->name);
 
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 8, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 8, &dev));
 	ut_asserteq_str("a-test", dev->name);
 
 	/*
 	 * c-test at 0 has the testfdt0 alias but is not bound since some-bus does
 	 * not bind its children. So d-test gets it.
 	 */
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 0, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 0, &dev));
 	ut_asserteq_str("d-test", dev->name);
 
 	ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 9,
-						       true, &dev));
+						       &dev));
 	ut_asserteq_ptr(NULL, dev);
 
 	/* Test aliases */
@@ -376,11 +376,11 @@ static int dm_test_fdt_uclass_seq(struct unit_test_state *uts)
 
 	/* There should be no holes in our sequence numbers */
 	for (i = 0; i < 9; i++) {
-		ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, i, true,
+		ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, i,
 						      &dev));
 	}
 	ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 9,
-						       true, &dev));
+						       &dev));
 
 	return 0;
 }
@@ -581,30 +581,30 @@ static int dm_test_fdt_translation(struct unit_test_state *uts)
 	fdt32_t dma_addr[2];
 
 	/* Some simple translations */
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, &dev));
 	ut_asserteq_str("dev@0,0", dev->name);
 	ut_asserteq(0x8000, dev_read_addr(dev));
 
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 1, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 1, &dev));
 	ut_asserteq_str("dev at 1,100", dev->name);
 	ut_asserteq(0x9000, dev_read_addr(dev));
 
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 2, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 2, &dev));
 	ut_asserteq_str("dev at 2,200", dev->name);
 	ut_asserteq(0xA000, dev_read_addr(dev));
 
 	/* No translation for busses with #size-cells == 0 */
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 3, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 3, &dev));
 	ut_asserteq_str("dev at 42", dev->name);
 	ut_asserteq(0x42, dev_read_addr(dev));
 
 	/* dma address translation */
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, &dev));
 	dma_addr[0] = cpu_to_be32(0);
 	dma_addr[1] = cpu_to_be32(0);
 	ut_asserteq(0x10000000, dev_translate_dma_address(dev, dma_addr));
 
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 1, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 1, &dev));
 	dma_addr[0] = cpu_to_be32(1);
 	dma_addr[1] = cpu_to_be32(0x100);
 	ut_asserteq(0x20000000, dev_translate_dma_address(dev, dma_addr));
@@ -622,7 +622,7 @@ static int dm_test_fdt_get_addr_ptr_flat(struct unit_test_state *uts)
 	ut_assertok(uclass_first_device_err(UCLASS_GPIO, &gpio));
 	ut_assertnull(devfdt_get_addr_ptr(gpio));
 
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, &dev));
 	ptr = devfdt_get_addr_ptr(dev);
 	ut_asserteq_ptr((void *)0x8000, ptr);
 
@@ -637,7 +637,7 @@ static int dm_test_fdt_remap_addr_flat(struct unit_test_state *uts)
 	fdt_addr_t addr;
 	void *paddr;
 
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, &dev));
 
 	addr = devfdt_get_addr(dev);
 	ut_asserteq(0x8000, addr);
@@ -658,7 +658,7 @@ static int dm_test_fdt_remap_addr_index_flat(struct unit_test_state *uts)
 	fdt_size_t size;
 	void *paddr;
 
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, &dev));
 
 	addr = devfdt_get_addr_size_index(dev, 0, &size);
 	ut_asserteq(0x8000, addr);
@@ -680,7 +680,7 @@ static int dm_test_fdt_remap_addr_name_flat(struct unit_test_state *uts)
 	fdt_size_t size;
 	void *paddr;
 
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, &dev));
 
 	addr = devfdt_get_addr_size_name(dev, "sandbox-dummy-0", &size);
 	ut_asserteq(0x8000, addr);
@@ -701,7 +701,7 @@ static int dm_test_fdt_remap_addr_live(struct unit_test_state *uts)
 	fdt_addr_t addr;
 	void *paddr;
 
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, &dev));
 
 	addr = dev_read_addr(dev);
 	ut_asserteq(0x8000, addr);
@@ -722,7 +722,7 @@ static int dm_test_fdt_remap_addr_index_live(struct unit_test_state *uts)
 	fdt_size_t size;
 	void *paddr;
 
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, &dev));
 
 	addr = dev_read_addr_size_index(dev, 0, &size);
 	ut_asserteq(0x8000, addr);
@@ -744,7 +744,7 @@ static int dm_test_fdt_remap_addr_name_live(struct unit_test_state *uts)
 	fdt_size_t size;
 	void *paddr;
 
-	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, &dev));
 
 	addr = dev_read_addr_size_name(dev, "sandbox-dummy-0", &size);
 	ut_asserteq(0x8000, addr);
@@ -779,7 +779,7 @@ static int dm_test_fdt_livetree_writing(struct unit_test_state *uts)
 
 	device_bind_driver_to_node(dm_root(), "usb_sandbox", "usb at 2", node,
 				   &dev);
-	ut_assertok(uclass_find_device_by_seq(UCLASS_USB, 2, true, &dev));
+	ut_assertok(uclass_find_device_by_seq(UCLASS_USB, 2, &dev));
 
 	/* Test string property setting */
 
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 24/27] dm: core: Simplify uclass_find_next_free_req_seq()
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (22 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 23/27] dm: Drop the unused arg in uclass_find_device_by_seq() Simon Glass
@ 2020-11-30  1:53 ` Simon Glass
  2020-11-30  1:54 ` [PATCH 25/27] cmd: Drop use of old sequence numbers in commands Simon Glass
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:53 UTC (permalink / raw)
  To: u-boot

This function current deals with req_seq which is deprecated. Update it to
use the new sequence numbers. Rename the function to make this clear.

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

 drivers/core/device.c        |  7 +++----
 drivers/core/uclass.c        |  6 +++---
 include/dm/uclass-internal.h | 14 +++++++-------
 3 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index d57a8bc1343..d9648f9394e 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -94,16 +94,15 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
 				if (dev->req_seq == -1) {
 					auto_seq = true;
 					dev->req_seq =
-						uclass_find_next_free_req_seq(
-							uc);
+						uclass_find_next_free_seq(uc);
 				}
 			}
 		} else {
 			auto_seq = true;
-			dev->req_seq = uclass_find_next_free_req_seq(uc);
+			dev->req_seq = uclass_find_next_free_seq(uc);
 		}
 		if (auto_seq && !(gd->flags & GD_FLG_DM_NO_SEQ))
-			dev->sqq = uclass_find_next_free_req_seq(uc);
+			dev->sqq = uclass_find_next_free_seq(uc);
 	}
 
 	if (drv->platdata_auto_alloc_size) {
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 48d81221c38..8d5e92da288 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -272,14 +272,14 @@ int uclass_find_device_by_name(enum uclass_id id, const char *name,
 	return -ENODEV;
 }
 
-int uclass_find_next_free_req_seq(struct uclass *uc)
+int uclass_find_next_free_seq(struct uclass *uc)
 {
 	struct udevice *dev;
 	int max = -1;
 
 	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
-		if ((dev->req_seq != -1) && (dev->req_seq > max))
-			max = dev->req_seq;
+		if (dev->sqq != -1 && dev->sqq > max)
+			max = dev->sqq;
 	}
 
 	if (max == -1)
diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h
index 9c23d3f223e..50431bd847c 100644
--- a/include/dm/uclass-internal.h
+++ b/include/dm/uclass-internal.h
@@ -12,17 +12,17 @@
 #include <dm/ofnode.h>
 
 /**
- * uclass_find_next_free_req_seq() - Get the next free req_seq number
+ * uclass_find_next_free_seq() - Get the next free sequence number
  *
- * This returns the next free req_seq number. This is useful only if
- * OF_CONTROL is not used. The next free req_seq number is simply the
- * maximum req_seq of the uclass + 1.
- * This allows assiging req_seq number in the binding order.
+ * This returns the next free sequence number. This is useful only if
+ * OF_CONTROL is not used. The next free sequence number is simply the
+ * maximum sequence number used by al devices in the uclass + 1.
+ * This allows assiging the sequence number in the binding order.
  *
  * @uc:		uclass to check
- * @return	The next free req_seq number
+ * @return	The next free sequence number
  */
-int uclass_find_next_free_req_seq(struct uclass *uc);
+int uclass_find_next_free_seq(struct uclass *uc);
 
 /**
  * uclass_get_device_tail() - handle the end of a get_device call
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 25/27] cmd: Drop use of old sequence numbers in commands
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (23 preceding siblings ...)
  2020-11-30  1:53 ` [PATCH 24/27] dm: core: Simplify uclass_find_next_free_req_seq() Simon Glass
@ 2020-11-30  1:54 ` Simon Glass
  2020-11-30  1:54 ` [PATCH 26/27] dm: core: Drop seq and req_seq Simon Glass
                   ` (3 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:54 UTC (permalink / raw)
  To: u-boot

Several commands use sequence numbers. Update them to use the new ones.

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

 cmd/axi.c           | 4 ++--
 cmd/i2c.c           | 2 +-
 cmd/osd.c           | 4 ++--
 drivers/core/dump.c | 4 ++--
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/cmd/axi.c b/cmd/axi.c
index f7e206c04a7..c72197ee82b 100644
--- a/cmd/axi.c
+++ b/cmd/axi.c
@@ -33,9 +33,9 @@ static void show_bus(struct udevice *bus)
 {
 	struct udevice *dev;
 
-	printf("Bus %d:\t%s", bus->req_seq, bus->name);
+	printf("Bus %d:\t%s", dev_seq(bus), bus->name);
 	if (device_active(bus))
-		printf("  (active %d)", dev_seq(bus));
+		printf("  (active)");
 	printf("\n");
 	for (device_find_first_child(bus, &dev);
 	     dev;
diff --git a/cmd/i2c.c b/cmd/i2c.c
index f97d437af47..c5cace6a9c6 100644
--- a/cmd/i2c.c
+++ b/cmd/i2c.c
@@ -1700,7 +1700,7 @@ static void show_bus(struct udevice *bus)
 {
 	struct udevice *dev;
 
-	printf("Bus %d:\t%s", bus->req_seq, bus->name);
+	printf("Bus %d:\t%s", dev_seq(bus), bus->name);
 	if (device_active(bus))
 		printf("  (active %d)", dev_seq(bus));
 	printf("\n");
diff --git a/cmd/osd.c b/cmd/osd.c
index 9b8fd5c921e..703d640b04e 100644
--- a/cmd/osd.c
+++ b/cmd/osd.c
@@ -75,9 +75,9 @@ static int osd_get_osd_cur(struct udevice **osdp)
  */
 static void show_osd(struct udevice *osd)
 {
-	printf("OSD %d:\t%s", osd->req_seq, osd->name);
+	printf("OSD %d:\t%s", dev_seq(osd), osd->name);
 	if (device_active(osd))
-		printf("  (active %d)", dev_seq(osd));
+		printf("  (active)");
 	printf("\n");
 }
 
diff --git a/drivers/core/dump.c b/drivers/core/dump.c
index 9f440366734..83456d7e6e8 100644
--- a/drivers/core/dump.c
+++ b/drivers/core/dump.c
@@ -67,8 +67,8 @@ static void dm_display_line(struct udevice *dev, int index)
 	printf("%-3i %c %s @ %08lx", index,
 	       dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
 	       dev->name, (ulong)map_to_sysmem(dev));
-	if (dev_seq(dev) != -1 || dev->req_seq != -1)
-		printf(", seq %d, (req %d)", dev_seq(dev), dev->req_seq);
+	if (dev->sqq != -1)
+		printf(", seq %d", dev_seq(dev));
 	puts("\n");
 }
 
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 26/27] dm: core: Drop seq and req_seq
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (24 preceding siblings ...)
  2020-11-30  1:54 ` [PATCH 25/27] cmd: Drop use of old sequence numbers in commands Simon Glass
@ 2020-11-30  1:54 ` Simon Glass
  2020-11-30  1:54 ` [PATCH 27/27] dm: Update documentation for new sequence numbers Simon Glass
                   ` (2 subsequent siblings)
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:54 UTC (permalink / raw)
  To: u-boot

Now that migration to the new sequence numbers is complete, drop the old
fields. Add a test that covers the new behaviour.

Also drop the check for OF_PRIOR_STAGE since we always assign sequence
numbers now.

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

 drivers/core/device-remove.c |  1 -
 drivers/core/device.c        | 18 +++---------------
 include/dm/device.h          |  9 +--------
 test/dm/test-fdt.c           | 28 ++++++++++++++++++++++++++++
 4 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
index efdb0f29058..114bb1bcea8 100644
--- a/drivers/core/device-remove.c
+++ b/drivers/core/device-remove.c
@@ -207,7 +207,6 @@ int device_remove(struct udevice *dev, uint flags)
 	if (flags_remove(flags, drv->flags)) {
 		device_free(dev);
 
-		dev->seq = -1;
 		dev->flags &= ~DM_FLAG_ACTIVATED;
 	}
 
diff --git a/drivers/core/device.c b/drivers/core/device.c
index d9648f9394e..bcf437ac231 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -72,34 +72,23 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
 	dev->driver = drv;
 	dev->uclass = uc;
 
-	dev->seq = -1;
-	dev->req_seq = -1;
 	dev->sqq = -1;
 	if (CONFIG_IS_ENABLED(DM_SEQ_ALIAS) &&
 	    (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS)) {
 		/*
 		 * Some devices, such as a SPI bus, I2C bus and serial ports
 		 * are numbered using aliases.
-		 *
-		 * This is just a 'requested' sequence, and will be
-		 * resolved (and ->seq updated) when the device is probed.
 		 */
 		if (CONFIG_IS_ENABLED(OF_CONTROL) &&
 		    !CONFIG_IS_ENABLED(OF_PLATDATA)) {
 			if (uc->uc_drv->name && ofnode_valid(node)) {
-				dev_read_alias_seq(dev, &dev->sqq);
-				dev_read_alias_seq(dev, &dev->req_seq);
-			}
-			if (CONFIG_IS_ENABLED(OF_PRIOR_STAGE)) {
-				if (dev->req_seq == -1) {
+				if (dev_read_alias_seq(dev, &dev->sqq))
 					auto_seq = true;
-					dev->req_seq =
-						uclass_find_next_free_seq(uc);
-				}
+			} else {
+				auto_seq = true;
 			}
 		} else {
 			auto_seq = true;
-			dev->req_seq = uclass_find_next_free_seq(uc);
 		}
 		if (auto_seq && !(gd->flags & GD_FLG_DM_NO_SEQ))
 			dev->sqq = uclass_find_next_free_seq(uc);
@@ -518,7 +507,6 @@ fail_uclass:
 fail:
 	dev->flags &= ~DM_FLAG_ACTIVATED;
 
-	dev->seq = -1;
 	device_free(dev);
 
 	return ret;
diff --git a/include/dm/device.h b/include/dm/device.h
index 073c5438fc2..b95aa346820 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -131,16 +131,11 @@ enum {
  * @child_head: List of children of this device
  * @sibling_node: Next device in list of all devices
  * @flags: Flags for this device DM_FLAG_...
- * @sqq: Allocated sequence number for this device (-1 = none). This is set up
+ * @seq: Allocated sequence number for this device (-1 = none). This is set up
  * when the device is bound and is unique within the device's uclass. If the
  * device has an alias in the devicetree then that is used to set the sequence
  * number. Otherwise, the next available number is used. Sequence numbers are
  * used by certain commands that need device to be numbered (e.g. 'mmc dev')
- *
- * The following two fields are deprecated:
- * @req_seq: Requested sequence number for this device (-1 = any)
- * @seq: Allocated sequence number for this device (-1 = none). This is set up
- * when the device is probed and will be unique within the device's uclass.
  * @devres_head: List of memory allocations associated with this device.
  *		When CONFIG_DEVRES is enabled, devm_kmalloc() and friends will
  *		add to this list. Memory so-allocated will be freed
@@ -164,8 +159,6 @@ struct udevice {
 	struct list_head sibling_node;
 	uint32_t flags;
 	int sqq;
-	int req_seq;
-	int seq;
 #ifdef CONFIG_DEVRES
 	struct list_head devres_head;
 #endif
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 50267f2fc26..c4de91da102 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -386,6 +386,34 @@ static int dm_test_fdt_uclass_seq(struct unit_test_state *uts)
 }
 DM_TEST(dm_test_fdt_uclass_seq, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
 
+/* More tests for sequence numbers */
+static int dm_test_fdt_uclass_seq_more(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	ofnode node;
+
+	/* Check creating a device with an alias */
+	node = ofnode_path("/some-bus/c-test at 1");
+	ut_assertok(device_bind(dm_root(), DM_GET_DRIVER(testfdt_drv),
+				"c-test at 1", NULL, node, &dev));
+	ut_asserteq(0, uclass_get_device_by_seq(UCLASS_TEST_FDT, 12, &dev));
+
+	/*
+	 * Now bind a device without an alias. It should not get the next
+	 * sequence number after all aliases, skipping 10 and 11
+	 */
+	ut_assertok(device_bind(dm_root(), DM_GET_DRIVER(testfdt_drv),
+				"fred", NULL, ofnode_null(), &dev));
+	ut_asserteq(13, dev_seq(dev));
+
+	ut_assertok(device_bind(dm_root(), DM_GET_DRIVER(testfdt_drv),
+				"fred2", NULL, ofnode_null(), &dev));
+	ut_asserteq(14, dev_seq(dev));
+
+	return 0;
+}
+DM_TEST(dm_test_fdt_uclass_seq_more, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
 /* Test that we can find a device by device tree offset */
 static int dm_test_fdt_offset(struct unit_test_state *uts)
 {
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 27/27] dm: Update documentation for new sequence numbers
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (25 preceding siblings ...)
  2020-11-30  1:54 ` [PATCH 26/27] dm: core: Drop seq and req_seq Simon Glass
@ 2020-11-30  1:54 ` Simon Glass
  2020-12-01  8:01 ` [PATCH 00/27] dm: Change the way sequence numbers are implemented Heinrich Schuchardt
  2020-12-08 22:52 ` Michael Walle
  28 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-11-30  1:54 UTC (permalink / raw)
  To: u-boot

Update the driver model documention to describe how sequence numbers now
work.

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

 doc/driver-model/design.rst | 58 +++++++++++++++++++++----------------
 1 file changed, 33 insertions(+), 25 deletions(-)

diff --git a/doc/driver-model/design.rst b/doc/driver-model/design.rst
index 96525b6ccc5..2db00e660e1 100644
--- a/doc/driver-model/design.rst
+++ b/doc/driver-model/design.rst
@@ -515,11 +515,15 @@ cases. While it might be tempting to automatically renumber the devices
 where there are gaps in the sequence, this can lead to confusion and is
 not the way that U-Boot works.
 
-Each device can request a sequence number. If none is required then the
-device will be automatically allocated the next available sequence number.
+Whether a device gets a sequence number is controlled by the DM_SEQ_ALIAS
+Kconfig option, which can have a different value in U-Boot proper and SPL.
+If this option is not set, aliases are ignored and no devices will get
+sequence numbers.
 
-To specify the sequence number in the device tree an alias is typically
-used. Make sure that the uclass has the DM_UC_FLAG_SEQ_ALIAS flag set.
+Even if DM_SEQ_ALIAS is enabled, the uclass must have the DM_UC_FLAG_SEQ_ALIAS
+flag set, for its devices to be sequenced. If DM_UC_FLAG_SEQ_ALIAS is set for
+the uclass, all devices in that uclass will get a sequence number, either one
+set from the aliases, or the next available sequence number.
 
 .. code-block:: none
 
@@ -546,12 +550,23 @@ More commonly you can use node references, which expand to the full path:
 The alias resolves to the same string in this case, but this version is
 easier to read.
 
-Device sequence numbers are resolved when a device is probed. Before then
-the sequence number is only a request which may or may not be honoured,
-depending on what other devices have been probed. However the numbering is
-entirely under the control of the board author so a conflict is generally
-an error.
+Device sequence numbers are resolved when a device is bound and the number does
+not change for the life of the device.
 
+When U-Boot initially binds all its devices, it sets a flag called
+GD_FLG_DM_NO_SEQ. This makes it check the aliases first. Then the devices with
+no alias fill in the gaps.
+
+For example, if aliases mmc2 and mmc3 are defined but there is a third mmc
+device with no alias, it will be assigned a sequence number of 0. However once
+the initial setup is complete, the GD_FLG_DM_NO_SEQ flag is cleared and further
+devices will be assigned numbers after all existing ones for that uclass. So
+in this case calling device_bind() for a fourth mmc device will cause it to
+get a sequence number of 4, not 1. This helps separate the aliases (which are
+considered officially allocated numbers) from ad-hoc devices.
+
+Note that changing the sequence number for a device (e.g. in driver) is not
+permitted. If it is felt to be necessary, ask on the mailing list.
 
 Bus Drivers
 -----------
@@ -673,6 +688,10 @@ platdata will be NULL, but of_offset will be the offset of the device tree
 node that caused the device to be created. The uclass is set correctly for
 the device.
 
+The device's sequence number is assigned, either the requested one or the next
+available one (after all aliases are processed) if nothing particular is
+requested.
+
 The device's bind() method is permitted to perform simple actions, but
 should not scan the device tree node, not initialise hardware, nor set up
 structures or allocate memory. All of these tasks should be left for
@@ -735,7 +754,7 @@ The steps are:
    that U-Boot will cache platform data for devices which are regularly
    de/activated).
 
-   5. The device is marked 'platdata valid'.
+   6. The device is marked 'platdata valid'.
 
 Note that ofdata reading is always done (for a child and all its parents)
 before probing starts. Thus devices go through two distinct states when
@@ -780,11 +799,7 @@ as above and then following these steps (see device_probe()):
    This means (for example) that an I2C driver will require that its bus
    be activated.
 
-   2. The device's sequence number is assigned, either the requested one
-   (assuming no conflicts) or the next available one if there is a conflict
-   or nothing particular is requested.
-
-   4. The device's probe() method is called. This should do anything that
+   2. The device's probe() method is called. This should do anything that
    is required by the device to get it going. This could include checking
    that the hardware is actually present, setting up clocks for the
    hardware and setting up hardware registers to initial values. The code
@@ -799,9 +814,9 @@ as above and then following these steps (see device_probe()):
    allocate the priv space here yourself. The same applies also to
    platdata_auto_alloc_size. Remember to free them in the remove() method.
 
-   5. The device is marked 'activated'
+   3. The device is marked 'activated'
 
-   10. The uclass's post_probe() method is called, if one exists. This may
+   4. The uclass's post_probe() method is called, if one exists. This may
    cause the uclass to do some housekeeping to record the device as
    activated and 'known' by the uclass.
 
@@ -850,14 +865,7 @@ remove it. This performs the probe steps in reverse:
         or preferably ofdata_to_platdata()) and the deallocation in remove()
         are the responsibility of the driver author.
 
-   5. The device sequence number is set to -1, meaning that it no longer
-   has an allocated sequence. If the device is later reactivated and that
-   sequence number is still free, it may well receive the name sequence
-   number again. But from this point, the sequence number previously used
-   by this device will no longer exist (think of SPI bus 2 being removed
-   and bus 2 is no longer available for use).
-
-   6. The device is marked inactive. Note that it is still bound, so the
+   5. The device is marked inactive. Note that it is still bound, so the
    device structure itself is not freed at this point. Should the device be
    activated again, then the cycle starts again at step 2 above.
 
-- 
2.29.2.454.gaff20da3a2-goog

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

* [PATCH 01/27] linker_lists: Fix alignment issue
  2020-11-30  1:53 ` [PATCH 01/27] linker_lists: Fix alignment issue Simon Glass
@ 2020-11-30  6:20   ` Heinrich Schuchardt
  2020-11-30 20:11     ` Simon Glass
  0 siblings, 1 reply; 50+ messages in thread
From: Heinrich Schuchardt @ 2020-11-30  6:20 UTC (permalink / raw)
  To: u-boot

Am 30. November 2020 02:53:36 MEZ schrieb Simon Glass <sjg@chromium.org>:
>The linker script uses alphabetic sorting to group the different linker
>lists together. Each group has its own struct and potentially its own
>alignment. But when the linker packs the structs together it cannot
>ensure that a linker list starts on the expected alignment boundary.
>
>For example, if the first list has a struct size of 8 and we place 3 of
>them in the image, that means that the next struct will start at offset
>0x18 from the start of the linker_list section. If the next struct has
>a size of 16 then it will start at an 8-byte aligned offset, but not a
>16-byte aligned offset.
>
>With sandbox on x86_64, a reference to a linker list item using
>ll_entry_get() can force alignment of that particular linker_list item,
>if it is in the same file as the linker_list item is declared.
>
>Consider this example, where struct driver is 0x80 bytes:
>
>	ll_entry_declare(struct driver, fred, driver)
>
>...
>
>	void *p = ll_entry_get(struct driver, fred, driver)
>
>If these two lines of code are in the same file, then the entry is
>forced
>to be aligned at the 'struct driver' alignment, which is 16 bytes. If
>the
>second line of code is in a different file, then no action is taken,
>since
>the compiler cannot update the alignment of the linker_list item.
>
>In the first case, an 8-byte 'fill' region is added:
>
> .u_boot_list_2_driver_2_testbus_drv
>                0x0000000000270018       0x80 test/built-in.o
>                0x0000000000270018
>                	_u_boot_list_2_driver_2_testbus_drv
> .u_boot_list_2_driver_2_testfdt1_drv
>                0x0000000000270098       0x80 test/built-in.o
>                0x0000000000270098
>                	_u_boot_list_2_driver_2_testfdt1_drv
> *fill*         0x0000000000270118        0x8
> .u_boot_list_2_driver_2_testfdt_drv
>                0x0000000000270120       0x80 test/built-in.o
>                0x0000000000270120
>                	_u_boot_list_2_driver_2_testfdt_drv
> .u_boot_list_2_driver_2_testprobe_drv
>                0x00000000002701a0       0x80 test/built-in.o
>                0x00000000002701a0
>                	_u_boot_list_2_driver_2_testprobe_drv
>
>With this, the linker_list no-longer works since items after
>testfdt1_drv
>are not at the expected address.
>
>Ideally we would have a way to tell gcc not to align structs in this
>way.
>It is not clear how we could do this, and in any case it would require
>us
>to adjust every struct used by the linker_list feature.
>
>One possible fix is to force each separate linker_list to start on the
>largest possible boundary that can be required by the compiler. However
>that does not seem to work on x86_64, which uses 16-byte alignment in
>this
>case but needs 32-byte alignment.
>
>So add a Kconfig option to handle this. Set the default value to 4 so
>as to avoid changing platforms that don't need it.
>
>Update the ll_entry_start() accordingly.
>
>Signed-off-by: Simon Glass <sjg@chromium.org>
>---
>
> arch/Kconfig             | 11 +++++++
> doc/api/linker_lists.rst | 62 ++++++++++++++++++++++++++++++++++++++++
> include/linker_lists.h   |  3 +-
> 3 files changed, 75 insertions(+), 1 deletion(-)
>
>diff --git a/arch/Kconfig b/arch/Kconfig
>index 3aa99e08fce..aa8664212f1 100644
>--- a/arch/Kconfig
>+++ b/arch/Kconfig
>@@ -7,6 +7,17 @@ config HAVE_ARCH_IOREMAP
> config NEEDS_MANUAL_RELOC
> 	bool
> 
>+config LINKER_LIST_ALIGN
>+	int
>+	default 32 if SANDBOX

What is so special about the sandbox?
Just evaluate if the host is 64 bit and use 8 or 4 accordingly?

>+	default 8 if ARM64 || X86

Shouldn't the default be 8 on all 64 bit platforms? And 4 on all 32 bit platforms?

Best regards

Heinrich


>+	default 4
>+	help
>+	  Force the each linker list to be aligned to this boundary. This
>+	  is required if ll_entry_get() is used, since otherwise the linker
>+	  may add padding into the table, thus breaking it.
>+	  See linker_lists.rst for full details.
>+
> choice
> 	prompt "Architecture select"
> 	default SANDBOX
>diff --git a/doc/api/linker_lists.rst b/doc/api/linker_lists.rst
>index 72f514e0ac0..7a37db52ba8 100644
>--- a/doc/api/linker_lists.rst
>+++ b/doc/api/linker_lists.rst
>@@ -96,5 +96,67 @@ defined for the whole list and each sub-list:
>   %u_boot_list_2_drivers_2_pci_3
>   %u_boot_list_2_drivers_3
> 
>+Alignment issues
>+----------------
>+
>+The linker script uses alphabetic sorting to group the different
>linker
>+lists together. Each group has its own struct and potentially its own
>+alignment. But when the linker packs the structs together it cannot
>ensure
>+that a linker list starts on the expected alignment boundary.
>+
>+For example, if the first list has a struct size of 8 and we place 3
>of
>+them in the image, that means that the next struct will start at
>offset
>+0x18 from the start of the linker_list section. If the next struct has
>+a size of 16 then it will start at an 8-byte aligned offset, but not a
>+16-byte aligned offset.
>+
>+With sandbox on x86_64, a reference to a linker list item using
>+ll_entry_get() can force alignment of that particular linker_list
>item,
>+if it is in the same file as the linker_list item is declared.
>+
>+Consider this example, where struct driver is 0x80 bytes:
>+
>+::
>+
>+    ll_entry_declare(struct driver, fred, driver)
>+
>+    ...
>+
>+    void *p = ll_entry_get(struct driver, fred, driver)
>+
>+If these two lines of code are in the same file, then the entry is
>forced
>+to be aligned at the 'struct driver' alignment, which is 16 bytes. If
>the
>+second line of code is in a different file, then no action is taken,
>since
>+the compiler cannot update the alignment of the linker_list item.
>+
>+In the first case, an 8-byte 'fill' region is added:
>+
>+::
>+
>+    .u_boot_list_2_driver_2_testbus_drv
>+                0x0000000000270018       0x80 test/built-in.o
>+                0x0000000000270018               
>_u_boot_list_2_driver_2_testbus_drv
>+    .u_boot_list_2_driver_2_testfdt1_drv
>+                0x0000000000270098       0x80 test/built-in.o
>+                0x0000000000270098               
>_u_boot_list_2_driver_2_testfdt1_drv
>+    *fill*         0x0000000000270118        0x8
>+    .u_boot_list_2_driver_2_testfdt_drv
>+                0x0000000000270120       0x80 test/built-in.o
>+                0x0000000000270120               
>_u_boot_list_2_driver_2_testfdt_drv
>+    .u_boot_list_2_driver_2_testprobe_drv
>+                0x00000000002701a0       0x80 test/built-in.o
>+                0x00000000002701a0               
>_u_boot_list_2_driver_2_testprobe_drv
>+
>+With this, the linker_list no-longer works since items after
>testfdt1_drv
>+are not at the expected address.
>+
>+Ideally we would have a way to tell gcc not to align structs in this
>way.
>+It is not clear how we could do this, and in any case it would require
>us
>+to adjust every struct used by the linker_list feature.
>+
>+The simplest fix seems to be to force each separate linker_list to
>start
>+on the largest possible boundary that can be required by the compiler.
>This
>+is the purpose of CONFIG_LINKER_LIST_ALIGN
>+
> .. kernel-doc:: include/linker_lists.h
>    :internal:
>diff --git a/include/linker_lists.h b/include/linker_lists.h
>index d775d041e04..fd98ecd297c 100644
>--- a/include/linker_lists.h
>+++ b/include/linker_lists.h
>@@ -124,7 +124,8 @@
>  */
> #define ll_entry_start(_type, _list)					\
> ({									\
>-	static char start[0] __aligned(4) __attribute__((unused,	\
>+	static char start[0] __aligned(CONFIG_LINKER_LIST_ALIGN)	\
>+		__attribute__((unused,					\
> 		section(".u_boot_list_2_"#_list"_1")));			\
> 	(_type *)&start;						\
> })

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

* [PATCH 01/27] linker_lists: Fix alignment issue
  2020-11-30  6:20   ` Heinrich Schuchardt
@ 2020-11-30 20:11     ` Simon Glass
  2020-11-30 22:56       ` Heinrich Schuchardt
  0 siblings, 1 reply; 50+ messages in thread
From: Simon Glass @ 2020-11-30 20:11 UTC (permalink / raw)
  To: u-boot

+Marek Vasut who originally wrote it

Hi Heinrich,

On Sun, 29 Nov 2020 at 23:20, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>
> Am 30. November 2020 02:53:36 MEZ schrieb Simon Glass <sjg@chromium.org>:
> >The linker script uses alphabetic sorting to group the different linker
> >lists together. Each group has its own struct and potentially its own
> >alignment. But when the linker packs the structs together it cannot
> >ensure that a linker list starts on the expected alignment boundary.
> >
> >For example, if the first list has a struct size of 8 and we place 3 of
> >them in the image, that means that the next struct will start at offset
> >0x18 from the start of the linker_list section. If the next struct has
> >a size of 16 then it will start at an 8-byte aligned offset, but not a
> >16-byte aligned offset.
> >
> >With sandbox on x86_64, a reference to a linker list item using
> >ll_entry_get() can force alignment of that particular linker_list item,
> >if it is in the same file as the linker_list item is declared.
> >
> >Consider this example, where struct driver is 0x80 bytes:
> >
> >       ll_entry_declare(struct driver, fred, driver)
> >
> >...
> >
> >       void *p = ll_entry_get(struct driver, fred, driver)
> >
> >If these two lines of code are in the same file, then the entry is
> >forced
> >to be aligned at the 'struct driver' alignment, which is 16 bytes. If
> >the
> >second line of code is in a different file, then no action is taken,
> >since
> >the compiler cannot update the alignment of the linker_list item.
> >
> >In the first case, an 8-byte 'fill' region is added:
> >
> > .u_boot_list_2_driver_2_testbus_drv
> >                0x0000000000270018       0x80 test/built-in.o
> >                0x0000000000270018
> >                       _u_boot_list_2_driver_2_testbus_drv
> > .u_boot_list_2_driver_2_testfdt1_drv
> >                0x0000000000270098       0x80 test/built-in.o
> >                0x0000000000270098
> >                       _u_boot_list_2_driver_2_testfdt1_drv
> > *fill*         0x0000000000270118        0x8
> > .u_boot_list_2_driver_2_testfdt_drv
> >                0x0000000000270120       0x80 test/built-in.o
> >                0x0000000000270120
> >                       _u_boot_list_2_driver_2_testfdt_drv
> > .u_boot_list_2_driver_2_testprobe_drv
> >                0x00000000002701a0       0x80 test/built-in.o
> >                0x00000000002701a0
> >                       _u_boot_list_2_driver_2_testprobe_drv
> >
> >With this, the linker_list no-longer works since items after
> >testfdt1_drv
> >are not at the expected address.
> >
> >Ideally we would have a way to tell gcc not to align structs in this
> >way.
> >It is not clear how we could do this, and in any case it would require
> >us
> >to adjust every struct used by the linker_list feature.
> >
> >One possible fix is to force each separate linker_list to start on the
> >largest possible boundary that can be required by the compiler. However
> >that does not seem to work on x86_64, which uses 16-byte alignment in
> >this
> >case but needs 32-byte alignment.
> >
> >So add a Kconfig option to handle this. Set the default value to 4 so
> >as to avoid changing platforms that don't need it.
> >
> >Update the ll_entry_start() accordingly.
> >
> >Signed-off-by: Simon Glass <sjg@chromium.org>
> >---
> >
> > arch/Kconfig             | 11 +++++++
> > doc/api/linker_lists.rst | 62 ++++++++++++++++++++++++++++++++++++++++
> > include/linker_lists.h   |  3 +-
> > 3 files changed, 75 insertions(+), 1 deletion(-)
> >
> >diff --git a/arch/Kconfig b/arch/Kconfig
> >index 3aa99e08fce..aa8664212f1 100644
> >--- a/arch/Kconfig
> >+++ b/arch/Kconfig
> >@@ -7,6 +7,17 @@ config HAVE_ARCH_IOREMAP
> > config NEEDS_MANUAL_RELOC
> >       bool
> >
> >+config LINKER_LIST_ALIGN
> >+      int
> >+      default 32 if SANDBOX
>
> What is so special about the sandbox?

I'm not too sure, actually. Also, 32 seems to be larger than
__BIGGEST_ALIGNMENT__ so it is confusing.

> Just evaluate if the host is 64 bit and use 8 or 4 accordingly?
>
> >+      default 8 if ARM64 || X86
>
> Shouldn't the default be 8 on all 64 bit platforms? And 4 on all 32 bit platforms?

Possibly, but who knows? One way to really get to the bottom of this
is to have a test that checks that the alignment is what it should be.
I spent half a day diagnosing this but not that much time thinking of
the best solution. If you have time to dig into it please let me know.

Regards,
Simon

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

* [PATCH 01/27] linker_lists: Fix alignment issue
  2020-11-30 20:11     ` Simon Glass
@ 2020-11-30 22:56       ` Heinrich Schuchardt
  2020-12-01 15:58         ` Simon Glass
  0 siblings, 1 reply; 50+ messages in thread
From: Heinrich Schuchardt @ 2020-11-30 22:56 UTC (permalink / raw)
  To: u-boot

On 11/30/20 9:11 PM, Simon Glass wrote:
> +Marek Vasut who originally wrote it
>
> Hi Heinrich,
>
> On Sun, 29 Nov 2020 at 23:20, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>>
>> Am 30. November 2020 02:53:36 MEZ schrieb Simon Glass <sjg@chromium.org>:
>>> The linker script uses alphabetic sorting to group the different linker
>>> lists together. Each group has its own struct and potentially its own
>>> alignment. But when the linker packs the structs together it cannot
>>> ensure that a linker list starts on the expected alignment boundary.
>>>
>>> For example, if the first list has a struct size of 8 and we place 3 of
>>> them in the image, that means that the next struct will start at offset
>>> 0x18 from the start of the linker_list section. If the next struct has
>>> a size of 16 then it will start at an 8-byte aligned offset, but not a
>>> 16-byte aligned offset.
>>>
>>> With sandbox on x86_64, a reference to a linker list item using
>>> ll_entry_get() can force alignment of that particular linker_list item,
>>> if it is in the same file as the linker_list item is declared.
>>>
>>> Consider this example, where struct driver is 0x80 bytes:
>>>
>>>        ll_entry_declare(struct driver, fred, driver)
>>>
>>> ...
>>>
>>>        void *p = ll_entry_get(struct driver, fred, driver)
>>>
>>> If these two lines of code are in the same file, then the entry is
>>> forced
>>> to be aligned at the 'struct driver' alignment, which is 16 bytes. If
>>> the
>>> second line of code is in a different file, then no action is taken,
>>> since
>>> the compiler cannot update the alignment of the linker_list item.
>>>
>>> In the first case, an 8-byte 'fill' region is added:
>>>
>>> .u_boot_list_2_driver_2_testbus_drv
>>>                 0x0000000000270018       0x80 test/built-in.o
>>>                 0x0000000000270018
>>>                        _u_boot_list_2_driver_2_testbus_drv
>>> .u_boot_list_2_driver_2_testfdt1_drv
>>>                 0x0000000000270098       0x80 test/built-in.o
>>>                 0x0000000000270098
>>>                        _u_boot_list_2_driver_2_testfdt1_drv
>>> *fill*         0x0000000000270118        0x8
>>> .u_boot_list_2_driver_2_testfdt_drv
>>>                 0x0000000000270120       0x80 test/built-in.o
>>>                 0x0000000000270120
>>>                        _u_boot_list_2_driver_2_testfdt_drv
>>> .u_boot_list_2_driver_2_testprobe_drv
>>>                 0x00000000002701a0       0x80 test/built-in.o
>>>                 0x00000000002701a0
>>>                        _u_boot_list_2_driver_2_testprobe_drv
>>>
>>> With this, the linker_list no-longer works since items after
>>> testfdt1_drv
>>> are not at the expected address.
>>>
>>> Ideally we would have a way to tell gcc not to align structs in this
>>> way.
>>> It is not clear how we could do this, and in any case it would require
>>> us
>>> to adjust every struct used by the linker_list feature.
>>>
>>> One possible fix is to force each separate linker_list to start on the
>>> largest possible boundary that can be required by the compiler. However
>>> that does not seem to work on x86_64, which uses 16-byte alignment in
>>> this
>>> case but needs 32-byte alignment.
>>>
>>> So add a Kconfig option to handle this. Set the default value to 4 so
>>> as to avoid changing platforms that don't need it.
>>>
>>> Update the ll_entry_start() accordingly.
>>>
>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>> ---
>>>
>>> arch/Kconfig             | 11 +++++++
>>> doc/api/linker_lists.rst | 62 ++++++++++++++++++++++++++++++++++++++++
>>> include/linker_lists.h   |  3 +-
>>> 3 files changed, 75 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/Kconfig b/arch/Kconfig
>>> index 3aa99e08fce..aa8664212f1 100644
>>> --- a/arch/Kconfig
>>> +++ b/arch/Kconfig
>>> @@ -7,6 +7,17 @@ config HAVE_ARCH_IOREMAP
>>> config NEEDS_MANUAL_RELOC
>>>        bool
>>>
>>> +config LINKER_LIST_ALIGN
>>> +      int
>>> +      default 32 if SANDBOX
>>
>> What is so special about the sandbox?
>
> I'm not too sure, actually. Also, 32 seems to be larger than
> __BIGGEST_ALIGNMENT__ so it is confusing.
>
>> Just evaluate if the host is 64 bit and use 8 or 4 accordingly?
>>
>>> +      default 8 if ARM64 || X86
>>
>> Shouldn't the default be 8 on all 64 bit platforms? And 4 on all 32 bit platforms?
>
> Possibly, but who knows? One way to really get to the bottom of this
> is to have a test that checks that the alignment is what it should be.
> I spent half a day diagnosing this but not that much time thinking of
> the best solution. If you have time to dig into it please let me know.
>
> Regards,
> Simon
>

If you change ll_entry_start() as below, the linker will complain
"lib/efi_driver/efi_uclass.c:309:
undefined reference to `bad_alignment'"

If you change value 4 to 8, it stops complaining for qemu-x86_64_defconfig.

#define ll_alignment(x) \
 ????????(__builtin_offsetof(struct {char a; x b;}, b))
void bad_alignment(void);
#define ll_entry_start(_type, _list) \
({ \
 ????????static char start[0] __aligned(4) __attribute__((unused, \
 ????????????????section(".u_boot_list_2_"#_list"_1"))); \
 ????????if (ll_alignment(_type) > 4) \
 ????????????????bad_alignment(); \
 ????????(_type *)&start; \
})

If the alignment is smaller than the limit, the compiler can remove the
bad_alignment() call due to the optimization setting -Os (or -O2).

For RISC-V 64bit you also need 8 byte alignment.

I suggest that you replace 4 by sizeof(long) and run the change through
Gitlab to validate that 8 bytes on 64-bit systems and 4 bytes on 32-bit
systems are sufficient alignment.

I did not check if any linker lists are accessed via other means then
ll_entry_start().

Best regards

Heinrich

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

* [PATCH 00/27] dm: Change the way sequence numbers are implemented
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (26 preceding siblings ...)
  2020-11-30  1:54 ` [PATCH 27/27] dm: Update documentation for new sequence numbers Simon Glass
@ 2020-12-01  8:01 ` Heinrich Schuchardt
  2020-12-03  2:04   ` Simon Glass
  2020-12-08 22:52 ` Michael Walle
  28 siblings, 1 reply; 50+ messages in thread
From: Heinrich Schuchardt @ 2020-12-01  8:01 UTC (permalink / raw)
  To: u-boot

On 11/30/20 2:53 AM, Simon Glass wrote:
> At present each device has two sequence numbers, with 'req_seq' being
> set up at bind time and 'seq' at probe time. The idea is that devices
> can 'request' a sequence number and then the conflicts are resolved when
> the device is probed.
>
> This makes things complicated in a few cases, since we don't really know
> (at bind time) what the sequence number will end up being. We want to
> honour the bind-time requests if at all possible, but in fact the only
> source of these at present is the devicetree aliases.
>
> Apart from the obvious need for sequence numbers to supports U-Boot's
> numbering on devices on the command line, the current scheme was
> designed to:
>
> - avoid calculating the sequence number until it is needed, to save
>    execution time
> - allow multiple devices to obtain a particular sequence number as they
>    are probed and removed
> - retain a record of the 'requested' sequence number even if it turns out
>    that a device could not get it (to allow debugging and retrying)
>
> After some years using the current scheme it seems on balance that these
> goals don't have as much merit as first thought. The first point would
> be persuasive except that we end up reading the devicetree aliases at
> bind-time anyway. So the work of resolving the sequence numbers during
> probing is not that great. The second point hasn't really been an issue,
> as there is typically no contention for sequence numbers (boards tend to
> allocate them statically in the devicetree). Re the third point, we can
> often figure out what was requested by looking at aliases, and in the
> cases where we can't, it doesn't seem to matter much.
>
> Since we have the devicetree available at bind time, we may as well just
> use it, in the hope that the required processing will turn out to be
> useful later (i.e. the device actually gets used). In addition, it is
> simpler to use a single sequence number, since it avoids confusion and
> some extra code.
>
> This series moves U-Boot to use a single, bind-time sequence number. All
> uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign sequence
> numbers to their devices, so that as soon as a device is bound, it has a
> sequence number. If a devicetree alias provides the number, it will be
> used. Otherwise, during initial binding, the first free number is used.
> For ad-hoc calls to device_bind() afterwards (e.g. from driver code), the
> sequence is set to the maximum sequence number for the uclass + 1.
>
> Apart from the simplicity gains, overall these changes seem to reduce the
> number of tweaks and workarounds needed to get the desired behaviour.
>
> However there will certainly be some problems created, so board
> maintainers should test this out.

What is the effect of the series on removable devices like USB storage,
USB Ethernet, SATA disks, ...?

Is there a test for removable devices?

Best regards

Heinrich

>
>
> Simon Glass (27):
>    linker_lists: Fix alignment issue
>    efi: Drop unwanted message in efi_uc_destroy()
>    dm: Avoid accessing seq directly
>    dm: core: Update uclass_find_next_free_req_seq() args
>    dm: core: Add a new sequence number for devices
>    dm: test: Add support for new sequence numbers
>    dm: core: Switch binding to use new sequence numbers
>    dm: Fix return value in dev_read_alias_seq()
>    dm: test: Drop assumptions of no sequence numbers
>    octeon: Don't attempt to set the sequence number
>    i2c: Update for new sequence numbers
>    net: Update to use new sequence numbers
>    pci: Update to use new sequence numbers
>    spi: Update for new sequence numbers
>    usb: ehci-mx6: Drop assignment of sequence number
>    usb: Update for new sequence numbers
>    x86: Drop unnecessary mp_init logic
>    x86: Simplify acpi_device_infer_name()
>    gpio: Update for new sequence numbers
>    pinctrl: Update for new sequence numbers
>    dm: Switch over to use new sequence number for dev_seq()
>    dm: Drop uclass_resolve_seq()
>    dm: Drop the unused arg in uclass_find_device_by_seq()
>    dm: core: Simplify uclass_find_next_free_req_seq()
>    cmd: Drop use of old sequence numbers in commands
>    dm: core: Drop seq and req_seq
>    dm: Update documentation for new sequence numbers
>
>   arch/Kconfig                             |  11 +++
>   arch/arm/include/asm/mach-imx/mxc_i2c.h  |   2 +-
>   arch/arm/mach-k3/am6_init.c              |   2 +-
>   arch/arm/mach-k3/j721e_init.c            |   2 +-
>   arch/arm/mach-k3/sysfw-loader.c          |   2 +-
>   arch/sandbox/dts/test.dts                |   2 +-
>   arch/x86/cpu/apollolake/cpu.c            |   2 +-
>   arch/x86/cpu/broadwell/cpu_full.c        |   2 +-
>   arch/x86/cpu/ivybridge/model_206ax.c     |   2 +-
>   arch/x86/cpu/mp_init.c                   |  23 ++---
>   arch/x86/include/asm/mp.h                |   2 +-
>   board/xilinx/versal/board.c              |  12 +--
>   board/xilinx/zynqmp/zynqmp.c             |  12 +--
>   cmd/axi.c                                |   6 +-
>   cmd/cpu.c                                |   2 +-
>   cmd/i2c.c                                |   6 +-
>   cmd/misc.c                               |   2 +-
>   cmd/osd.c                                |   6 +-
>   cmd/pci.c                                |   7 +-
>   cmd/pmic.c                               |   4 +-
>   cmd/remoteproc.c                         |   2 +-
>   cmd/w1.c                                 |   4 +-
>   doc/api/linker_lists.rst                 |  62 ++++++++++++
>   doc/driver-model/design.rst              |  58 +++++++-----
>   drivers/core/device-remove.c             |   1 -
>   drivers/core/device.c                    |  52 ++++------
>   drivers/core/dump.c                      |   4 +-
>   drivers/core/read.c                      |   4 +-
>   drivers/core/root.c                      |  21 ++++-
>   drivers/core/uclass.c                    | 115 ++++++++++-------------
>   drivers/gpio/imx_rgpio2p.c               |   2 +-
>   drivers/gpio/iproc_gpio.c                |   2 +-
>   drivers/gpio/mvebu_gpio.c                |   2 +-
>   drivers/gpio/mxc_gpio.c                  |   2 +-
>   drivers/gpio/octeon_gpio.c               |   2 +-
>   drivers/gpio/vybrid_gpio.c               |   2 +-
>   drivers/i2c/ast_i2c.c                    |   4 +-
>   drivers/i2c/davinci_i2c.c                |   2 +-
>   drivers/i2c/designware_i2c_pci.c         |  16 +---
>   drivers/i2c/exynos_hs_i2c.c              |   2 +-
>   drivers/i2c/i2c-gpio.c                   |   2 +-
>   drivers/i2c/i2c-uclass.c                 |   8 +-
>   drivers/i2c/i2c-versatile.c              |   5 -
>   drivers/i2c/imx_lpi2c.c                  |  12 +--
>   drivers/i2c/intel_i2c.c                  |  12 +--
>   drivers/i2c/lpc32xx_i2c.c                |   6 +-
>   drivers/i2c/muxes/i2c-mux-uclass.c       |   4 +-
>   drivers/i2c/mvtwsi.c                     |   4 +-
>   drivers/i2c/mxc_i2c.c                    |  10 +-
>   drivers/i2c/nx_i2c.c                     |   2 +-
>   drivers/i2c/octeon_i2c.c                 |   3 +-
>   drivers/i2c/s3c24x0_i2c.c                |   2 +-
>   drivers/i2c/tegra_i2c.c                  |   5 +-
>   drivers/mmc/fsl_esdhc_imx.c              |   4 +-
>   drivers/mmc/octeontx_hsmmc.c             |   2 -
>   drivers/mtd/spi/sandbox.c                |   4 +-
>   drivers/net/dwc_eth_qos.c                |   2 +-
>   drivers/net/fec_mxc.c                    |   7 +-
>   drivers/net/fsl-mc/mc.c                  |   2 +-
>   drivers/net/fsl_mcdmafec.c               |   2 +-
>   drivers/net/ftgmac100.c                  |   2 +-
>   drivers/net/higmacv300.c                 |   2 +-
>   drivers/net/mcffec.c                     |   2 +-
>   drivers/net/octeontx/nicvf_main.c        |   9 +-
>   drivers/net/octeontx/smi.c               |   3 +-
>   drivers/net/octeontx2/nix.c              |   2 +-
>   drivers/net/octeontx2/rvu_pf.c           |   6 +-
>   drivers/net/xilinx_axi_emac.c            |   2 +-
>   drivers/net/xilinx_emaclite.c            |   2 +-
>   drivers/net/zynq_gem.c                   |   2 +-
>   drivers/pci/pci-aardvark.c               |   2 +-
>   drivers/pci/pci-uclass.c                 |  42 ++++-----
>   drivers/pci/pci_auto.c                   |   6 +-
>   drivers/pci/pcie_dw_mvebu.c              |   6 +-
>   drivers/pci/pcie_dw_ti.c                 |   6 +-
>   drivers/pci/pcie_ecam_generic.c          |   2 +-
>   drivers/pci/pcie_fsl.c                   |  16 ++--
>   drivers/pci/pcie_intel_fpga.c            |   2 +-
>   drivers/pci/pcie_layerscape_fixup.c      |   4 +-
>   drivers/pci/pcie_layerscape_gen4.c       |  10 +-
>   drivers/pci/pcie_layerscape_gen4_fixup.c |   2 +-
>   drivers/pci/pcie_layerscape_rc.c         |  12 +--
>   drivers/pci/pcie_mediatek.c              |   2 +-
>   drivers/pci/pcie_rockchip.c              |   6 +-
>   drivers/pinctrl/exynos/pinctrl-exynos.c  |   2 +-
>   drivers/serial/serial_mcf.c              |   2 +-
>   drivers/serial/serial_s5p.c              |   2 +-
>   drivers/spi/altera_spi.c                 |   2 +-
>   drivers/spi/cf_spi.c                     |  12 +--
>   drivers/spi/fsl_dspi.c                   |   8 +-
>   drivers/spi/fsl_espi.c                   |   2 +-
>   drivers/spi/octeon_spi.c                 |   2 +-
>   drivers/spi/pic32_spi.c                  |   4 +-
>   drivers/spi/rk_spi.c                     |   1 -
>   drivers/spi/sandbox_spi.c                |   2 +-
>   drivers/spi/spi-uclass.c                 |   4 +-
>   drivers/spi/tegra114_spi.c               |   2 +-
>   drivers/spi/tegra20_sflash.c             |   2 +-
>   drivers/spi/tegra20_slink.c              |   2 +-
>   drivers/spi/tegra210_qspi.c              |   2 +-
>   drivers/spi/xilinx_spi.c                 |   2 +-
>   drivers/spi/zynq_qspi.c                  |   2 +-
>   drivers/spi/zynq_spi.c                   |   2 +-
>   drivers/usb/gadget/max3420_udc.c         |   2 +-
>   drivers/usb/host/ehci-mx5.c              |   2 +-
>   drivers/usb/host/ehci-mx6.c              |  14 ++-
>   drivers/usb/host/ehci-omap.c             |   2 +-
>   drivers/usb/host/ehci-vf.c               |   8 +-
>   drivers/usb/host/usb-sandbox.c           |   2 +-
>   drivers/usb/host/usb-uclass.c            |   6 +-
>   drivers/video/vidconsole-uclass.c        |   4 +-
>   drivers/virtio/virtio-uclass.c           |   2 +-
>   drivers/watchdog/ast_wdt.c               |   2 +-
>   drivers/watchdog/at91sam9_wdt.c          |   2 +-
>   drivers/watchdog/cdns_wdt.c              |   2 +-
>   drivers/watchdog/omap_wdt.c              |   2 +-
>   drivers/watchdog/orion_wdt.c             |   2 +-
>   drivers/watchdog/sbsa_gwdt.c             |   2 +-
>   drivers/watchdog/sp805_wdt.c             |   2 +-
>   drivers/watchdog/tangier_wdt.c           |   2 +-
>   drivers/watchdog/xilinx_tb_wdt.c         |   2 +-
>   drivers/watchdog/xilinx_wwdt.c           |   2 +-
>   include/asm-generic/global_data.h        |   2 +
>   include/configs/sandbox.h                |   2 +-
>   include/dm/device.h                      |  32 +++----
>   include/dm/uclass-internal.h             |  34 +++----
>   include/dm/uclass.h                      |  15 +--
>   include/linker_lists.h                   |   3 +-
>   include/pci.h                            |   2 +-
>   include/spi.h                            |   2 +-
>   lib/acpi/acpi_device.c                   |  27 +-----
>   lib/efi_driver/efi_uclass.c              |   1 -
>   lib/efi_loader/efi_device_path.c         |   4 +-
>   net/eth-uclass.c                         |  24 +++--
>   test/dm/acpi.c                           |   6 +-
>   test/dm/blk.c                            |   3 -
>   test/dm/bus.c                            |  15 +--
>   test/dm/core.c                           |  19 ++++
>   test/dm/eth.c                            |  14 +--
>   test/dm/i2c.c                            |   3 -
>   test/dm/spi.c                            |   3 -
>   test/dm/test-fdt.c                       | 100 ++++++++++++--------
>   test/dm/test-main.c                      |   6 ++
>   143 files changed, 583 insertions(+), 569 deletions(-)
>

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

* [PATCH 02/27] efi: Drop unwanted message in efi_uc_destroy()
  2020-11-30  1:53 ` [PATCH 02/27] efi: Drop unwanted message in efi_uc_destroy() Simon Glass
@ 2020-12-01  8:04   ` Heinrich Schuchardt
  0 siblings, 0 replies; 50+ messages in thread
From: Heinrich Schuchardt @ 2020-12-01  8:04 UTC (permalink / raw)
  To: u-boot

On 11/30/20 2:53 AM, Simon Glass wrote:
> This is not very useful and is printed by some tests, causing confusion.
> Drop it.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>   lib/efi_driver/efi_uclass.c | 1 -
>   1 file changed, 1 deletion(-)
>
> diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c
> index 0cf74b0361d..5b8315472e3 100644
> --- a/lib/efi_driver/efi_uclass.c
> +++ b/lib/efi_driver/efi_uclass.c
> @@ -340,7 +340,6 @@ static int efi_uc_init(struct uclass *class)
>    */
>   static int efi_uc_destroy(struct uclass *class)
>   {
> -	printf("Destroying  UCLASS_EFI\n");

log_debug() would be appropriate.

Please, drop this patch. I will change all printf() statements in this
file to log.

Best regards

Heinrich

>   	return 0;
>   }
>
>

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

* [PATCH 01/27] linker_lists: Fix alignment issue
  2020-11-30 22:56       ` Heinrich Schuchardt
@ 2020-12-01 15:58         ` Simon Glass
  2020-12-09 18:22           ` Heinrich Schuchardt
  0 siblings, 1 reply; 50+ messages in thread
From: Simon Glass @ 2020-12-01 15:58 UTC (permalink / raw)
  To: u-boot

Hi Heinrich,

On Mon, 30 Nov 2020 at 15:56, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>
> On 11/30/20 9:11 PM, Simon Glass wrote:
> > +Marek Vasut who originally wrote it
> >
> > Hi Heinrich,
> >
> > On Sun, 29 Nov 2020 at 23:20, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
> >>
> >> Am 30. November 2020 02:53:36 MEZ schrieb Simon Glass <sjg@chromium.org>:
> >>> The linker script uses alphabetic sorting to group the different linker
> >>> lists together. Each group has its own struct and potentially its own
> >>> alignment. But when the linker packs the structs together it cannot
> >>> ensure that a linker list starts on the expected alignment boundary.
> >>>
> >>> For example, if the first list has a struct size of 8 and we place 3 of
> >>> them in the image, that means that the next struct will start at offset
> >>> 0x18 from the start of the linker_list section. If the next struct has
> >>> a size of 16 then it will start at an 8-byte aligned offset, but not a
> >>> 16-byte aligned offset.
> >>>
> >>> With sandbox on x86_64, a reference to a linker list item using
> >>> ll_entry_get() can force alignment of that particular linker_list item,
> >>> if it is in the same file as the linker_list item is declared.
> >>>
> >>> Consider this example, where struct driver is 0x80 bytes:
> >>>
> >>>        ll_entry_declare(struct driver, fred, driver)
> >>>
> >>> ...
> >>>
> >>>        void *p = ll_entry_get(struct driver, fred, driver)
> >>>
> >>> If these two lines of code are in the same file, then the entry is
> >>> forced
> >>> to be aligned at the 'struct driver' alignment, which is 16 bytes. If
> >>> the
> >>> second line of code is in a different file, then no action is taken,
> >>> since
> >>> the compiler cannot update the alignment of the linker_list item.
> >>>
> >>> In the first case, an 8-byte 'fill' region is added:
> >>>
> >>> .u_boot_list_2_driver_2_testbus_drv
> >>>                 0x0000000000270018       0x80 test/built-in.o
> >>>                 0x0000000000270018
> >>>                        _u_boot_list_2_driver_2_testbus_drv
> >>> .u_boot_list_2_driver_2_testfdt1_drv
> >>>                 0x0000000000270098       0x80 test/built-in.o
> >>>                 0x0000000000270098
> >>>                        _u_boot_list_2_driver_2_testfdt1_drv
> >>> *fill*         0x0000000000270118        0x8
> >>> .u_boot_list_2_driver_2_testfdt_drv
> >>>                 0x0000000000270120       0x80 test/built-in.o
> >>>                 0x0000000000270120
> >>>                        _u_boot_list_2_driver_2_testfdt_drv
> >>> .u_boot_list_2_driver_2_testprobe_drv
> >>>                 0x00000000002701a0       0x80 test/built-in.o
> >>>                 0x00000000002701a0
> >>>                        _u_boot_list_2_driver_2_testprobe_drv
> >>>
> >>> With this, the linker_list no-longer works since items after
> >>> testfdt1_drv
> >>> are not at the expected address.
> >>>
> >>> Ideally we would have a way to tell gcc not to align structs in this
> >>> way.
> >>> It is not clear how we could do this, and in any case it would require
> >>> us
> >>> to adjust every struct used by the linker_list feature.
> >>>
> >>> One possible fix is to force each separate linker_list to start on the
> >>> largest possible boundary that can be required by the compiler. However
> >>> that does not seem to work on x86_64, which uses 16-byte alignment in
> >>> this
> >>> case but needs 32-byte alignment.
> >>>
> >>> So add a Kconfig option to handle this. Set the default value to 4 so
> >>> as to avoid changing platforms that don't need it.
> >>>
> >>> Update the ll_entry_start() accordingly.
> >>>
> >>> Signed-off-by: Simon Glass <sjg@chromium.org>
> >>> ---
> >>>
> >>> arch/Kconfig             | 11 +++++++
> >>> doc/api/linker_lists.rst | 62 ++++++++++++++++++++++++++++++++++++++++
> >>> include/linker_lists.h   |  3 +-
> >>> 3 files changed, 75 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/arch/Kconfig b/arch/Kconfig
> >>> index 3aa99e08fce..aa8664212f1 100644
> >>> --- a/arch/Kconfig
> >>> +++ b/arch/Kconfig
> >>> @@ -7,6 +7,17 @@ config HAVE_ARCH_IOREMAP
> >>> config NEEDS_MANUAL_RELOC
> >>>        bool
> >>>
> >>> +config LINKER_LIST_ALIGN
> >>> +      int
> >>> +      default 32 if SANDBOX
> >>
> >> What is so special about the sandbox?
> >
> > I'm not too sure, actually. Also, 32 seems to be larger than
> > __BIGGEST_ALIGNMENT__ so it is confusing.
> >
> >> Just evaluate if the host is 64 bit and use 8 or 4 accordingly?
> >>
> >>> +      default 8 if ARM64 || X86
> >>
> >> Shouldn't the default be 8 on all 64 bit platforms? And 4 on all 32 bit platforms?
> >
> > Possibly, but who knows? One way to really get to the bottom of this
> > is to have a test that checks that the alignment is what it should be.
> > I spent half a day diagnosing this but not that much time thinking of
> > the best solution. If you have time to dig into it please let me know.
> >
> > Regards,
> > Simon
> >
>
> If you change ll_entry_start() as below, the linker will complain
> "lib/efi_driver/efi_uclass.c:309:
> undefined reference to `bad_alignment'"
>
> If you change value 4 to 8, it stops complaining for qemu-x86_64_defconfig.
>
> #define ll_alignment(x) \
>          (__builtin_offsetof(struct {char a; x b;}, b))
> void bad_alignment(void);
> #define ll_entry_start(_type, _list) \
> ({ \
>          static char start[0] __aligned(4) __attribute__((unused, \
>                  section(".u_boot_list_2_"#_list"_1"))); \
>          if (ll_alignment(_type) > 4) \
>                  bad_alignment(); \
>          (_type *)&start; \
> })
>
> If the alignment is smaller than the limit, the compiler can remove the
> bad_alignment() call due to the optimization setting -Os (or -O2).
>
> For RISC-V 64bit you also need 8 byte alignment.
>
> I suggest that you replace 4 by sizeof(long) and run the change through
> Gitlab to validate that 8 bytes on 64-bit systems and 4 bytes on 32-bit
> systems are sufficient alignment.
>
> I did not check if any linker lists are accessed via other means then
> ll_entry_start().

Thanks. You would think that would be enough, but somehow
ll_entry_get() seems to make things worse.

I'm not sure how to do sizeof(long) in Kconfig

I think we need a test, as you say, but it needs to go one step
further from what you have here, I think.

Regards,
Simon

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

* [PATCH 00/27] dm: Change the way sequence numbers are implemented
  2020-12-01  8:01 ` [PATCH 00/27] dm: Change the way sequence numbers are implemented Heinrich Schuchardt
@ 2020-12-03  2:04   ` Simon Glass
  0 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-12-03  2:04 UTC (permalink / raw)
  To: u-boot

Hi Heinrich,

On Tue, 1 Dec 2020 at 01:32, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>
> On 11/30/20 2:53 AM, Simon Glass wrote:
> > At present each device has two sequence numbers, with 'req_seq' being
> > set up at bind time and 'seq' at probe time. The idea is that devices
> > can 'request' a sequence number and then the conflicts are resolved when
> > the device is probed.
> >
> > This makes things complicated in a few cases, since we don't really know
> > (at bind time) what the sequence number will end up being. We want to
> > honour the bind-time requests if at all possible, but in fact the only
> > source of these at present is the devicetree aliases.
> >
> > Apart from the obvious need for sequence numbers to supports U-Boot's
> > numbering on devices on the command line, the current scheme was
> > designed to:
> >
> > - avoid calculating the sequence number until it is needed, to save
> >    execution time
> > - allow multiple devices to obtain a particular sequence number as they
> >    are probed and removed
> > - retain a record of the 'requested' sequence number even if it turns out
> >    that a device could not get it (to allow debugging and retrying)
> >
> > After some years using the current scheme it seems on balance that these
> > goals don't have as much merit as first thought. The first point would
> > be persuasive except that we end up reading the devicetree aliases at
> > bind-time anyway. So the work of resolving the sequence numbers during
> > probing is not that great. The second point hasn't really been an issue,
> > as there is typically no contention for sequence numbers (boards tend to
> > allocate them statically in the devicetree). Re the third point, we can
> > often figure out what was requested by looking at aliases, and in the
> > cases where we can't, it doesn't seem to matter much.
> >
> > Since we have the devicetree available at bind time, we may as well just
> > use it, in the hope that the required processing will turn out to be
> > useful later (i.e. the device actually gets used). In addition, it is
> > simpler to use a single sequence number, since it avoids confusion and
> > some extra code.
> >
> > This series moves U-Boot to use a single, bind-time sequence number. All
> > uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign sequence
> > numbers to their devices, so that as soon as a device is bound, it has a
> > sequence number. If a devicetree alias provides the number, it will be
> > used. Otherwise, during initial binding, the first free number is used.
> > For ad-hoc calls to device_bind() afterwards (e.g. from driver code), the
> > sequence is set to the maximum sequence number for the uclass + 1.
> >
> > Apart from the simplicity gains, overall these changes seem to reduce the
> > number of tweaks and workarounds needed to get the desired behaviour.
> >
> > However there will certainly be some problems created, so board
> > maintainers should test this out.
>
> What is the effect of the series on removable devices like USB storage,
> USB Ethernet, SATA disks, ...?

They should work as now, in that they get the maximum seq + 1.

>
> Is there a test for removable devices?

The test I added in this series covers the case of devices being bound
ad-hoc, so yes I think so.

Regards,
Simon

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

* [PATCH 00/27] dm: Change the way sequence numbers are implemented
  2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
                   ` (27 preceding siblings ...)
  2020-12-01  8:01 ` [PATCH 00/27] dm: Change the way sequence numbers are implemented Heinrich Schuchardt
@ 2020-12-08 22:52 ` Michael Walle
  2020-12-09 16:19   ` Tom Rini
  2020-12-09 16:23   ` Simon Glass
  28 siblings, 2 replies; 50+ messages in thread
From: Michael Walle @ 2020-12-08 22:52 UTC (permalink / raw)
  To: u-boot

Hi Simon,

Am 2020-11-30 02:53, schrieb Simon Glass:
> At present each device has two sequence numbers, with 'req_seq' being
> set up at bind time and 'seq' at probe time. The idea is that devices
> can 'request' a sequence number and then the conflicts are resolved 
> when
> the device is probed.
> 
> This makes things complicated in a few cases, since we don't really 
> know
> (at bind time) what the sequence number will end up being. We want to
> honour the bind-time requests if at all possible, but in fact the only
> source of these at present is the devicetree aliases.
> 
> Apart from the obvious need for sequence numbers to supports U-Boot's
> numbering on devices on the command line, the current scheme was
> designed to:
> 
> - avoid calculating the sequence number until it is needed, to save
>   execution time
> - allow multiple devices to obtain a particular sequence number as they
>   are probed and removed
> - retain a record of the 'requested' sequence number even if it turns 
> out
>   that a device could not get it (to allow debugging and retrying)
> 
> After some years using the current scheme it seems on balance that 
> these
> goals don't have as much merit as first thought. The first point would
> be persuasive except that we end up reading the devicetree aliases at
> bind-time anyway. So the work of resolving the sequence numbers during
> probing is not that great. The second point hasn't really been an 
> issue,
> as there is typically no contention for sequence numbers (boards tend 
> to
> allocate them statically in the devicetree). Re the third point, we can
> often figure out what was requested by looking at aliases, and in the
> cases where we can't, it doesn't seem to matter much.
> 
> Since we have the devicetree available at bind time, we may as well 
> just
> use it, in the hope that the required processing will turn out to be
> useful later (i.e. the device actually gets used). In addition, it is
> simpler to use a single sequence number, since it avoids confusion and
> some extra code.
> 
> This series moves U-Boot to use a single, bind-time sequence number. 
> All
> uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign 
> sequence
> numbers to their devices, so that as soon as a device is bound, it has 
> a
> sequence number. If a devicetree alias provides the number, it will be
> used. Otherwise, during initial binding, the first free number is used.

What does "first free number mean"?

I have a device tree with the following aliases for network:

aliases {
         ethernet0 = &enetc0;
         ethernet1 = &enetc1;
         ethernet2 = &enetc2;
         ethernet3 = &enetc6;
};

The individual devices might be disabled, depending on the board variant
(which might also be dynamically determined during startup).

My first smoke test with this series show the following:

   uclass 32: eth
   0   * enetc-0 @ ffd40e60, seq 0
   1   * ax88179_eth @ ffd51f50, seq 1

Looks like the usb ethernet device will get seq 1 assigned (after "usb
start"). Is this intended?

If so, this is a problem, because for ethernet devices, the MAC address
is assigned according to the ethNaddr variable. And at least for this
board (kontron_sl28) the first four are reserved for the ones with the
alias entries. Thus I'd have expected that the usb device will get seq 4
assigned.

> For ad-hoc calls to device_bind() afterwards (e.g. from driver code), 
> the
> sequence is set to the maximum sequence number for the uclass + 1.
> 
> Apart from the simplicity gains, overall these changes seem to reduce 
> the
> number of tweaks and workarounds needed to get the desired behaviour.
> 
> However there will certainly be some problems created, so board
> maintainers should test this out.

-michael

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

* [PATCH 00/27] dm: Change the way sequence numbers are implemented
  2020-12-08 22:52 ` Michael Walle
@ 2020-12-09 16:19   ` Tom Rini
  2020-12-09 16:24     ` Simon Glass
  2020-12-09 16:23   ` Simon Glass
  1 sibling, 1 reply; 50+ messages in thread
From: Tom Rini @ 2020-12-09 16:19 UTC (permalink / raw)
  To: u-boot

On Tue, Dec 08, 2020 at 11:52:07PM +0100, Michael Walle wrote:
> Hi Simon,
> 
> Am 2020-11-30 02:53, schrieb Simon Glass:
> > At present each device has two sequence numbers, with 'req_seq' being
> > set up at bind time and 'seq' at probe time. The idea is that devices
> > can 'request' a sequence number and then the conflicts are resolved when
> > the device is probed.
> > 
> > This makes things complicated in a few cases, since we don't really know
> > (at bind time) what the sequence number will end up being. We want to
> > honour the bind-time requests if at all possible, but in fact the only
> > source of these at present is the devicetree aliases.
> > 
> > Apart from the obvious need for sequence numbers to supports U-Boot's
> > numbering on devices on the command line, the current scheme was
> > designed to:
> > 
> > - avoid calculating the sequence number until it is needed, to save
> >   execution time
> > - allow multiple devices to obtain a particular sequence number as they
> >   are probed and removed
> > - retain a record of the 'requested' sequence number even if it turns
> > out
> >   that a device could not get it (to allow debugging and retrying)
> > 
> > After some years using the current scheme it seems on balance that these
> > goals don't have as much merit as first thought. The first point would
> > be persuasive except that we end up reading the devicetree aliases at
> > bind-time anyway. So the work of resolving the sequence numbers during
> > probing is not that great. The second point hasn't really been an issue,
> > as there is typically no contention for sequence numbers (boards tend to
> > allocate them statically in the devicetree). Re the third point, we can
> > often figure out what was requested by looking at aliases, and in the
> > cases where we can't, it doesn't seem to matter much.
> > 
> > Since we have the devicetree available at bind time, we may as well just
> > use it, in the hope that the required processing will turn out to be
> > useful later (i.e. the device actually gets used). In addition, it is
> > simpler to use a single sequence number, since it avoids confusion and
> > some extra code.
> > 
> > This series moves U-Boot to use a single, bind-time sequence number. All
> > uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign sequence
> > numbers to their devices, so that as soon as a device is bound, it has a
> > sequence number. If a devicetree alias provides the number, it will be
> > used. Otherwise, during initial binding, the first free number is used.
> 
> What does "first free number mean"?
> 
> I have a device tree with the following aliases for network:
> 
> aliases {
>         ethernet0 = &enetc0;
>         ethernet1 = &enetc1;
>         ethernet2 = &enetc2;
>         ethernet3 = &enetc6;
> };
> 
> The individual devices might be disabled, depending on the board variant
> (which might also be dynamically determined during startup).
> 
> My first smoke test with this series show the following:
> 
>   uclass 32: eth
>   0   * enetc-0 @ ffd40e60, seq 0
>   1   * ax88179_eth @ ffd51f50, seq 1
> 
> Looks like the usb ethernet device will get seq 1 assigned (after "usb
> start"). Is this intended?
> 
> If so, this is a problem, because for ethernet devices, the MAC address
> is assigned according to the ethNaddr variable. And at least for this
> board (kontron_sl28) the first four are reserved for the ones with the
> alias entries. Thus I'd have expected that the usb device will get seq 4
> assigned.

I want to echo this concern.  One of the things that can be challenging
when working with devices in Linux is that it's now long accepted that
you can't rely on anything like probe order as that can and will change
randomly (seemingly).  You have to instead rely on some stable attribute
of the device.  Consistency of device numbering is a feature for us.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20201209/f70e7db7/attachment.sig>

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

* [PATCH 00/27] dm: Change the way sequence numbers are implemented
  2020-12-08 22:52 ` Michael Walle
  2020-12-09 16:19   ` Tom Rini
@ 2020-12-09 16:23   ` Simon Glass
  2020-12-09 16:30     ` Michael Walle
  1 sibling, 1 reply; 50+ messages in thread
From: Simon Glass @ 2020-12-09 16:23 UTC (permalink / raw)
  To: u-boot

Hi Michael,

On Tue, 8 Dec 2020 at 15:52, Michael Walle <michael@walle.cc> wrote:
>
> Hi Simon,
>
> Am 2020-11-30 02:53, schrieb Simon Glass:
> > At present each device has two sequence numbers, with 'req_seq' being
> > set up at bind time and 'seq' at probe time. The idea is that devices
> > can 'request' a sequence number and then the conflicts are resolved
> > when
> > the device is probed.
> >
> > This makes things complicated in a few cases, since we don't really
> > know
> > (at bind time) what the sequence number will end up being. We want to
> > honour the bind-time requests if at all possible, but in fact the only
> > source of these at present is the devicetree aliases.
> >
> > Apart from the obvious need for sequence numbers to supports U-Boot's
> > numbering on devices on the command line, the current scheme was
> > designed to:
> >
> > - avoid calculating the sequence number until it is needed, to save
> >   execution time
> > - allow multiple devices to obtain a particular sequence number as they
> >   are probed and removed
> > - retain a record of the 'requested' sequence number even if it turns
> > out
> >   that a device could not get it (to allow debugging and retrying)
> >
> > After some years using the current scheme it seems on balance that
> > these
> > goals don't have as much merit as first thought. The first point would
> > be persuasive except that we end up reading the devicetree aliases at
> > bind-time anyway. So the work of resolving the sequence numbers during
> > probing is not that great. The second point hasn't really been an
> > issue,
> > as there is typically no contention for sequence numbers (boards tend
> > to
> > allocate them statically in the devicetree). Re the third point, we can
> > often figure out what was requested by looking at aliases, and in the
> > cases where we can't, it doesn't seem to matter much.
> >
> > Since we have the devicetree available at bind time, we may as well
> > just
> > use it, in the hope that the required processing will turn out to be
> > useful later (i.e. the device actually gets used). In addition, it is
> > simpler to use a single sequence number, since it avoids confusion and
> > some extra code.
> >
> > This series moves U-Boot to use a single, bind-time sequence number.
> > All
> > uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign
> > sequence
> > numbers to their devices, so that as soon as a device is bound, it has
> > a
> > sequence number. If a devicetree alias provides the number, it will be
> > used. Otherwise, during initial binding, the first free number is used.
>
> What does "first free number mean"?
>
> I have a device tree with the following aliases for network:
>
> aliases {
>          ethernet0 = &enetc0;
>          ethernet1 = &enetc1;
>          ethernet2 = &enetc2;
>          ethernet3 = &enetc6;
> };
>
> The individual devices might be disabled, depending on the board variant
> (which might also be dynamically determined during startup).

By disabled, do you mean that they are marked 'status = "disabled"'?
If so, then they are ignored by DM and will not claim their number.

>
> My first smoke test with this series show the following:
>
>    uclass 32: eth
>    0   * enetc-0 @ ffd40e60, seq 0
>    1   * ax88179_eth @ ffd51f50, seq 1
>
> Looks like the usb ethernet device will get seq 1 assigned (after "usb
> start"). Is this intended?
>
> If so, this is a problem, because for ethernet devices, the MAC address
> is assigned according to the ethNaddr variable. And at least for this
> board (kontron_sl28) the first four are reserved for the ones with the
> alias entries. Thus I'd have expected that the usb device will get seq 4
> assigned.

OK, so you mean after all existing aliases, even if they did not bind.
I think we can do that.

Regards,
Simon

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

* [PATCH 00/27] dm: Change the way sequence numbers are implemented
  2020-12-09 16:19   ` Tom Rini
@ 2020-12-09 16:24     ` Simon Glass
  0 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-12-09 16:24 UTC (permalink / raw)
  To: u-boot

Hi Tom,

On Wed, 9 Dec 2020 at 09:19, Tom Rini <trini@konsulko.com> wrote:
>
> On Tue, Dec 08, 2020 at 11:52:07PM +0100, Michael Walle wrote:
> > Hi Simon,
> >
> > Am 2020-11-30 02:53, schrieb Simon Glass:
> > > At present each device has two sequence numbers, with 'req_seq' being
> > > set up at bind time and 'seq' at probe time. The idea is that devices
> > > can 'request' a sequence number and then the conflicts are resolved when
> > > the device is probed.
> > >
> > > This makes things complicated in a few cases, since we don't really know
> > > (at bind time) what the sequence number will end up being. We want to
> > > honour the bind-time requests if at all possible, but in fact the only
> > > source of these at present is the devicetree aliases.
> > >
> > > Apart from the obvious need for sequence numbers to supports U-Boot's
> > > numbering on devices on the command line, the current scheme was
> > > designed to:
> > >
> > > - avoid calculating the sequence number until it is needed, to save
> > >   execution time
> > > - allow multiple devices to obtain a particular sequence number as they
> > >   are probed and removed
> > > - retain a record of the 'requested' sequence number even if it turns
> > > out
> > >   that a device could not get it (to allow debugging and retrying)
> > >
> > > After some years using the current scheme it seems on balance that these
> > > goals don't have as much merit as first thought. The first point would
> > > be persuasive except that we end up reading the devicetree aliases at
> > > bind-time anyway. So the work of resolving the sequence numbers during
> > > probing is not that great. The second point hasn't really been an issue,
> > > as there is typically no contention for sequence numbers (boards tend to
> > > allocate them statically in the devicetree). Re the third point, we can
> > > often figure out what was requested by looking at aliases, and in the
> > > cases where we can't, it doesn't seem to matter much.
> > >
> > > Since we have the devicetree available at bind time, we may as well just
> > > use it, in the hope that the required processing will turn out to be
> > > useful later (i.e. the device actually gets used). In addition, it is
> > > simpler to use a single sequence number, since it avoids confusion and
> > > some extra code.
> > >
> > > This series moves U-Boot to use a single, bind-time sequence number. All
> > > uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign sequence
> > > numbers to their devices, so that as soon as a device is bound, it has a
> > > sequence number. If a devicetree alias provides the number, it will be
> > > used. Otherwise, during initial binding, the first free number is used.
> >
> > What does "first free number mean"?
> >
> > I have a device tree with the following aliases for network:
> >
> > aliases {
> >         ethernet0 = &enetc0;
> >         ethernet1 = &enetc1;
> >         ethernet2 = &enetc2;
> >         ethernet3 = &enetc6;
> > };
> >
> > The individual devices might be disabled, depending on the board variant
> > (which might also be dynamically determined during startup).
> >
> > My first smoke test with this series show the following:
> >
> >   uclass 32: eth
> >   0   * enetc-0 @ ffd40e60, seq 0
> >   1   * ax88179_eth @ ffd51f50, seq 1
> >
> > Looks like the usb ethernet device will get seq 1 assigned (after "usb
> > start"). Is this intended?
> >
> > If so, this is a problem, because for ethernet devices, the MAC address
> > is assigned according to the ethNaddr variable. And at least for this
> > board (kontron_sl28) the first four are reserved for the ones with the
> > alias entries. Thus I'd have expected that the usb device will get seq 4
> > assigned.
>
> I want to echo this concern.  One of the things that can be challenging
> when working with devices in Linux is that it's now long accepted that
> you can't rely on anything like probe order as that can and will change
> randomly (seemingly).  You have to instead rely on some stable attribute
> of the device.  Consistency of device numbering is a feature for us.

This is still using aliases for devices that have them. But for
dynamically allocated devices (without aliases) we always rely on what
is next available. I think I can change the algorithm to look for the
number after all existing aliases.

Regards,
Simon

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

* [PATCH 00/27] dm: Change the way sequence numbers are implemented
  2020-12-09 16:23   ` Simon Glass
@ 2020-12-09 16:30     ` Michael Walle
  2020-12-10  7:34       ` Michal Simek
  0 siblings, 1 reply; 50+ messages in thread
From: Michael Walle @ 2020-12-09 16:30 UTC (permalink / raw)
  To: u-boot

Hi Simon,

Am 2020-12-09 17:23, schrieb Simon Glass:
> On Tue, 8 Dec 2020 at 15:52, Michael Walle <michael@walle.cc> wrote:
>> Am 2020-11-30 02:53, schrieb Simon Glass:
>> > At present each device has two sequence numbers, with 'req_seq' being
>> > set up at bind time and 'seq' at probe time. The idea is that devices
>> > can 'request' a sequence number and then the conflicts are resolved
>> > when
>> > the device is probed.
>> >
>> > This makes things complicated in a few cases, since we don't really
>> > know
>> > (at bind time) what the sequence number will end up being. We want to
>> > honour the bind-time requests if at all possible, but in fact the only
>> > source of these at present is the devicetree aliases.
>> >
>> > Apart from the obvious need for sequence numbers to supports U-Boot's
>> > numbering on devices on the command line, the current scheme was
>> > designed to:
>> >
>> > - avoid calculating the sequence number until it is needed, to save
>> >   execution time
>> > - allow multiple devices to obtain a particular sequence number as they
>> >   are probed and removed
>> > - retain a record of the 'requested' sequence number even if it turns
>> > out
>> >   that a device could not get it (to allow debugging and retrying)
>> >
>> > After some years using the current scheme it seems on balance that
>> > these
>> > goals don't have as much merit as first thought. The first point would
>> > be persuasive except that we end up reading the devicetree aliases at
>> > bind-time anyway. So the work of resolving the sequence numbers during
>> > probing is not that great. The second point hasn't really been an
>> > issue,
>> > as there is typically no contention for sequence numbers (boards tend
>> > to
>> > allocate them statically in the devicetree). Re the third point, we can
>> > often figure out what was requested by looking at aliases, and in the
>> > cases where we can't, it doesn't seem to matter much.
>> >
>> > Since we have the devicetree available at bind time, we may as well
>> > just
>> > use it, in the hope that the required processing will turn out to be
>> > useful later (i.e. the device actually gets used). In addition, it is
>> > simpler to use a single sequence number, since it avoids confusion and
>> > some extra code.
>> >
>> > This series moves U-Boot to use a single, bind-time sequence number.
>> > All
>> > uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign
>> > sequence
>> > numbers to their devices, so that as soon as a device is bound, it has
>> > a
>> > sequence number. If a devicetree alias provides the number, it will be
>> > used. Otherwise, during initial binding, the first free number is used.
>> 
>> What does "first free number mean"?
>> 
>> I have a device tree with the following aliases for network:
>> 
>> aliases {
>>          ethernet0 = &enetc0;
>>          ethernet1 = &enetc1;
>>          ethernet2 = &enetc2;
>>          ethernet3 = &enetc6;
>> };
>> 
>> The individual devices might be disabled, depending on the board 
>> variant
>> (which might also be dynamically determined during startup).
> 
> By disabled, do you mean that they are marked 'status = "disabled"'?

yes

> If so, then they are ignored by DM and will not claim their number.
> 
>> 
>> My first smoke test with this series show the following:
>> 
>>    uclass 32: eth
>>    0   * enetc-0 @ ffd40e60, seq 0
>>    1   * ax88179_eth @ ffd51f50, seq 1
>> 
>> Looks like the usb ethernet device will get seq 1 assigned (after "usb
>> start"). Is this intended?
>> 
>> If so, this is a problem, because for ethernet devices, the MAC 
>> address
>> is assigned according to the ethNaddr variable. And at least for this
>> board (kontron_sl28) the first four are reserved for the ones with the
>> alias entries. Thus I'd have expected that the usb device will get seq 
>> 4
>> assigned.
> 
> OK, so you mean after all existing aliases, even if they did not bind.
> I think we can do that.

Great, that will also match the current behavior. See
be1a6e94254af205bd67d69e3bdb26b161ccd72f ("dm: uclass: don't assign 
aliased seq numbers")

-michael

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

* [PATCH 01/27] linker_lists: Fix alignment issue
  2020-12-01 15:58         ` Simon Glass
@ 2020-12-09 18:22           ` Heinrich Schuchardt
  2020-12-10 19:26             ` Simon Glass
  0 siblings, 1 reply; 50+ messages in thread
From: Heinrich Schuchardt @ 2020-12-09 18:22 UTC (permalink / raw)
  To: u-boot

On 12/1/20 4:58 PM, Simon Glass wrote:
> Hi Heinrich,
>
> On Mon, 30 Nov 2020 at 15:56, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>>
>> On 11/30/20 9:11 PM, Simon Glass wrote:
>>> +Marek Vasut who originally wrote it
>>>
>>> Hi Heinrich,
>>>
>>> On Sun, 29 Nov 2020 at 23:20, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>>>>
>>>> Am 30. November 2020 02:53:36 MEZ schrieb Simon Glass <sjg@chromium.org>:
>>>>> The linker script uses alphabetic sorting to group the different linker
>>>>> lists together. Each group has its own struct and potentially its own
>>>>> alignment. But when the linker packs the structs together it cannot
>>>>> ensure that a linker list starts on the expected alignment boundary.
>>>>>
>>>>> For example, if the first list has a struct size of 8 and we place 3 of
>>>>> them in the image, that means that the next struct will start at offset
>>>>> 0x18 from the start of the linker_list section. If the next struct has
>>>>> a size of 16 then it will start at an 8-byte aligned offset, but not a
>>>>> 16-byte aligned offset.
>>>>>
>>>>> With sandbox on x86_64, a reference to a linker list item using
>>>>> ll_entry_get() can force alignment of that particular linker_list item,
>>>>> if it is in the same file as the linker_list item is declared.
>>>>>
>>>>> Consider this example, where struct driver is 0x80 bytes:
>>>>>
>>>>>         ll_entry_declare(struct driver, fred, driver)
>>>>>
>>>>> ...
>>>>>
>>>>>         void *p = ll_entry_get(struct driver, fred, driver)
>>>>>
>>>>> If these two lines of code are in the same file, then the entry is
>>>>> forced
>>>>> to be aligned at the 'struct driver' alignment, which is 16 bytes. If
>>>>> the
>>>>> second line of code is in a different file, then no action is taken,
>>>>> since
>>>>> the compiler cannot update the alignment of the linker_list item.
>>>>>
>>>>> In the first case, an 8-byte 'fill' region is added:
>>>>>
>>>>> .u_boot_list_2_driver_2_testbus_drv
>>>>>                  0x0000000000270018       0x80 test/built-in.o
>>>>>                  0x0000000000270018
>>>>>                         _u_boot_list_2_driver_2_testbus_drv
>>>>> .u_boot_list_2_driver_2_testfdt1_drv
>>>>>                  0x0000000000270098       0x80 test/built-in.o
>>>>>                  0x0000000000270098
>>>>>                         _u_boot_list_2_driver_2_testfdt1_drv
>>>>> *fill*         0x0000000000270118        0x8
>>>>> .u_boot_list_2_driver_2_testfdt_drv
>>>>>                  0x0000000000270120       0x80 test/built-in.o
>>>>>                  0x0000000000270120
>>>>>                         _u_boot_list_2_driver_2_testfdt_drv
>>>>> .u_boot_list_2_driver_2_testprobe_drv
>>>>>                  0x00000000002701a0       0x80 test/built-in.o
>>>>>                  0x00000000002701a0
>>>>>                         _u_boot_list_2_driver_2_testprobe_drv
>>>>>
>>>>> With this, the linker_list no-longer works since items after
>>>>> testfdt1_drv
>>>>> are not at the expected address.
>>>>>
>>>>> Ideally we would have a way to tell gcc not to align structs in this
>>>>> way.
>>>>> It is not clear how we could do this, and in any case it would require
>>>>> us
>>>>> to adjust every struct used by the linker_list feature.
>>>>>
>>>>> One possible fix is to force each separate linker_list to start on the
>>>>> largest possible boundary that can be required by the compiler. However
>>>>> that does not seem to work on x86_64, which uses 16-byte alignment in
>>>>> this
>>>>> case but needs 32-byte alignment.
>>>>>
>>>>> So add a Kconfig option to handle this. Set the default value to 4 so
>>>>> as to avoid changing platforms that don't need it.
>>>>>
>>>>> Update the ll_entry_start() accordingly.
>>>>>
>>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>>> ---
>>>>>
>>>>> arch/Kconfig             | 11 +++++++
>>>>> doc/api/linker_lists.rst | 62 ++++++++++++++++++++++++++++++++++++++++
>>>>> include/linker_lists.h   |  3 +-
>>>>> 3 files changed, 75 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/arch/Kconfig b/arch/Kconfig
>>>>> index 3aa99e08fce..aa8664212f1 100644
>>>>> --- a/arch/Kconfig
>>>>> +++ b/arch/Kconfig
>>>>> @@ -7,6 +7,17 @@ config HAVE_ARCH_IOREMAP
>>>>> config NEEDS_MANUAL_RELOC
>>>>>         bool
>>>>>
>>>>> +config LINKER_LIST_ALIGN
>>>>> +      int
>>>>> +      default 32 if SANDBOX
>>>>
>>>> What is so special about the sandbox?
>>>
>>> I'm not too sure, actually. Also, 32 seems to be larger than
>>> __BIGGEST_ALIGNMENT__ so it is confusing.
>>>
>>>> Just evaluate if the host is 64 bit and use 8 or 4 accordingly?
>>>>
>>>>> +      default 8 if ARM64 || X86
>>>>
>>>> Shouldn't the default be 8 on all 64 bit platforms? And 4 on all 32 bit platforms?
>>>
>>> Possibly, but who knows? One way to really get to the bottom of this
>>> is to have a test that checks that the alignment is what it should be.
>>> I spent half a day diagnosing this but not that much time thinking of
>>> the best solution. If you have time to dig into it please let me know.
>>>
>>> Regards,
>>> Simon
>>>
>>
>> If you change ll_entry_start() as below, the linker will complain
>> "lib/efi_driver/efi_uclass.c:309:
>> undefined reference to `bad_alignment'"
>>
>> If you change value 4 to 8, it stops complaining for qemu-x86_64_defconfig.
>>
>> #define ll_alignment(x) \
>>           (__builtin_offsetof(struct {char a; x b;}, b))
>> void bad_alignment(void);
>> #define ll_entry_start(_type, _list) \
>> ({ \
>>           static char start[0] __aligned(4) __attribute__((unused, \
>>                   section(".u_boot_list_2_"#_list"_1"))); \
>>           if (ll_alignment(_type) > 4) \
>>                   bad_alignment(); \
>>           (_type *)&start; \
>> })
>>
>> If the alignment is smaller than the limit, the compiler can remove the
>> bad_alignment() call due to the optimization setting -Os (or -O2).
>>
>> For RISC-V 64bit you also need 8 byte alignment.
>>
>> I suggest that you replace 4 by sizeof(long) and run the change through
>> Gitlab to validate that 8 bytes on 64-bit systems and 4 bytes on 32-bit
>> systems are sufficient alignment.
>>
>> I did not check if any linker lists are accessed via other means then
>> ll_entry_start().
>
> Thanks. You would think that would be enough, but somehow
> ll_entry_get() seems to make things worse.
>
> I'm not sure how to do sizeof(long) in Kconfig

Linux defines a symbol 64BIT in arch/ for all architectures, e.g.

arch/x86/Kconfig:3:config 64BIT
arch/x86/Kconfig-4-     bool "64-bit kernel" if "$(ARCH)" = "x86"
arch/x86/Kconfig-5-     default "$(ARCH)" != "i386"

U-Boot has it only for two architectures:

arch/mips/Kconfig:501:config 64BIT
arch/riscv/Kconfig:152:config 64BIT

Best regards

Heinrich

>
> I think we need a test, as you say, but it needs to go one step
> further from what you have here, I think.
>
> Regards,
> Simon
>

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

* [PATCH 00/27] dm: Change the way sequence numbers are implemented
  2020-12-09 16:30     ` Michael Walle
@ 2020-12-10  7:34       ` Michal Simek
  2020-12-10 17:27         ` Simon Glass
  0 siblings, 1 reply; 50+ messages in thread
From: Michal Simek @ 2020-12-10  7:34 UTC (permalink / raw)
  To: u-boot

Hi,

On 09. 12. 20 17:30, Michael Walle wrote:
> Hi Simon,
> 
> Am 2020-12-09 17:23, schrieb Simon Glass:
>> On Tue, 8 Dec 2020 at 15:52, Michael Walle <michael@walle.cc> wrote:
>>> Am 2020-11-30 02:53, schrieb Simon Glass:
>>> > At present each device has two sequence numbers, with 'req_seq' being
>>> > set up at bind time and 'seq' at probe time. The idea is that devices
>>> > can 'request' a sequence number and then the conflicts are resolved
>>> > when
>>> > the device is probed.
>>> >
>>> > This makes things complicated in a few cases, since we don't really
>>> > know
>>> > (at bind time) what the sequence number will end up being. We want to
>>> > honour the bind-time requests if at all possible, but in fact the only
>>> > source of these at present is the devicetree aliases.
>>> >
>>> > Apart from the obvious need for sequence numbers to supports U-Boot's
>>> > numbering on devices on the command line, the current scheme was
>>> > designed to:
>>> >
>>> > - avoid calculating the sequence number until it is needed, to save
>>> >?? execution time
>>> > - allow multiple devices to obtain a particular sequence number as
>>> they
>>> >?? are probed and removed
>>> > - retain a record of the 'requested' sequence number even if it turns
>>> > out
>>> >?? that a device could not get it (to allow debugging and retrying)
>>> >
>>> > After some years using the current scheme it seems on balance that
>>> > these
>>> > goals don't have as much merit as first thought. The first point would
>>> > be persuasive except that we end up reading the devicetree aliases at
>>> > bind-time anyway. So the work of resolving the sequence numbers during
>>> > probing is not that great. The second point hasn't really been an
>>> > issue,
>>> > as there is typically no contention for sequence numbers (boards tend
>>> > to
>>> > allocate them statically in the devicetree). Re the third point, we
>>> can
>>> > often figure out what was requested by looking at aliases, and in the
>>> > cases where we can't, it doesn't seem to matter much.
>>> >
>>> > Since we have the devicetree available at bind time, we may as well
>>> > just
>>> > use it, in the hope that the required processing will turn out to be
>>> > useful later (i.e. the device actually gets used). In addition, it is
>>> > simpler to use a single sequence number, since it avoids confusion and
>>> > some extra code.
>>> >
>>> > This series moves U-Boot to use a single, bind-time sequence number.
>>> > All
>>> > uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign
>>> > sequence
>>> > numbers to their devices, so that as soon as a device is bound, it has
>>> > a
>>> > sequence number. If a devicetree alias provides the number, it will be
>>> > used. Otherwise, during initial binding, the first free number is
>>> used.
>>>
>>> What does "first free number mean"?
>>>
>>> I have a device tree with the following aliases for network:
>>>
>>> aliases {
>>> ???????? ethernet0 = &enetc0;
>>> ???????? ethernet1 = &enetc1;
>>> ???????? ethernet2 = &enetc2;
>>> ???????? ethernet3 = &enetc6;
>>> };
>>>
>>> The individual devices might be disabled, depending on the board variant
>>> (which might also be dynamically determined during startup).
>>
>> By disabled, do you mean that they are marked 'status = "disabled"'?
> 
> yes
> 
>> If so, then they are ignored by DM and will not claim their number.
>>
>>>
>>> My first smoke test with this series show the following:
>>>
>>> ?? uclass 32: eth
>>> ?? 0?? * enetc-0 @ ffd40e60, seq 0
>>> ?? 1?? * ax88179_eth @ ffd51f50, seq 1
>>>
>>> Looks like the usb ethernet device will get seq 1 assigned (after "usb
>>> start"). Is this intended?
>>>
>>> If so, this is a problem, because for ethernet devices, the MAC address
>>> is assigned according to the ethNaddr variable. And at least for this
>>> board (kontron_sl28) the first four are reserved for the ones with the
>>> alias entries. Thus I'd have expected that the usb device will get seq 4
>>> assigned.
>>
>> OK, so you mean after all existing aliases, even if they did not bind.
>> I think we can do that.
> 
> Great, that will also match the current behavior. See
> be1a6e94254af205bd67d69e3bdb26b161ccd72f ("dm: uclass: don't assign
> aliased seq numbers")

Also take a look at 83e4c7e9ffa57fe4116967999c223c952a46a78a
which is more or less the same things as is done in linux
by351d224f64afc1b3b359a1738b7d4600c7e64061

And we are using it for i2c subsystem.

If you look at Linux kernel i2c/spi subsystems they are using it for
quite a while. Recently mmc subsystem starts to use it.
On the other hand we had similar discussion around networking and it has
never started to be used.

In general make sense if you have uclass that it is recorded(based on
aliases) the first highest free ID and start to use it for devices which
are not listed or don't have record in aliases.

That's IMHO the best predictable behavior we could reach. If you care
about numbering scheme then your device should have alias.

Also if there are devices which doesn't have alias keyword we should
work with DT guys to get it listed in the spec.

Thanks,
Michal

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

* [PATCH 00/27] dm: Change the way sequence numbers are implemented
  2020-12-10  7:34       ` Michal Simek
@ 2020-12-10 17:27         ` Simon Glass
  2020-12-10 17:32           ` Michal Simek
  0 siblings, 1 reply; 50+ messages in thread
From: Simon Glass @ 2020-12-10 17:27 UTC (permalink / raw)
  To: u-boot

Hi Michal,

On Thu, 10 Dec 2020 at 00:34, Michal Simek <michal.simek@xilinx.com> wrote:
>
> Hi,
>
> On 09. 12. 20 17:30, Michael Walle wrote:
> > Hi Simon,
> >
> > Am 2020-12-09 17:23, schrieb Simon Glass:
> >> On Tue, 8 Dec 2020 at 15:52, Michael Walle <michael@walle.cc> wrote:
> >>> Am 2020-11-30 02:53, schrieb Simon Glass:
> >>> > At present each device has two sequence numbers, with 'req_seq' being
> >>> > set up at bind time and 'seq' at probe time. The idea is that devices
> >>> > can 'request' a sequence number and then the conflicts are resolved
> >>> > when
> >>> > the device is probed.
> >>> >
> >>> > This makes things complicated in a few cases, since we don't really
> >>> > know
> >>> > (at bind time) what the sequence number will end up being. We want to
> >>> > honour the bind-time requests if at all possible, but in fact the only
> >>> > source of these at present is the devicetree aliases.
> >>> >
> >>> > Apart from the obvious need for sequence numbers to supports U-Boot's
> >>> > numbering on devices on the command line, the current scheme was
> >>> > designed to:
> >>> >
> >>> > - avoid calculating the sequence number until it is needed, to save
> >>> >   execution time
> >>> > - allow multiple devices to obtain a particular sequence number as
> >>> they
> >>> >   are probed and removed
> >>> > - retain a record of the 'requested' sequence number even if it turns
> >>> > out
> >>> >   that a device could not get it (to allow debugging and retrying)
> >>> >
> >>> > After some years using the current scheme it seems on balance that
> >>> > these
> >>> > goals don't have as much merit as first thought. The first point would
> >>> > be persuasive except that we end up reading the devicetree aliases at
> >>> > bind-time anyway. So the work of resolving the sequence numbers during
> >>> > probing is not that great. The second point hasn't really been an
> >>> > issue,
> >>> > as there is typically no contention for sequence numbers (boards tend
> >>> > to
> >>> > allocate them statically in the devicetree). Re the third point, we
> >>> can
> >>> > often figure out what was requested by looking at aliases, and in the
> >>> > cases where we can't, it doesn't seem to matter much.
> >>> >
> >>> > Since we have the devicetree available at bind time, we may as well
> >>> > just
> >>> > use it, in the hope that the required processing will turn out to be
> >>> > useful later (i.e. the device actually gets used). In addition, it is
> >>> > simpler to use a single sequence number, since it avoids confusion and
> >>> > some extra code.
> >>> >
> >>> > This series moves U-Boot to use a single, bind-time sequence number.
> >>> > All
> >>> > uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign
> >>> > sequence
> >>> > numbers to their devices, so that as soon as a device is bound, it has
> >>> > a
> >>> > sequence number. If a devicetree alias provides the number, it will be
> >>> > used. Otherwise, during initial binding, the first free number is
> >>> used.
> >>>
> >>> What does "first free number mean"?
> >>>
> >>> I have a device tree with the following aliases for network:
> >>>
> >>> aliases {
> >>>          ethernet0 = &enetc0;
> >>>          ethernet1 = &enetc1;
> >>>          ethernet2 = &enetc2;
> >>>          ethernet3 = &enetc6;
> >>> };
> >>>
> >>> The individual devices might be disabled, depending on the board variant
> >>> (which might also be dynamically determined during startup).
> >>
> >> By disabled, do you mean that they are marked 'status = "disabled"'?
> >
> > yes
> >
> >> If so, then they are ignored by DM and will not claim their number.
> >>
> >>>
> >>> My first smoke test with this series show the following:
> >>>
> >>>    uclass 32: eth
> >>>    0   * enetc-0 @ ffd40e60, seq 0
> >>>    1   * ax88179_eth @ ffd51f50, seq 1
> >>>
> >>> Looks like the usb ethernet device will get seq 1 assigned (after "usb
> >>> start"). Is this intended?
> >>>
> >>> If so, this is a problem, because for ethernet devices, the MAC address
> >>> is assigned according to the ethNaddr variable. And at least for this
> >>> board (kontron_sl28) the first four are reserved for the ones with the
> >>> alias entries. Thus I'd have expected that the usb device will get seq 4
> >>> assigned.
> >>
> >> OK, so you mean after all existing aliases, even if they did not bind.
> >> I think we can do that.
> >
> > Great, that will also match the current behavior. See
> > be1a6e94254af205bd67d69e3bdb26b161ccd72f ("dm: uclass: don't assign
> > aliased seq numbers")
>
> Also take a look at 83e4c7e9ffa57fe4116967999c223c952a46a78a
> which is more or less the same things as is done in linux
> by351d224f64afc1b3b359a1738b7d4600c7e64061
>
> And we are using it for i2c subsystem.
>
> If you look at Linux kernel i2c/spi subsystems they are using it for
> quite a while. Recently mmc subsystem starts to use it.
> On the other hand we had similar discussion around networking and it has
> never started to be used.
>
> In general make sense if you have uclass that it is recorded(based on
> aliases) the first highest free ID and start to use it for devices which
> are not listed or don't have record in aliases.
>
> That's IMHO the best predictable behavior we could reach. If you care
> about numbering scheme then your device should have alias.
>
> Also if there are devices which doesn't have alias keyword we should
> work with DT guys to get it listed in the spec.

Do you mean the root of the name (e.g. i2c for i2c1)?

Also has there been any discussion of using phandles instead of
strings? Perhaps we could create a new node with that approach.

Regards,
Simon

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

* [PATCH 00/27] dm: Change the way sequence numbers are implemented
  2020-12-10 17:27         ` Simon Glass
@ 2020-12-10 17:32           ` Michal Simek
  2020-12-10 17:46             ` Simon Glass
  0 siblings, 1 reply; 50+ messages in thread
From: Michal Simek @ 2020-12-10 17:32 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On 10. 12. 20 18:27, Simon Glass wrote:
> Hi Michal,
> 
> On Thu, 10 Dec 2020 at 00:34, Michal Simek <michal.simek@xilinx.com> wrote:
>>
>> Hi,
>>
>> On 09. 12. 20 17:30, Michael Walle wrote:
>>> Hi Simon,
>>>
>>> Am 2020-12-09 17:23, schrieb Simon Glass:
>>>> On Tue, 8 Dec 2020 at 15:52, Michael Walle <michael@walle.cc> wrote:
>>>>> Am 2020-11-30 02:53, schrieb Simon Glass:
>>>>>> At present each device has two sequence numbers, with 'req_seq' being
>>>>>> set up at bind time and 'seq' at probe time. The idea is that devices
>>>>>> can 'request' a sequence number and then the conflicts are resolved
>>>>>> when
>>>>>> the device is probed.
>>>>>>
>>>>>> This makes things complicated in a few cases, since we don't really
>>>>>> know
>>>>>> (at bind time) what the sequence number will end up being. We want to
>>>>>> honour the bind-time requests if at all possible, but in fact the only
>>>>>> source of these at present is the devicetree aliases.
>>>>>>
>>>>>> Apart from the obvious need for sequence numbers to supports U-Boot's
>>>>>> numbering on devices on the command line, the current scheme was
>>>>>> designed to:
>>>>>>
>>>>>> - avoid calculating the sequence number until it is needed, to save
>>>>>>   execution time
>>>>>> - allow multiple devices to obtain a particular sequence number as
>>>>> they
>>>>>>   are probed and removed
>>>>>> - retain a record of the 'requested' sequence number even if it turns
>>>>>> out
>>>>>>   that a device could not get it (to allow debugging and retrying)
>>>>>>
>>>>>> After some years using the current scheme it seems on balance that
>>>>>> these
>>>>>> goals don't have as much merit as first thought. The first point would
>>>>>> be persuasive except that we end up reading the devicetree aliases at
>>>>>> bind-time anyway. So the work of resolving the sequence numbers during
>>>>>> probing is not that great. The second point hasn't really been an
>>>>>> issue,
>>>>>> as there is typically no contention for sequence numbers (boards tend
>>>>>> to
>>>>>> allocate them statically in the devicetree). Re the third point, we
>>>>> can
>>>>>> often figure out what was requested by looking at aliases, and in the
>>>>>> cases where we can't, it doesn't seem to matter much.
>>>>>>
>>>>>> Since we have the devicetree available at bind time, we may as well
>>>>>> just
>>>>>> use it, in the hope that the required processing will turn out to be
>>>>>> useful later (i.e. the device actually gets used). In addition, it is
>>>>>> simpler to use a single sequence number, since it avoids confusion and
>>>>>> some extra code.
>>>>>>
>>>>>> This series moves U-Boot to use a single, bind-time sequence number.
>>>>>> All
>>>>>> uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign
>>>>>> sequence
>>>>>> numbers to their devices, so that as soon as a device is bound, it has
>>>>>> a
>>>>>> sequence number. If a devicetree alias provides the number, it will be
>>>>>> used. Otherwise, during initial binding, the first free number is
>>>>> used.
>>>>>
>>>>> What does "first free number mean"?
>>>>>
>>>>> I have a device tree with the following aliases for network:
>>>>>
>>>>> aliases {
>>>>>          ethernet0 = &enetc0;
>>>>>          ethernet1 = &enetc1;
>>>>>          ethernet2 = &enetc2;
>>>>>          ethernet3 = &enetc6;
>>>>> };
>>>>>
>>>>> The individual devices might be disabled, depending on the board variant
>>>>> (which might also be dynamically determined during startup).
>>>>
>>>> By disabled, do you mean that they are marked 'status = "disabled"'?
>>>
>>> yes
>>>
>>>> If so, then they are ignored by DM and will not claim their number.
>>>>
>>>>>
>>>>> My first smoke test with this series show the following:
>>>>>
>>>>>    uclass 32: eth
>>>>>    0   * enetc-0 @ ffd40e60, seq 0
>>>>>    1   * ax88179_eth @ ffd51f50, seq 1
>>>>>
>>>>> Looks like the usb ethernet device will get seq 1 assigned (after "usb
>>>>> start"). Is this intended?
>>>>>
>>>>> If so, this is a problem, because for ethernet devices, the MAC address
>>>>> is assigned according to the ethNaddr variable. And at least for this
>>>>> board (kontron_sl28) the first four are reserved for the ones with the
>>>>> alias entries. Thus I'd have expected that the usb device will get seq 4
>>>>> assigned.
>>>>
>>>> OK, so you mean after all existing aliases, even if they did not bind.
>>>> I think we can do that.
>>>
>>> Great, that will also match the current behavior. See
>>> be1a6e94254af205bd67d69e3bdb26b161ccd72f ("dm: uclass: don't assign
>>> aliased seq numbers")
>>
>> Also take a look at 83e4c7e9ffa57fe4116967999c223c952a46a78a
>> which is more or less the same things as is done in linux
>> by351d224f64afc1b3b359a1738b7d4600c7e64061
>>
>> And we are using it for i2c subsystem.
>>
>> If you look at Linux kernel i2c/spi subsystems they are using it for
>> quite a while. Recently mmc subsystem starts to use it.
>> On the other hand we had similar discussion around networking and it has
>> never started to be used.
>>
>> In general make sense if you have uclass that it is recorded(based on
>> aliases) the first highest free ID and start to use it for devices which
>> are not listed or don't have record in aliases.
>>
>> That's IMHO the best predictable behavior we could reach. If you care
>> about numbering scheme then your device should have alias.
>>
>> Also if there are devices which doesn't have alias keyword we should
>> work with DT guys to get it listed in the spec.
> 
> Do you mean the root of the name (e.g. i2c for i2c1)?

yes assigned the root of the name to specific uclass.

> 
> Also has there been any discussion of using phandles instead of
> strings? Perhaps we could create a new node with that approach.

What do you mean by string?
Aliases are not using phandles. It is just label converted to path.
for example from dtc -I dtb -O dts.

        aliases {
                ethernet0 = "/amba_pl/ethernet at 40c00000";
                i2c0 = "/amba_pl/i2c at 40800000";
                serial0 = "/amba_pl/serial at 40600000";
        };


Thanks,
Michal

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

* [PATCH 00/27] dm: Change the way sequence numbers are implemented
  2020-12-10 17:32           ` Michal Simek
@ 2020-12-10 17:46             ` Simon Glass
  2020-12-11  7:28               ` Michal Simek
  0 siblings, 1 reply; 50+ messages in thread
From: Simon Glass @ 2020-12-10 17:46 UTC (permalink / raw)
  To: u-boot

Hi Michal,

On Thu, 10 Dec 2020 at 10:33, Michal Simek <michal.simek@xilinx.com> wrote:
>
> Hi Simon,
>
> On 10. 12. 20 18:27, Simon Glass wrote:
> > Hi Michal,
> >
> > On Thu, 10 Dec 2020 at 00:34, Michal Simek <michal.simek@xilinx.com> wrote:
> >>
> >> Hi,
> >>
> >> On 09. 12. 20 17:30, Michael Walle wrote:
> >>> Hi Simon,
> >>>
> >>> Am 2020-12-09 17:23, schrieb Simon Glass:
> >>>> On Tue, 8 Dec 2020 at 15:52, Michael Walle <michael@walle.cc> wrote:
> >>>>> Am 2020-11-30 02:53, schrieb Simon Glass:
> >>>>>> At present each device has two sequence numbers, with 'req_seq' being
> >>>>>> set up at bind time and 'seq' at probe time. The idea is that devices
> >>>>>> can 'request' a sequence number and then the conflicts are resolved
> >>>>>> when
> >>>>>> the device is probed.
> >>>>>>
> >>>>>> This makes things complicated in a few cases, since we don't really
> >>>>>> know
> >>>>>> (at bind time) what the sequence number will end up being. We want to
> >>>>>> honour the bind-time requests if at all possible, but in fact the only
> >>>>>> source of these at present is the devicetree aliases.
> >>>>>>
> >>>>>> Apart from the obvious need for sequence numbers to supports U-Boot's
> >>>>>> numbering on devices on the command line, the current scheme was
> >>>>>> designed to:
> >>>>>>
> >>>>>> - avoid calculating the sequence number until it is needed, to save
> >>>>>>   execution time
> >>>>>> - allow multiple devices to obtain a particular sequence number as
> >>>>> they
> >>>>>>   are probed and removed
> >>>>>> - retain a record of the 'requested' sequence number even if it turns
> >>>>>> out
> >>>>>>   that a device could not get it (to allow debugging and retrying)
> >>>>>>
> >>>>>> After some years using the current scheme it seems on balance that
> >>>>>> these
> >>>>>> goals don't have as much merit as first thought. The first point would
> >>>>>> be persuasive except that we end up reading the devicetree aliases at
> >>>>>> bind-time anyway. So the work of resolving the sequence numbers during
> >>>>>> probing is not that great. The second point hasn't really been an
> >>>>>> issue,
> >>>>>> as there is typically no contention for sequence numbers (boards tend
> >>>>>> to
> >>>>>> allocate them statically in the devicetree). Re the third point, we
> >>>>> can
> >>>>>> often figure out what was requested by looking at aliases, and in the
> >>>>>> cases where we can't, it doesn't seem to matter much.
> >>>>>>
> >>>>>> Since we have the devicetree available at bind time, we may as well
> >>>>>> just
> >>>>>> use it, in the hope that the required processing will turn out to be
> >>>>>> useful later (i.e. the device actually gets used). In addition, it is
> >>>>>> simpler to use a single sequence number, since it avoids confusion and
> >>>>>> some extra code.
> >>>>>>
> >>>>>> This series moves U-Boot to use a single, bind-time sequence number.
> >>>>>> All
> >>>>>> uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign
> >>>>>> sequence
> >>>>>> numbers to their devices, so that as soon as a device is bound, it has
> >>>>>> a
> >>>>>> sequence number. If a devicetree alias provides the number, it will be
> >>>>>> used. Otherwise, during initial binding, the first free number is
> >>>>> used.
> >>>>>
> >>>>> What does "first free number mean"?
> >>>>>
> >>>>> I have a device tree with the following aliases for network:
> >>>>>
> >>>>> aliases {
> >>>>>          ethernet0 = &enetc0;
> >>>>>          ethernet1 = &enetc1;
> >>>>>          ethernet2 = &enetc2;
> >>>>>          ethernet3 = &enetc6;
> >>>>> };
> >>>>>
> >>>>> The individual devices might be disabled, depending on the board variant
> >>>>> (which might also be dynamically determined during startup).
> >>>>
> >>>> By disabled, do you mean that they are marked 'status = "disabled"'?
> >>>
> >>> yes
> >>>
> >>>> If so, then they are ignored by DM and will not claim their number.
> >>>>
> >>>>>
> >>>>> My first smoke test with this series show the following:
> >>>>>
> >>>>>    uclass 32: eth
> >>>>>    0   * enetc-0 @ ffd40e60, seq 0
> >>>>>    1   * ax88179_eth @ ffd51f50, seq 1
> >>>>>
> >>>>> Looks like the usb ethernet device will get seq 1 assigned (after "usb
> >>>>> start"). Is this intended?
> >>>>>
> >>>>> If so, this is a problem, because for ethernet devices, the MAC address
> >>>>> is assigned according to the ethNaddr variable. And at least for this
> >>>>> board (kontron_sl28) the first four are reserved for the ones with the
> >>>>> alias entries. Thus I'd have expected that the usb device will get seq 4
> >>>>> assigned.
> >>>>
> >>>> OK, so you mean after all existing aliases, even if they did not bind.
> >>>> I think we can do that.
> >>>
> >>> Great, that will also match the current behavior. See
> >>> be1a6e94254af205bd67d69e3bdb26b161ccd72f ("dm: uclass: don't assign
> >>> aliased seq numbers")
> >>
> >> Also take a look at 83e4c7e9ffa57fe4116967999c223c952a46a78a
> >> which is more or less the same things as is done in linux
> >> by351d224f64afc1b3b359a1738b7d4600c7e64061
> >>
> >> And we are using it for i2c subsystem.
> >>
> >> If you look at Linux kernel i2c/spi subsystems they are using it for
> >> quite a while. Recently mmc subsystem starts to use it.
> >> On the other hand we had similar discussion around networking and it has
> >> never started to be used.
> >>
> >> In general make sense if you have uclass that it is recorded(based on
> >> aliases) the first highest free ID and start to use it for devices which
> >> are not listed or don't have record in aliases.
> >>
> >> That's IMHO the best predictable behavior we could reach. If you care
> >> about numbering scheme then your device should have alias.
> >>
> >> Also if there are devices which doesn't have alias keyword we should
> >> work with DT guys to get it listed in the spec.
> >
> > Do you mean the root of the name (e.g. i2c for i2c1)?
>
> yes assigned the root of the name to specific uclass.

Oh gosh, I didn't even know they were in the DT spec.

>
> >
> > Also has there been any discussion of using phandles instead of
> > strings? Perhaps we could create a new node with that approach.
>
> What do you mean by string?
> Aliases are not using phandles. It is just label converted to path.
> for example from dtc -I dtb -O dts.
>
>         aliases {
>                 ethernet0 = "/amba_pl/ethernet at 40c00000";
>                 i2c0 = "/amba_pl/i2c at 40800000";
>                 serial0 = "/amba_pl/serial at 40600000";
>         };

Yes that's my point. It uses strings, which is inefficient. I feel we
could use phandles instead and solve a number of problems.

Regards,
Simon

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

* [PATCH 01/27] linker_lists: Fix alignment issue
  2020-12-09 18:22           ` Heinrich Schuchardt
@ 2020-12-10 19:26             ` Simon Glass
  0 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-12-10 19:26 UTC (permalink / raw)
  To: u-boot

Hi Heinrich,

On Wed, 9 Dec 2020 at 11:22, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>
> On 12/1/20 4:58 PM, Simon Glass wrote:
> > Hi Heinrich,
> >
> > On Mon, 30 Nov 2020 at 15:56, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
> >>
> >> On 11/30/20 9:11 PM, Simon Glass wrote:
> >>> +Marek Vasut who originally wrote it
> >>>
> >>> Hi Heinrich,
> >>>
> >>> On Sun, 29 Nov 2020 at 23:20, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
> >>>>
> >>>> Am 30. November 2020 02:53:36 MEZ schrieb Simon Glass <sjg@chromium.org>:
> >>>>> The linker script uses alphabetic sorting to group the different linker
> >>>>> lists together. Each group has its own struct and potentially its own
> >>>>> alignment. But when the linker packs the structs together it cannot
> >>>>> ensure that a linker list starts on the expected alignment boundary.
> >>>>>
> >>>>> For example, if the first list has a struct size of 8 and we place 3 of
> >>>>> them in the image, that means that the next struct will start at offset
> >>>>> 0x18 from the start of the linker_list section. If the next struct has
> >>>>> a size of 16 then it will start at an 8-byte aligned offset, but not a
> >>>>> 16-byte aligned offset.
> >>>>>
> >>>>> With sandbox on x86_64, a reference to a linker list item using
> >>>>> ll_entry_get() can force alignment of that particular linker_list item,
> >>>>> if it is in the same file as the linker_list item is declared.
> >>>>>
> >>>>> Consider this example, where struct driver is 0x80 bytes:
> >>>>>
> >>>>>         ll_entry_declare(struct driver, fred, driver)
> >>>>>
> >>>>> ...
> >>>>>
> >>>>>         void *p = ll_entry_get(struct driver, fred, driver)
> >>>>>
> >>>>> If these two lines of code are in the same file, then the entry is
> >>>>> forced
> >>>>> to be aligned at the 'struct driver' alignment, which is 16 bytes. If
> >>>>> the
> >>>>> second line of code is in a different file, then no action is taken,
> >>>>> since
> >>>>> the compiler cannot update the alignment of the linker_list item.
> >>>>>
> >>>>> In the first case, an 8-byte 'fill' region is added:
> >>>>>
> >>>>> .u_boot_list_2_driver_2_testbus_drv
> >>>>>                  0x0000000000270018       0x80 test/built-in.o
> >>>>>                  0x0000000000270018
> >>>>>                         _u_boot_list_2_driver_2_testbus_drv
> >>>>> .u_boot_list_2_driver_2_testfdt1_drv
> >>>>>                  0x0000000000270098       0x80 test/built-in.o
> >>>>>                  0x0000000000270098
> >>>>>                         _u_boot_list_2_driver_2_testfdt1_drv
> >>>>> *fill*         0x0000000000270118        0x8
> >>>>> .u_boot_list_2_driver_2_testfdt_drv
> >>>>>                  0x0000000000270120       0x80 test/built-in.o
> >>>>>                  0x0000000000270120
> >>>>>                         _u_boot_list_2_driver_2_testfdt_drv
> >>>>> .u_boot_list_2_driver_2_testprobe_drv
> >>>>>                  0x00000000002701a0       0x80 test/built-in.o
> >>>>>                  0x00000000002701a0
> >>>>>                         _u_boot_list_2_driver_2_testprobe_drv
> >>>>>
> >>>>> With this, the linker_list no-longer works since items after
> >>>>> testfdt1_drv
> >>>>> are not at the expected address.
> >>>>>
> >>>>> Ideally we would have a way to tell gcc not to align structs in this
> >>>>> way.
> >>>>> It is not clear how we could do this, and in any case it would require
> >>>>> us
> >>>>> to adjust every struct used by the linker_list feature.
> >>>>>
> >>>>> One possible fix is to force each separate linker_list to start on the
> >>>>> largest possible boundary that can be required by the compiler. However
> >>>>> that does not seem to work on x86_64, which uses 16-byte alignment in
> >>>>> this
> >>>>> case but needs 32-byte alignment.
> >>>>>
> >>>>> So add a Kconfig option to handle this. Set the default value to 4 so
> >>>>> as to avoid changing platforms that don't need it.
> >>>>>
> >>>>> Update the ll_entry_start() accordingly.
> >>>>>
> >>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
> >>>>> ---
> >>>>>
> >>>>> arch/Kconfig             | 11 +++++++
> >>>>> doc/api/linker_lists.rst | 62 ++++++++++++++++++++++++++++++++++++++++
> >>>>> include/linker_lists.h   |  3 +-
> >>>>> 3 files changed, 75 insertions(+), 1 deletion(-)
> >>>>>
> >>>>> diff --git a/arch/Kconfig b/arch/Kconfig
> >>>>> index 3aa99e08fce..aa8664212f1 100644
> >>>>> --- a/arch/Kconfig
> >>>>> +++ b/arch/Kconfig
> >>>>> @@ -7,6 +7,17 @@ config HAVE_ARCH_IOREMAP
> >>>>> config NEEDS_MANUAL_RELOC
> >>>>>         bool
> >>>>>
> >>>>> +config LINKER_LIST_ALIGN
> >>>>> +      int
> >>>>> +      default 32 if SANDBOX
> >>>>
> >>>> What is so special about the sandbox?
> >>>
> >>> I'm not too sure, actually. Also, 32 seems to be larger than
> >>> __BIGGEST_ALIGNMENT__ so it is confusing.
> >>>
> >>>> Just evaluate if the host is 64 bit and use 8 or 4 accordingly?
> >>>>
> >>>>> +      default 8 if ARM64 || X86
> >>>>
> >>>> Shouldn't the default be 8 on all 64 bit platforms? And 4 on all 32 bit platforms?
> >>>
> >>> Possibly, but who knows? One way to really get to the bottom of this
> >>> is to have a test that checks that the alignment is what it should be.
> >>> I spent half a day diagnosing this but not that much time thinking of
> >>> the best solution. If you have time to dig into it please let me know.
> >>>
> >>> Regards,
> >>> Simon
> >>>
> >>
> >> If you change ll_entry_start() as below, the linker will complain
> >> "lib/efi_driver/efi_uclass.c:309:
> >> undefined reference to `bad_alignment'"
> >>
> >> If you change value 4 to 8, it stops complaining for qemu-x86_64_defconfig.
> >>
> >> #define ll_alignment(x) \
> >>           (__builtin_offsetof(struct {char a; x b;}, b))
> >> void bad_alignment(void);
> >> #define ll_entry_start(_type, _list) \
> >> ({ \
> >>           static char start[0] __aligned(4) __attribute__((unused, \
> >>                   section(".u_boot_list_2_"#_list"_1"))); \
> >>           if (ll_alignment(_type) > 4) \
> >>                   bad_alignment(); \
> >>           (_type *)&start; \
> >> })
> >>
> >> If the alignment is smaller than the limit, the compiler can remove the
> >> bad_alignment() call due to the optimization setting -Os (or -O2).
> >>
> >> For RISC-V 64bit you also need 8 byte alignment.
> >>
> >> I suggest that you replace 4 by sizeof(long) and run the change through
> >> Gitlab to validate that 8 bytes on 64-bit systems and 4 bytes on 32-bit
> >> systems are sufficient alignment.
> >>
> >> I did not check if any linker lists are accessed via other means then
> >> ll_entry_start().
> >
> > Thanks. You would think that would be enough, but somehow
> > ll_entry_get() seems to make things worse.
> >
> > I'm not sure how to do sizeof(long) in Kconfig
>
> Linux defines a symbol 64BIT in arch/ for all architectures, e.g.
>
> arch/x86/Kconfig:3:config 64BIT
> arch/x86/Kconfig-4-     bool "64-bit kernel" if "$(ARCH)" = "x86"
> arch/x86/Kconfig-5-     default "$(ARCH)" != "i386"
>
> U-Boot has it only for two architectures:
>
> arch/mips/Kconfig:501:config 64BIT
> arch/riscv/Kconfig:152:config 64BIT

Yes indeed.

But I haven't actually found documentation that explains what is going
on with alignment. It is hard to define rules when we don't know the
behaviour.

https://docs.adacore.com/live/wave/binutils-stable/html/ld/ld.html

Regards,
Simon

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

* [PATCH 00/27] dm: Change the way sequence numbers are implemented
  2020-12-10 17:46             ` Simon Glass
@ 2020-12-11  7:28               ` Michal Simek
  2020-12-11  7:42                 ` Heinrich Schuchardt
  0 siblings, 1 reply; 50+ messages in thread
From: Michal Simek @ 2020-12-11  7:28 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On 10. 12. 20 18:46, Simon Glass wrote:
> Hi Michal,
> 
> On Thu, 10 Dec 2020 at 10:33, Michal Simek <michal.simek@xilinx.com> wrote:
>>
>> Hi Simon,
>>
>> On 10. 12. 20 18:27, Simon Glass wrote:
>>> Hi Michal,
>>>
>>> On Thu, 10 Dec 2020 at 00:34, Michal Simek <michal.simek@xilinx.com> wrote:
>>>>
>>>> Hi,
>>>>
>>>> On 09. 12. 20 17:30, Michael Walle wrote:
>>>>> Hi Simon,
>>>>>
>>>>> Am 2020-12-09 17:23, schrieb Simon Glass:
>>>>>> On Tue, 8 Dec 2020 at 15:52, Michael Walle <michael@walle.cc> wrote:
>>>>>>> Am 2020-11-30 02:53, schrieb Simon Glass:
>>>>>>>> At present each device has two sequence numbers, with 'req_seq' being
>>>>>>>> set up at bind time and 'seq' at probe time. The idea is that devices
>>>>>>>> can 'request' a sequence number and then the conflicts are resolved
>>>>>>>> when
>>>>>>>> the device is probed.
>>>>>>>>
>>>>>>>> This makes things complicated in a few cases, since we don't really
>>>>>>>> know
>>>>>>>> (at bind time) what the sequence number will end up being. We want to
>>>>>>>> honour the bind-time requests if at all possible, but in fact the only
>>>>>>>> source of these at present is the devicetree aliases.
>>>>>>>>
>>>>>>>> Apart from the obvious need for sequence numbers to supports U-Boot's
>>>>>>>> numbering on devices on the command line, the current scheme was
>>>>>>>> designed to:
>>>>>>>>
>>>>>>>> - avoid calculating the sequence number until it is needed, to save
>>>>>>>>   execution time
>>>>>>>> - allow multiple devices to obtain a particular sequence number as
>>>>>>> they
>>>>>>>>   are probed and removed
>>>>>>>> - retain a record of the 'requested' sequence number even if it turns
>>>>>>>> out
>>>>>>>>   that a device could not get it (to allow debugging and retrying)
>>>>>>>>
>>>>>>>> After some years using the current scheme it seems on balance that
>>>>>>>> these
>>>>>>>> goals don't have as much merit as first thought. The first point would
>>>>>>>> be persuasive except that we end up reading the devicetree aliases at
>>>>>>>> bind-time anyway. So the work of resolving the sequence numbers during
>>>>>>>> probing is not that great. The second point hasn't really been an
>>>>>>>> issue,
>>>>>>>> as there is typically no contention for sequence numbers (boards tend
>>>>>>>> to
>>>>>>>> allocate them statically in the devicetree). Re the third point, we
>>>>>>> can
>>>>>>>> often figure out what was requested by looking at aliases, and in the
>>>>>>>> cases where we can't, it doesn't seem to matter much.
>>>>>>>>
>>>>>>>> Since we have the devicetree available at bind time, we may as well
>>>>>>>> just
>>>>>>>> use it, in the hope that the required processing will turn out to be
>>>>>>>> useful later (i.e. the device actually gets used). In addition, it is
>>>>>>>> simpler to use a single sequence number, since it avoids confusion and
>>>>>>>> some extra code.
>>>>>>>>
>>>>>>>> This series moves U-Boot to use a single, bind-time sequence number.
>>>>>>>> All
>>>>>>>> uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign
>>>>>>>> sequence
>>>>>>>> numbers to their devices, so that as soon as a device is bound, it has
>>>>>>>> a
>>>>>>>> sequence number. If a devicetree alias provides the number, it will be
>>>>>>>> used. Otherwise, during initial binding, the first free number is
>>>>>>> used.
>>>>>>>
>>>>>>> What does "first free number mean"?
>>>>>>>
>>>>>>> I have a device tree with the following aliases for network:
>>>>>>>
>>>>>>> aliases {
>>>>>>>          ethernet0 = &enetc0;
>>>>>>>          ethernet1 = &enetc1;
>>>>>>>          ethernet2 = &enetc2;
>>>>>>>          ethernet3 = &enetc6;
>>>>>>> };
>>>>>>>
>>>>>>> The individual devices might be disabled, depending on the board variant
>>>>>>> (which might also be dynamically determined during startup).
>>>>>>
>>>>>> By disabled, do you mean that they are marked 'status = "disabled"'?
>>>>>
>>>>> yes
>>>>>
>>>>>> If so, then they are ignored by DM and will not claim their number.
>>>>>>
>>>>>>>
>>>>>>> My first smoke test with this series show the following:
>>>>>>>
>>>>>>>    uclass 32: eth
>>>>>>>    0   * enetc-0 @ ffd40e60, seq 0
>>>>>>>    1   * ax88179_eth @ ffd51f50, seq 1
>>>>>>>
>>>>>>> Looks like the usb ethernet device will get seq 1 assigned (after "usb
>>>>>>> start"). Is this intended?
>>>>>>>
>>>>>>> If so, this is a problem, because for ethernet devices, the MAC address
>>>>>>> is assigned according to the ethNaddr variable. And at least for this
>>>>>>> board (kontron_sl28) the first four are reserved for the ones with the
>>>>>>> alias entries. Thus I'd have expected that the usb device will get seq 4
>>>>>>> assigned.
>>>>>>
>>>>>> OK, so you mean after all existing aliases, even if they did not bind.
>>>>>> I think we can do that.
>>>>>
>>>>> Great, that will also match the current behavior. See
>>>>> be1a6e94254af205bd67d69e3bdb26b161ccd72f ("dm: uclass: don't assign
>>>>> aliased seq numbers")
>>>>
>>>> Also take a look at 83e4c7e9ffa57fe4116967999c223c952a46a78a
>>>> which is more or less the same things as is done in linux
>>>> by351d224f64afc1b3b359a1738b7d4600c7e64061
>>>>
>>>> And we are using it for i2c subsystem.
>>>>
>>>> If you look at Linux kernel i2c/spi subsystems they are using it for
>>>> quite a while. Recently mmc subsystem starts to use it.
>>>> On the other hand we had similar discussion around networking and it has
>>>> never started to be used.
>>>>
>>>> In general make sense if you have uclass that it is recorded(based on
>>>> aliases) the first highest free ID and start to use it for devices which
>>>> are not listed or don't have record in aliases.
>>>>
>>>> That's IMHO the best predictable behavior we could reach. If you care
>>>> about numbering scheme then your device should have alias.
>>>>
>>>> Also if there are devices which doesn't have alias keyword we should
>>>> work with DT guys to get it listed in the spec.
>>>
>>> Do you mean the root of the name (e.g. i2c for i2c1)?
>>
>> yes assigned the root of the name to specific uclass.
> 
> Oh gosh, I didn't even know they were in the DT spec.

In DT spec you have recommended node names which is more or less fit
with uclasses.


>>
>>>
>>> Also has there been any discussion of using phandles instead of
>>> strings? Perhaps we could create a new node with that approach.
>>
>> What do you mean by string?
>> Aliases are not using phandles. It is just label converted to path.
>> for example from dtc -I dtb -O dts.
>>
>>         aliases {
>>                 ethernet0 = "/amba_pl/ethernet at 40c00000";
>>                 i2c0 = "/amba_pl/i2c at 40800000";
>>                 serial0 = "/amba_pl/serial at 40600000";
>>         };
> 
> Yes that's my point. It uses strings, which is inefficient. I feel we
> could use phandles instead and solve a number of problems.

If you want to change it we can't change it in one project only. And
this discussion should be made against DT specification.
Another thing is that that Linux is not capable to update aliases when
for example DT overlay is applied. This part is completely ignored even
if there is no collision. Nothing important for U-Boot but something to
keep in mind.
IIRC We don't support run time overlay applying to be able to add more
nodes (but would be useful to have it too).

Thanks,
Michal

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

* [PATCH 00/27] dm: Change the way sequence numbers are implemented
  2020-12-11  7:28               ` Michal Simek
@ 2020-12-11  7:42                 ` Heinrich Schuchardt
  2020-12-11  7:53                   ` Michal Simek
  0 siblings, 1 reply; 50+ messages in thread
From: Heinrich Schuchardt @ 2020-12-11  7:42 UTC (permalink / raw)
  To: u-boot

On 12/11/20 8:28 AM, Michal Simek wrote:
> Hi Simon,
>
> On 10. 12. 20 18:46, Simon Glass wrote:
>> Hi Michal,
>>
>> On Thu, 10 Dec 2020 at 10:33, Michal Simek <michal.simek@xilinx.com> wrote:
>>>
>>> Hi Simon,
>>>
>>> On 10. 12. 20 18:27, Simon Glass wrote:
>>>> Hi Michal,
>>>>
>>>> On Thu, 10 Dec 2020 at 00:34, Michal Simek <michal.simek@xilinx.com> wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> On 09. 12. 20 17:30, Michael Walle wrote:
>>>>>> Hi Simon,
>>>>>>
>>>>>> Am 2020-12-09 17:23, schrieb Simon Glass:
>>>>>>> On Tue, 8 Dec 2020 at 15:52, Michael Walle <michael@walle.cc> wrote:
>>>>>>>> Am 2020-11-30 02:53, schrieb Simon Glass:
>>>>>>>>> At present each device has two sequence numbers, with 'req_seq' being
>>>>>>>>> set up at bind time and 'seq' at probe time. The idea is that devices
>>>>>>>>> can 'request' a sequence number and then the conflicts are resolved
>>>>>>>>> when
>>>>>>>>> the device is probed.
>>>>>>>>>
>>>>>>>>> This makes things complicated in a few cases, since we don't really
>>>>>>>>> know
>>>>>>>>> (at bind time) what the sequence number will end up being. We want to
>>>>>>>>> honour the bind-time requests if at all possible, but in fact the only
>>>>>>>>> source of these at present is the devicetree aliases.
>>>>>>>>>
>>>>>>>>> Apart from the obvious need for sequence numbers to supports U-Boot's
>>>>>>>>> numbering on devices on the command line, the current scheme was
>>>>>>>>> designed to:
>>>>>>>>>
>>>>>>>>> - avoid calculating the sequence number until it is needed, to save
>>>>>>>>>    execution time
>>>>>>>>> - allow multiple devices to obtain a particular sequence number as
>>>>>>>> they
>>>>>>>>>    are probed and removed
>>>>>>>>> - retain a record of the 'requested' sequence number even if it turns
>>>>>>>>> out
>>>>>>>>>    that a device could not get it (to allow debugging and retrying)
>>>>>>>>>
>>>>>>>>> After some years using the current scheme it seems on balance that
>>>>>>>>> these
>>>>>>>>> goals don't have as much merit as first thought. The first point would
>>>>>>>>> be persuasive except that we end up reading the devicetree aliases at
>>>>>>>>> bind-time anyway. So the work of resolving the sequence numbers during
>>>>>>>>> probing is not that great. The second point hasn't really been an
>>>>>>>>> issue,
>>>>>>>>> as there is typically no contention for sequence numbers (boards tend
>>>>>>>>> to
>>>>>>>>> allocate them statically in the devicetree). Re the third point, we
>>>>>>>> can
>>>>>>>>> often figure out what was requested by looking at aliases, and in the
>>>>>>>>> cases where we can't, it doesn't seem to matter much.
>>>>>>>>>
>>>>>>>>> Since we have the devicetree available at bind time, we may as well
>>>>>>>>> just
>>>>>>>>> use it, in the hope that the required processing will turn out to be
>>>>>>>>> useful later (i.e. the device actually gets used). In addition, it is
>>>>>>>>> simpler to use a single sequence number, since it avoids confusion and
>>>>>>>>> some extra code.
>>>>>>>>>
>>>>>>>>> This series moves U-Boot to use a single, bind-time sequence number.
>>>>>>>>> All
>>>>>>>>> uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign
>>>>>>>>> sequence
>>>>>>>>> numbers to their devices, so that as soon as a device is bound, it has
>>>>>>>>> a
>>>>>>>>> sequence number. If a devicetree alias provides the number, it will be
>>>>>>>>> used. Otherwise, during initial binding, the first free number is
>>>>>>>> used.
>>>>>>>>
>>>>>>>> What does "first free number mean"?
>>>>>>>>
>>>>>>>> I have a device tree with the following aliases for network:
>>>>>>>>
>>>>>>>> aliases {
>>>>>>>>           ethernet0 = &enetc0;
>>>>>>>>           ethernet1 = &enetc1;
>>>>>>>>           ethernet2 = &enetc2;
>>>>>>>>           ethernet3 = &enetc6;
>>>>>>>> };
>>>>>>>>
>>>>>>>> The individual devices might be disabled, depending on the board variant
>>>>>>>> (which might also be dynamically determined during startup).
>>>>>>>
>>>>>>> By disabled, do you mean that they are marked 'status = "disabled"'?
>>>>>>
>>>>>> yes
>>>>>>
>>>>>>> If so, then they are ignored by DM and will not claim their number.
>>>>>>>
>>>>>>>>
>>>>>>>> My first smoke test with this series show the following:
>>>>>>>>
>>>>>>>>     uclass 32: eth
>>>>>>>>     0   * enetc-0 @ ffd40e60, seq 0
>>>>>>>>     1   * ax88179_eth @ ffd51f50, seq 1
>>>>>>>>
>>>>>>>> Looks like the usb ethernet device will get seq 1 assigned (after "usb
>>>>>>>> start"). Is this intended?
>>>>>>>>
>>>>>>>> If so, this is a problem, because for ethernet devices, the MAC address
>>>>>>>> is assigned according to the ethNaddr variable. And at least for this
>>>>>>>> board (kontron_sl28) the first four are reserved for the ones with the
>>>>>>>> alias entries. Thus I'd have expected that the usb device will get seq 4
>>>>>>>> assigned.
>>>>>>>
>>>>>>> OK, so you mean after all existing aliases, even if they did not bind.
>>>>>>> I think we can do that.
>>>>>>
>>>>>> Great, that will also match the current behavior. See
>>>>>> be1a6e94254af205bd67d69e3bdb26b161ccd72f ("dm: uclass: don't assign
>>>>>> aliased seq numbers")
>>>>>
>>>>> Also take a look at 83e4c7e9ffa57fe4116967999c223c952a46a78a
>>>>> which is more or less the same things as is done in linux
>>>>> by351d224f64afc1b3b359a1738b7d4600c7e64061
>>>>>
>>>>> And we are using it for i2c subsystem.
>>>>>
>>>>> If you look at Linux kernel i2c/spi subsystems they are using it for
>>>>> quite a while. Recently mmc subsystem starts to use it.
>>>>> On the other hand we had similar discussion around networking and it has
>>>>> never started to be used.
>>>>>
>>>>> In general make sense if you have uclass that it is recorded(based on
>>>>> aliases) the first highest free ID and start to use it for devices which
>>>>> are not listed or don't have record in aliases.
>>>>>
>>>>> That's IMHO the best predictable behavior we could reach. If you care
>>>>> about numbering scheme then your device should have alias.
>>>>>
>>>>> Also if there are devices which doesn't have alias keyword we should
>>>>> work with DT guys to get it listed in the spec.
>>>>
>>>> Do you mean the root of the name (e.g. i2c for i2c1)?
>>>
>>> yes assigned the root of the name to specific uclass.
>>
>> Oh gosh, I didn't even know they were in the DT spec.
>
> In DT spec you have recommended node names which is more or less fit
> with uclasses.
>
>
>>>
>>>>
>>>> Also has there been any discussion of using phandles instead of
>>>> strings? Perhaps we could create a new node with that approach.
>>>
>>> What do you mean by string?
>>> Aliases are not using phandles. It is just label converted to path.
>>> for example from dtc -I dtb -O dts.
>>>
>>>          aliases {
>>>                  ethernet0 = "/amba_pl/ethernet at 40c00000";
>>>                  i2c0 = "/amba_pl/i2c at 40800000";
>>>                  serial0 = "/amba_pl/serial at 40600000";
>>>          };
>>
>> Yes that's my point. It uses strings, which is inefficient. I feel we
>> could use phandles instead and solve a number of problems.
>
> If you want to change it we can't change it in one project only. And
> this discussion should be made against DT specification.
> Another thing is that that Linux is not capable to update aliases when
> for example DT overlay is applied. This part is completely ignored even
> if there is no collision. Nothing important for U-Boot but something to
> keep in mind.
> IIRC We don't support run time overlay applying to be able to add more
> nodes (but would be useful to have it too).

https://lkml.org/lkml/2016/12/20/510
[PATCH 0/4 v2] of/overlay: sysfs based ABI for dt overlays
suggested a mechanism to do so but was not merged.

Best regards

Heinrich

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

* [PATCH 00/27] dm: Change the way sequence numbers are implemented
  2020-12-11  7:42                 ` Heinrich Schuchardt
@ 2020-12-11  7:53                   ` Michal Simek
  2020-12-11 16:24                     ` Simon Glass
  0 siblings, 1 reply; 50+ messages in thread
From: Michal Simek @ 2020-12-11  7:53 UTC (permalink / raw)
  To: u-boot



On 11. 12. 20 8:42, Heinrich Schuchardt wrote:
> On 12/11/20 8:28 AM, Michal Simek wrote:
>> Hi Simon,
>>
>> On 10. 12. 20 18:46, Simon Glass wrote:
>>> Hi Michal,
>>>
>>> On Thu, 10 Dec 2020 at 10:33, Michal Simek <michal.simek@xilinx.com>
>>> wrote:
>>>>
>>>> Hi Simon,
>>>>
>>>> On 10. 12. 20 18:27, Simon Glass wrote:
>>>>> Hi Michal,
>>>>>
>>>>> On Thu, 10 Dec 2020 at 00:34, Michal Simek
>>>>> <michal.simek@xilinx.com> wrote:
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On 09. 12. 20 17:30, Michael Walle wrote:
>>>>>>> Hi Simon,
>>>>>>>
>>>>>>> Am 2020-12-09 17:23, schrieb Simon Glass:
>>>>>>>> On Tue, 8 Dec 2020 at 15:52, Michael Walle <michael@walle.cc>
>>>>>>>> wrote:
>>>>>>>>> Am 2020-11-30 02:53, schrieb Simon Glass:
>>>>>>>>>> At present each device has two sequence numbers, with
>>>>>>>>>> 'req_seq' being
>>>>>>>>>> set up at bind time and 'seq' at probe time. The idea is that
>>>>>>>>>> devices
>>>>>>>>>> can 'request' a sequence number and then the conflicts are
>>>>>>>>>> resolved
>>>>>>>>>> when
>>>>>>>>>> the device is probed.
>>>>>>>>>>
>>>>>>>>>> This makes things complicated in a few cases, since we don't
>>>>>>>>>> really
>>>>>>>>>> know
>>>>>>>>>> (at bind time) what the sequence number will end up being. We
>>>>>>>>>> want to
>>>>>>>>>> honour the bind-time requests if at all possible, but in fact
>>>>>>>>>> the only
>>>>>>>>>> source of these at present is the devicetree aliases.
>>>>>>>>>>
>>>>>>>>>> Apart from the obvious need for sequence numbers to supports
>>>>>>>>>> U-Boot's
>>>>>>>>>> numbering on devices on the command line, the current scheme was
>>>>>>>>>> designed to:
>>>>>>>>>>
>>>>>>>>>> - avoid calculating the sequence number until it is needed, to
>>>>>>>>>> save
>>>>>>>>>> ?? execution time
>>>>>>>>>> - allow multiple devices to obtain a particular sequence
>>>>>>>>>> number as
>>>>>>>>> they
>>>>>>>>>> ?? are probed and removed
>>>>>>>>>> - retain a record of the 'requested' sequence number even if
>>>>>>>>>> it turns
>>>>>>>>>> out
>>>>>>>>>> ?? that a device could not get it (to allow debugging and
>>>>>>>>>> retrying)
>>>>>>>>>>
>>>>>>>>>> After some years using the current scheme it seems on balance
>>>>>>>>>> that
>>>>>>>>>> these
>>>>>>>>>> goals don't have as much merit as first thought. The first
>>>>>>>>>> point would
>>>>>>>>>> be persuasive except that we end up reading the devicetree
>>>>>>>>>> aliases at
>>>>>>>>>> bind-time anyway. So the work of resolving the sequence
>>>>>>>>>> numbers during
>>>>>>>>>> probing is not that great. The second point hasn't really been an
>>>>>>>>>> issue,
>>>>>>>>>> as there is typically no contention for sequence numbers
>>>>>>>>>> (boards tend
>>>>>>>>>> to
>>>>>>>>>> allocate them statically in the devicetree). Re the third
>>>>>>>>>> point, we
>>>>>>>>> can
>>>>>>>>>> often figure out what was requested by looking at aliases, and
>>>>>>>>>> in the
>>>>>>>>>> cases where we can't, it doesn't seem to matter much.
>>>>>>>>>>
>>>>>>>>>> Since we have the devicetree available at bind time, we may as
>>>>>>>>>> well
>>>>>>>>>> just
>>>>>>>>>> use it, in the hope that the required processing will turn out
>>>>>>>>>> to be
>>>>>>>>>> useful later (i.e. the device actually gets used). In
>>>>>>>>>> addition, it is
>>>>>>>>>> simpler to use a single sequence number, since it avoids
>>>>>>>>>> confusion and
>>>>>>>>>> some extra code.
>>>>>>>>>>
>>>>>>>>>> This series moves U-Boot to use a single, bind-time sequence
>>>>>>>>>> number.
>>>>>>>>>> All
>>>>>>>>>> uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign
>>>>>>>>>> sequence
>>>>>>>>>> numbers to their devices, so that as soon as a device is
>>>>>>>>>> bound, it has
>>>>>>>>>> a
>>>>>>>>>> sequence number. If a devicetree alias provides the number, it
>>>>>>>>>> will be
>>>>>>>>>> used. Otherwise, during initial binding, the first free number is
>>>>>>>>> used.
>>>>>>>>>
>>>>>>>>> What does "first free number mean"?
>>>>>>>>>
>>>>>>>>> I have a device tree with the following aliases for network:
>>>>>>>>>
>>>>>>>>> aliases {
>>>>>>>>> ????????? ethernet0 = &enetc0;
>>>>>>>>> ????????? ethernet1 = &enetc1;
>>>>>>>>> ????????? ethernet2 = &enetc2;
>>>>>>>>> ????????? ethernet3 = &enetc6;
>>>>>>>>> };
>>>>>>>>>
>>>>>>>>> The individual devices might be disabled, depending on the
>>>>>>>>> board variant
>>>>>>>>> (which might also be dynamically determined during startup).
>>>>>>>>
>>>>>>>> By disabled, do you mean that they are marked 'status =
>>>>>>>> "disabled"'?
>>>>>>>
>>>>>>> yes
>>>>>>>
>>>>>>>> If so, then they are ignored by DM and will not claim their number.
>>>>>>>>
>>>>>>>>>
>>>>>>>>> My first smoke test with this series show the following:
>>>>>>>>>
>>>>>>>>> ??? uclass 32: eth
>>>>>>>>> ??? 0?? * enetc-0 @ ffd40e60, seq 0
>>>>>>>>> ??? 1?? * ax88179_eth @ ffd51f50, seq 1
>>>>>>>>>
>>>>>>>>> Looks like the usb ethernet device will get seq 1 assigned
>>>>>>>>> (after "usb
>>>>>>>>> start"). Is this intended?
>>>>>>>>>
>>>>>>>>> If so, this is a problem, because for ethernet devices, the MAC
>>>>>>>>> address
>>>>>>>>> is assigned according to the ethNaddr variable. And at least
>>>>>>>>> for this
>>>>>>>>> board (kontron_sl28) the first four are reserved for the ones
>>>>>>>>> with the
>>>>>>>>> alias entries. Thus I'd have expected that the usb device will
>>>>>>>>> get seq 4
>>>>>>>>> assigned.
>>>>>>>>
>>>>>>>> OK, so you mean after all existing aliases, even if they did not
>>>>>>>> bind.
>>>>>>>> I think we can do that.
>>>>>>>
>>>>>>> Great, that will also match the current behavior. See
>>>>>>> be1a6e94254af205bd67d69e3bdb26b161ccd72f ("dm: uclass: don't assign
>>>>>>> aliased seq numbers")
>>>>>>
>>>>>> Also take a look at 83e4c7e9ffa57fe4116967999c223c952a46a78a
>>>>>> which is more or less the same things as is done in linux
>>>>>> by351d224f64afc1b3b359a1738b7d4600c7e64061
>>>>>>
>>>>>> And we are using it for i2c subsystem.
>>>>>>
>>>>>> If you look at Linux kernel i2c/spi subsystems they are using it for
>>>>>> quite a while. Recently mmc subsystem starts to use it.
>>>>>> On the other hand we had similar discussion around networking and
>>>>>> it has
>>>>>> never started to be used.
>>>>>>
>>>>>> In general make sense if you have uclass that it is recorded(based on
>>>>>> aliases) the first highest free ID and start to use it for devices
>>>>>> which
>>>>>> are not listed or don't have record in aliases.
>>>>>>
>>>>>> That's IMHO the best predictable behavior we could reach. If you care
>>>>>> about numbering scheme then your device should have alias.
>>>>>>
>>>>>> Also if there are devices which doesn't have alias keyword we should
>>>>>> work with DT guys to get it listed in the spec.
>>>>>
>>>>> Do you mean the root of the name (e.g. i2c for i2c1)?
>>>>
>>>> yes assigned the root of the name to specific uclass.
>>>
>>> Oh gosh, I didn't even know they were in the DT spec.
>>
>> In DT spec you have recommended node names which is more or less fit
>> with uclasses.
>>
>>
>>>>
>>>>>
>>>>> Also has there been any discussion of using phandles instead of
>>>>> strings? Perhaps we could create a new node with that approach.
>>>>
>>>> What do you mean by string?
>>>> Aliases are not using phandles. It is just label converted to path.
>>>> for example from dtc -I dtb -O dts.
>>>>
>>>> ???????? aliases {
>>>> ???????????????? ethernet0 = "/amba_pl/ethernet at 40c00000";
>>>> ???????????????? i2c0 = "/amba_pl/i2c at 40800000";
>>>> ???????????????? serial0 = "/amba_pl/serial at 40600000";
>>>> ???????? };
>>>
>>> Yes that's my point. It uses strings, which is inefficient. I feel we
>>> could use phandles instead and solve a number of problems.
>>
>> If you want to change it we can't change it in one project only. And
>> this discussion should be made against DT specification.
>> Another thing is that that Linux is not capable to update aliases when
>> for example DT overlay is applied. This part is completely ignored even
>> if there is no collision. Nothing important for U-Boot but something to
>> keep in mind.
>> IIRC We don't support run time overlay applying to be able to add more
>> nodes (but would be useful to have it too).
> 
> https://lkml.org/lkml/2016/12/20/510
> [PATCH 0/4 v2] of/overlay: sysfs based ABI for dt overlays
> suggested a mechanism to do so but was not merged.

The last sentence was more for u-boot run time overlay support
especially useful for SOMs.

Thanks,
Michal

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

* [PATCH 00/27] dm: Change the way sequence numbers are implemented
  2020-12-11  7:53                   ` Michal Simek
@ 2020-12-11 16:24                     ` Simon Glass
  0 siblings, 0 replies; 50+ messages in thread
From: Simon Glass @ 2020-12-11 16:24 UTC (permalink / raw)
  To: u-boot

Hi Michal, Heinrich,

On Fri, 11 Dec 2020 at 00:54, Michal Simek <michal.simek@xilinx.com> wrote:
>
>
>
> On 11. 12. 20 8:42, Heinrich Schuchardt wrote:
> > On 12/11/20 8:28 AM, Michal Simek wrote:
> >> Hi Simon,
> >>
> >> On 10. 12. 20 18:46, Simon Glass wrote:
> >>> Hi Michal,
> >>>
> >>> On Thu, 10 Dec 2020 at 10:33, Michal Simek <michal.simek@xilinx.com>
> >>> wrote:
> >>>>
> >>>> Hi Simon,
> >>>>
> >>>> On 10. 12. 20 18:27, Simon Glass wrote:
> >>>>> Hi Michal,
> >>>>>
> >>>>> On Thu, 10 Dec 2020 at 00:34, Michal Simek
> >>>>> <michal.simek@xilinx.com> wrote:
> >>>>>>
> >>>>>> Hi,
> >>>>>>
> >>>>>> On 09. 12. 20 17:30, Michael Walle wrote:
> >>>>>>> Hi Simon,
> >>>>>>>
> >>>>>>> Am 2020-12-09 17:23, schrieb Simon Glass:
> >>>>>>>> On Tue, 8 Dec 2020 at 15:52, Michael Walle <michael@walle.cc>
> >>>>>>>> wrote:
> >>>>>>>>> Am 2020-11-30 02:53, schrieb Simon Glass:
> >>>>>>>>>> At present each device has two sequence numbers, with
> >>>>>>>>>> 'req_seq' being
> >>>>>>>>>> set up at bind time and 'seq' at probe time. The idea is that
> >>>>>>>>>> devices
> >>>>>>>>>> can 'request' a sequence number and then the conflicts are
> >>>>>>>>>> resolved
> >>>>>>>>>> when
> >>>>>>>>>> the device is probed.
> >>>>>>>>>>
> >>>>>>>>>> This makes things complicated in a few cases, since we don't
> >>>>>>>>>> really
> >>>>>>>>>> know
> >>>>>>>>>> (at bind time) what the sequence number will end up being. We
> >>>>>>>>>> want to
> >>>>>>>>>> honour the bind-time requests if at all possible, but in fact
> >>>>>>>>>> the only
> >>>>>>>>>> source of these at present is the devicetree aliases.
> >>>>>>>>>>
> >>>>>>>>>> Apart from the obvious need for sequence numbers to supports
> >>>>>>>>>> U-Boot's
> >>>>>>>>>> numbering on devices on the command line, the current scheme was
> >>>>>>>>>> designed to:
> >>>>>>>>>>
> >>>>>>>>>> - avoid calculating the sequence number until it is needed, to
> >>>>>>>>>> save
> >>>>>>>>>>    execution time
> >>>>>>>>>> - allow multiple devices to obtain a particular sequence
> >>>>>>>>>> number as
> >>>>>>>>> they
> >>>>>>>>>>    are probed and removed
> >>>>>>>>>> - retain a record of the 'requested' sequence number even if
> >>>>>>>>>> it turns
> >>>>>>>>>> out
> >>>>>>>>>>    that a device could not get it (to allow debugging and
> >>>>>>>>>> retrying)
> >>>>>>>>>>
> >>>>>>>>>> After some years using the current scheme it seems on balance
> >>>>>>>>>> that
> >>>>>>>>>> these
> >>>>>>>>>> goals don't have as much merit as first thought. The first
> >>>>>>>>>> point would
> >>>>>>>>>> be persuasive except that we end up reading the devicetree
> >>>>>>>>>> aliases at
> >>>>>>>>>> bind-time anyway. So the work of resolving the sequence
> >>>>>>>>>> numbers during
> >>>>>>>>>> probing is not that great. The second point hasn't really been an
> >>>>>>>>>> issue,
> >>>>>>>>>> as there is typically no contention for sequence numbers
> >>>>>>>>>> (boards tend
> >>>>>>>>>> to
> >>>>>>>>>> allocate them statically in the devicetree). Re the third
> >>>>>>>>>> point, we
> >>>>>>>>> can
> >>>>>>>>>> often figure out what was requested by looking at aliases, and
> >>>>>>>>>> in the
> >>>>>>>>>> cases where we can't, it doesn't seem to matter much.
> >>>>>>>>>>
> >>>>>>>>>> Since we have the devicetree available at bind time, we may as
> >>>>>>>>>> well
> >>>>>>>>>> just
> >>>>>>>>>> use it, in the hope that the required processing will turn out
> >>>>>>>>>> to be
> >>>>>>>>>> useful later (i.e. the device actually gets used). In
> >>>>>>>>>> addition, it is
> >>>>>>>>>> simpler to use a single sequence number, since it avoids
> >>>>>>>>>> confusion and
> >>>>>>>>>> some extra code.
> >>>>>>>>>>
> >>>>>>>>>> This series moves U-Boot to use a single, bind-time sequence
> >>>>>>>>>> number.
> >>>>>>>>>> All
> >>>>>>>>>> uclasses with the DM_UC_FLAG_SEQ_ALIAS flag enabled will assign
> >>>>>>>>>> sequence
> >>>>>>>>>> numbers to their devices, so that as soon as a device is
> >>>>>>>>>> bound, it has
> >>>>>>>>>> a
> >>>>>>>>>> sequence number. If a devicetree alias provides the number, it
> >>>>>>>>>> will be
> >>>>>>>>>> used. Otherwise, during initial binding, the first free number is
> >>>>>>>>> used.
> >>>>>>>>>
> >>>>>>>>> What does "first free number mean"?
> >>>>>>>>>
> >>>>>>>>> I have a device tree with the following aliases for network:
> >>>>>>>>>
> >>>>>>>>> aliases {
> >>>>>>>>>           ethernet0 = &enetc0;
> >>>>>>>>>           ethernet1 = &enetc1;
> >>>>>>>>>           ethernet2 = &enetc2;
> >>>>>>>>>           ethernet3 = &enetc6;
> >>>>>>>>> };
> >>>>>>>>>
> >>>>>>>>> The individual devices might be disabled, depending on the
> >>>>>>>>> board variant
> >>>>>>>>> (which might also be dynamically determined during startup).
> >>>>>>>>
> >>>>>>>> By disabled, do you mean that they are marked 'status =
> >>>>>>>> "disabled"'?
> >>>>>>>
> >>>>>>> yes
> >>>>>>>
> >>>>>>>> If so, then they are ignored by DM and will not claim their number.
> >>>>>>>>
> >>>>>>>>>
> >>>>>>>>> My first smoke test with this series show the following:
> >>>>>>>>>
> >>>>>>>>>     uclass 32: eth
> >>>>>>>>>     0   * enetc-0 @ ffd40e60, seq 0
> >>>>>>>>>     1   * ax88179_eth @ ffd51f50, seq 1
> >>>>>>>>>
> >>>>>>>>> Looks like the usb ethernet device will get seq 1 assigned
> >>>>>>>>> (after "usb
> >>>>>>>>> start"). Is this intended?
> >>>>>>>>>
> >>>>>>>>> If so, this is a problem, because for ethernet devices, the MAC
> >>>>>>>>> address
> >>>>>>>>> is assigned according to the ethNaddr variable. And at least
> >>>>>>>>> for this
> >>>>>>>>> board (kontron_sl28) the first four are reserved for the ones
> >>>>>>>>> with the
> >>>>>>>>> alias entries. Thus I'd have expected that the usb device will
> >>>>>>>>> get seq 4
> >>>>>>>>> assigned.
> >>>>>>>>
> >>>>>>>> OK, so you mean after all existing aliases, even if they did not
> >>>>>>>> bind.
> >>>>>>>> I think we can do that.
> >>>>>>>
> >>>>>>> Great, that will also match the current behavior. See
> >>>>>>> be1a6e94254af205bd67d69e3bdb26b161ccd72f ("dm: uclass: don't assign
> >>>>>>> aliased seq numbers")
> >>>>>>
> >>>>>> Also take a look at 83e4c7e9ffa57fe4116967999c223c952a46a78a
> >>>>>> which is more or less the same things as is done in linux
> >>>>>> by351d224f64afc1b3b359a1738b7d4600c7e64061
> >>>>>>
> >>>>>> And we are using it for i2c subsystem.
> >>>>>>
> >>>>>> If you look at Linux kernel i2c/spi subsystems they are using it for
> >>>>>> quite a while. Recently mmc subsystem starts to use it.
> >>>>>> On the other hand we had similar discussion around networking and
> >>>>>> it has
> >>>>>> never started to be used.
> >>>>>>
> >>>>>> In general make sense if you have uclass that it is recorded(based on
> >>>>>> aliases) the first highest free ID and start to use it for devices
> >>>>>> which
> >>>>>> are not listed or don't have record in aliases.
> >>>>>>
> >>>>>> That's IMHO the best predictable behavior we could reach. If you care
> >>>>>> about numbering scheme then your device should have alias.
> >>>>>>
> >>>>>> Also if there are devices which doesn't have alias keyword we should
> >>>>>> work with DT guys to get it listed in the spec.
> >>>>>
> >>>>> Do you mean the root of the name (e.g. i2c for i2c1)?
> >>>>
> >>>> yes assigned the root of the name to specific uclass.
> >>>
> >>> Oh gosh, I didn't even know they were in the DT spec.
> >>
> >> In DT spec you have recommended node names which is more or less fit
> >> with uclasses.
> >>
> >>
> >>>>
> >>>>>
> >>>>> Also has there been any discussion of using phandles instead of
> >>>>> strings? Perhaps we could create a new node with that approach.
> >>>>
> >>>> What do you mean by string?
> >>>> Aliases are not using phandles. It is just label converted to path.
> >>>> for example from dtc -I dtb -O dts.
> >>>>
> >>>>          aliases {
> >>>>                  ethernet0 = "/amba_pl/ethernet at 40c00000";
> >>>>                  i2c0 = "/amba_pl/i2c at 40800000";
> >>>>                  serial0 = "/amba_pl/serial at 40600000";
> >>>>          };
> >>>
> >>> Yes that's my point. It uses strings, which is inefficient. I feel we
> >>> could use phandles instead and solve a number of problems.
> >>
> >> If you want to change it we can't change it in one project only. And
> >> this discussion should be made against DT specification.
> >> Another thing is that that Linux is not capable to update aliases when
> >> for example DT overlay is applied. This part is completely ignored even
> >> if there is no collision. Nothing important for U-Boot but something to
> >> keep in mind.
> >> IIRC We don't support run time overlay applying to be able to add more
> >> nodes (but would be useful to have it too).
> >
> > https://lkml.org/lkml/2016/12/20/510
> > [PATCH 0/4 v2] of/overlay: sysfs based ABI for dt overlays
> > suggested a mechanism to do so but was not merged.
>
> The last sentence was more for u-boot run time overlay support
> especially useful for SOMs.

Thanks for the background. I think I will have a look at it and ask on
the DT side.

Regards,
Simon

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

end of thread, other threads:[~2020-12-11 16:24 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-30  1:53 [PATCH 00/27] dm: Change the way sequence numbers are implemented Simon Glass
2020-11-30  1:53 ` [PATCH 01/27] linker_lists: Fix alignment issue Simon Glass
2020-11-30  6:20   ` Heinrich Schuchardt
2020-11-30 20:11     ` Simon Glass
2020-11-30 22:56       ` Heinrich Schuchardt
2020-12-01 15:58         ` Simon Glass
2020-12-09 18:22           ` Heinrich Schuchardt
2020-12-10 19:26             ` Simon Glass
2020-11-30  1:53 ` [PATCH 02/27] efi: Drop unwanted message in efi_uc_destroy() Simon Glass
2020-12-01  8:04   ` Heinrich Schuchardt
2020-11-30  1:53 ` [PATCH 03/27] dm: Avoid accessing seq directly Simon Glass
2020-11-30  1:53 ` [PATCH 04/27] dm: core: Update uclass_find_next_free_req_seq() args Simon Glass
2020-11-30  1:53 ` [PATCH 05/27] dm: core: Add a new sequence number for devices Simon Glass
2020-11-30  1:53 ` [PATCH 06/27] dm: test: Add support for new sequence numbers Simon Glass
2020-11-30  1:53 ` [PATCH 07/27] dm: core: Switch binding to use " Simon Glass
2020-11-30  1:53 ` [PATCH 08/27] dm: Fix return value in dev_read_alias_seq() Simon Glass
2020-11-30  1:53 ` [PATCH 09/27] dm: test: Drop assumptions of no sequence numbers Simon Glass
2020-11-30  1:53 ` [PATCH 10/27] octeon: Don't attempt to set the sequence number Simon Glass
2020-11-30  1:53 ` [PATCH 11/27] i2c: Update for new sequence numbers Simon Glass
2020-11-30  1:53 ` [PATCH 12/27] net: Update to use " Simon Glass
2020-11-30  1:53 ` [PATCH 13/27] pci: " Simon Glass
2020-11-30  1:53 ` [PATCH 14/27] spi: Update for " Simon Glass
2020-11-30  1:53 ` [PATCH 15/27] usb: ehci-mx6: Drop assignment of sequence number Simon Glass
2020-11-30  1:53 ` [PATCH 16/27] usb: Update for new sequence numbers Simon Glass
2020-11-30  1:53 ` [PATCH 17/27] x86: Drop unnecessary mp_init logic Simon Glass
2020-11-30  1:53 ` [PATCH 18/27] x86: Simplify acpi_device_infer_name() Simon Glass
2020-11-30  1:53 ` [PATCH 19/27] gpio: Update for new sequence numbers Simon Glass
2020-11-30  1:53 ` [PATCH 20/27] pinctrl: " Simon Glass
2020-11-30  1:53 ` [PATCH 21/27] dm: Switch over to use new sequence number for dev_seq() Simon Glass
2020-11-30  1:53 ` [PATCH 22/27] dm: Drop uclass_resolve_seq() Simon Glass
2020-11-30  1:53 ` [PATCH 23/27] dm: Drop the unused arg in uclass_find_device_by_seq() Simon Glass
2020-11-30  1:53 ` [PATCH 24/27] dm: core: Simplify uclass_find_next_free_req_seq() Simon Glass
2020-11-30  1:54 ` [PATCH 25/27] cmd: Drop use of old sequence numbers in commands Simon Glass
2020-11-30  1:54 ` [PATCH 26/27] dm: core: Drop seq and req_seq Simon Glass
2020-11-30  1:54 ` [PATCH 27/27] dm: Update documentation for new sequence numbers Simon Glass
2020-12-01  8:01 ` [PATCH 00/27] dm: Change the way sequence numbers are implemented Heinrich Schuchardt
2020-12-03  2:04   ` Simon Glass
2020-12-08 22:52 ` Michael Walle
2020-12-09 16:19   ` Tom Rini
2020-12-09 16:24     ` Simon Glass
2020-12-09 16:23   ` Simon Glass
2020-12-09 16:30     ` Michael Walle
2020-12-10  7:34       ` Michal Simek
2020-12-10 17:27         ` Simon Glass
2020-12-10 17:32           ` Michal Simek
2020-12-10 17:46             ` Simon Glass
2020-12-11  7:28               ` Michal Simek
2020-12-11  7:42                 ` Heinrich Schuchardt
2020-12-11  7:53                   ` Michal Simek
2020-12-11 16:24                     ` 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.