Before this patch is applied all i2c sub-buses are using number -1 and they can't be addresses(switch to). If all busses are listed in DT alias they will get proper numbers and U-Boot can work with them. In Linux buses which are not listed in DT alias get uniq number which starts from the first highest free ID.
This is the behavior on ZynqMP zcu100-revA before this patch is applied. Bus 0: i2c@ff020000 20: gpio@20, offset len 1, flags 0 21: gpio@21, offset len 1, flags 0 75: i2c-mux@75, offset len 1, flags 0 Bus -1: i2c@0 Bus -1: i2c@1 Bus -1: i2c@2 Bus 1: i2c@ff030000 74: i2c-mux@74, offset len 1, flags 0 75: i2c-mux@75, offset len 1, flags 0 Bus -1: i2c@0 Bus -1: i2c@1 Bus -1: i2c@2 Bus -1: i2c@3 Bus -1: i2c@4 Bus -1: i2c@0 Bus -1: i2c@1 Bus -1: i2c@2 Bus -1: i2c@3 Bus -1: i2c@4 Bus -1: i2c@5 Bus -1: i2c@6 Bus -1: i2c@7 When the patch is applied also i2c-mux busses are listed properly. ZynqMP> i2c bus Bus 0: i2c@ff020000 20: gpio@20, offset len 1, flags 0 21: gpio@21, offset len 1, flags 0 75: i2c-mux@75, offset len 1, flags 0 Bus 2: i2c@ff020000->i2c-mux@75->i2c@0 Bus 3: i2c@ff020000->i2c-mux@75->i2c@1 Bus 4: i2c@ff020000->i2c-mux@75->i2c@2 Bus 1: i2c@ff030000 (active 1) 74: i2c-mux@74, offset len 1, flags 0 75: i2c-mux@75, offset len 1, flags 0 Bus 5: i2c@ff030000->i2c-mux@74->i2c@0 (active 5) 54: generic_54, offset len 1, flags 0 Bus 6: i2c@ff030000->i2c-mux@74->i2c@1 Bus 7: i2c@ff030000->i2c-mux@74->i2c@2 Bus 8: i2c@ff030000->i2c-mux@74->i2c@3 Bus 9: i2c@ff030000->i2c-mux@74->i2c@4 Bus 10: i2c@ff030000->i2c-mux@75->i2c@0 Bus 11: i2c@ff030000->i2c-mux@75->i2c@1 Bus 12: i2c@ff030000->i2c-mux@75->i2c@2 Bus 13: i2c@ff030000->i2c-mux@75->i2c@3 Bus 14: i2c@ff030000->i2c-mux@75->i2c@4 Bus 15: i2c@ff030000->i2c-mux@75->i2c@5 Bus 16: i2c@ff030000->i2c-mux@75->i2c@6 Bus 17: i2c@ff030000->i2c-mux@75->i2c@7 Signed-off-by: Michal Simek <michal.si...@xilinx.com> --- zcu102-revA Before this patch applied for !DM case with static description ZynqMP> i2c bus Bus 0: zynq_0 Bus 1: zynq_0->PCA9544A@0x75:0 Bus 2: zynq_0->PCA9544A@0x75:1 Bus 3: zynq_0->PCA9544A@0x75:2 Bus 4: zynq_1 Bus 5: zynq_1->PCA9548@0x74:0 Bus 6: zynq_1->PCA9548@0x74:1 Bus 7: zynq_1->PCA9548@0x74:2 Bus 8: zynq_1->PCA9548@0x74:3 Bus 9: zynq_1->PCA9548@0x74:4 Bus 10: zynq_1->PCA9548@0x75:0 Bus 11: zynq_1->PCA9548@0x75:1 Bus 12: zynq_1->PCA9548@0x75:2 Bus 13: zynq_1->PCA9548@0x75:3 Bus 14: zynq_1->PCA9548@0x75:4 Bus 15: zynq_1->PCA9548@0x75:5 Bus 16: zynq_1->PCA9548@0x75:6 Bus 17: zynq_1->PCA9548@0x75:7 When Patch is applied with OF_LIVE - of_alias_get_highest_id() is used ZynqMP> i2c bus Bus 0: i2c@ff020000 75: i2c-mux@75, offset len 1, flags 0 Bus 2: i2c@ff020000->i2c-mux@75->i2c@0 Bus 3: i2c@ff020000->i2c-mux@75->i2c@1 Bus 4: i2c@ff020000->i2c-mux@75->i2c@2 Bus 1: i2c@ff030000 74: i2c-mux@74, offset len 1, flags 0 75: i2c-mux@75, offset len 1, flags 0 Bus 5: i2c@ff030000->i2c-mux@74->i2c@0 Bus 6: i2c@ff030000->i2c-mux@74->i2c@1 Bus 7: i2c@ff030000->i2c-mux@74->i2c@2 Bus 8: i2c@ff030000->i2c-mux@74->i2c@3 Bus 9: i2c@ff030000->i2c-mux@74->i2c@4 Bus 10: i2c@ff030000->i2c-mux@75->i2c@0 Bus 11: i2c@ff030000->i2c-mux@75->i2c@1 Bus 12: i2c@ff030000->i2c-mux@75->i2c@2 Bus 13: i2c@ff030000->i2c-mux@75->i2c@3 Bus 14: i2c@ff030000->i2c-mux@75->i2c@4 Bus 15: i2c@ff030000->i2c-mux@75->i2c@5 Bus 16: i2c@ff030000->i2c-mux@75->i2c@6 Bus 17: i2c@ff030000->i2c-mux@75->i2c@7 For !OF_LIVE - hardcoded number is used ZynqMP> i2c bus Bus 0: i2c@ff020000 75: i2c-mux@75, offset len 1, flags 0 Bus 21: i2c@ff020000->i2c-mux@75->i2c@0 Bus 22: i2c@ff020000->i2c-mux@75->i2c@1 Bus 23: i2c@ff020000->i2c-mux@75->i2c@2 Bus 1: i2c@ff030000 74: i2c-mux@74, offset len 1, flags 0 75: i2c-mux@75, offset len 1, flags 0 Bus 24: i2c@ff030000->i2c-mux@74->i2c@0 Bus 25: i2c@ff030000->i2c-mux@74->i2c@1 Bus 26: i2c@ff030000->i2c-mux@74->i2c@2 Bus 27: i2c@ff030000->i2c-mux@74->i2c@3 Bus 28: i2c@ff030000->i2c-mux@74->i2c@4 Bus 29: i2c@ff030000->i2c-mux@75->i2c@0 Bus 30: i2c@ff030000->i2c-mux@75->i2c@1 Bus 31: i2c@ff030000->i2c-mux@75->i2c@2 Bus 32: i2c@ff030000->i2c-mux@75->i2c@3 Bus 33: i2c@ff030000->i2c-mux@75->i2c@4 Bus 34: i2c@ff030000->i2c-mux@75->i2c@5 Bus 35: i2c@ff030000->i2c-mux@75->i2c@6 Bus 36: i2c@ff030000->i2c-mux@75->i2c@7 --- drivers/i2c/muxes/i2c-mux-uclass.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/muxes/i2c-mux-uclass.c b/drivers/i2c/muxes/i2c-mux-uclass.c index a680ee176253..cb69d053fd59 100644 --- a/drivers/i2c/muxes/i2c-mux-uclass.c +++ b/drivers/i2c/muxes/i2c-mux-uclass.c @@ -9,6 +9,7 @@ #include <errno.h> #include <i2c.h> #include <dm/lists.h> +#include <dm/of_access.h> #include <dm/root.h> /** @@ -59,13 +60,42 @@ static int i2c_mux_post_bind(struct udevice *mux) dev_for_each_subnode(node, mux) { struct udevice *dev; const char *name; + const char *arrow = "->"; + char *full_name; + int parent_name_len, arrow_len, mux_name_len, name_len; name = ofnode_get_name(node); - ret = device_bind_driver_to_node(mux, "i2c_mux_bus_drv", name, - node, &dev); + + /* Calculate lenghts of strings */ + parent_name_len = strlen(mux->parent->name); + arrow_len = strlen(arrow); + mux_name_len = strlen(mux->name); + name_len = strlen(name); + + full_name = calloc(1, parent_name_len + arrow_len + + mux_name_len + arrow_len + name_len + 1); + if (!full_name) + return -ENOMEM; + + /* Compose bus name */ + strcat(full_name, mux->parent->name); + strcat(full_name, arrow); + strcat(full_name, mux->name); + strcat(full_name, arrow); + strcat(full_name, name); + + ret = device_bind_driver_to_node(mux, "i2c_mux_bus_drv", + full_name, node, &dev); debug(" - bind ret=%d, %s\n", ret, dev ? dev->name : NULL); if (ret) return ret; + + /* If dt alias is not found start to allocate new IDs */ + if (dev->req_seq == -1) + dev->req_seq = ++i2c_highest_id; + + debug("%s: MUX bus %d: %s\n", __func__, dev->req_seq, + full_name); } return 0; @@ -192,6 +222,7 @@ U_BOOT_DRIVER(i2c_mux_bus) = { UCLASS_DRIVER(i2c_mux) = { .id = UCLASS_I2C_MUX, + .flags = DM_UC_FLAG_SEQ_ALIAS, .name = "i2c_mux", .post_bind = i2c_mux_post_bind, .post_probe = i2c_mux_post_probe, -- 1.9.1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot