
Hi Michal,
On Fri, 18 Jan 2019 at 08:13, Michal Simek michal.simek@xilinx.com wrote:
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.simek@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(-)
This is quite a complicated issue...
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);
Why do we use the full name here? We can create this by looking at the parents if needed.
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;
As in the other patch, if we change this, I think we should do it in DM core, by adjusting uclass_resolve_seq(). Would that work?
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
Also we have no i2c mux tests by the look of it, and should add a test to make sure this works on sandbox.
Regards, Simon