[PATCH] misc: scu: Remove child dev bind

Remove the child device binding codes for clk and iomux nodes, because the misc uclass has added such operation in post-bind. If we keep the codes in scu bind, child devices will be created twices. Find the problem by "dm uclass" command.
uclass 24: clk 0 * clk @ fce22380, seq 0, (req -1) 1 clk @ fce23110
uclass 67: pinctrl 0 * iomuxc @ fce22470, seq 0, (req -1) 1 iomuxc @ fce231c0
After the fix:
uclass 24: clk 0 * clk @ fce22380, seq 0, (req -1)
uclass 67: pinctrl 0 * iomuxc @ fce22470, seq 0, (req -1)
Signed-off-by: Ye Li ye.li@nxp.com Reviewed-by: Peng Fan peng.fan@nxp.com --- drivers/misc/imx8/scu.c | 12 ------------ 1 file changed, 12 deletions(-)
diff --git a/drivers/misc/imx8/scu.c b/drivers/misc/imx8/scu.c index ee635eb..cdf3052 100644 --- a/drivers/misc/imx8/scu.c +++ b/drivers/misc/imx8/scu.c @@ -212,18 +212,6 @@ static int imx8_scu_remove(struct udevice *dev)
static int imx8_scu_bind(struct udevice *dev) { - int ret; - struct udevice *child; - ofnode node; - - debug("%s(dev=%p)\n", __func__, dev); - ofnode_for_each_subnode(node, dev_ofnode(dev)) { - ret = lists_bind_fdt(dev, node, &child, true); - if (ret) - return ret; - debug("bind child dev %s\n", child->name); - } - return 0; }

Current driver calls the devfdt_get_addr to get the base address of lpi2c controller in each sub-functions. Since the devfdt_get_addr accesses the DTB and translate the address, it introduces much overhead. Improve the codes to use private variable which has recorded the base address from probe.
Signed-off-by: Ye Li ye.li@nxp.com Reviewed-by: Peng Fan peng.fan@nxp.com --- drivers/i2c/imx_lpi2c.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/i2c/imx_lpi2c.c b/drivers/i2c/imx_lpi2c.c index c8e42e0..b7b2aaf 100644 --- a/drivers/i2c/imx_lpi2c.c +++ b/drivers/i2c/imx_lpi2c.c @@ -97,7 +97,8 @@ static int bus_i2c_wait_for_tx_ready(struct imx_lpi2c_reg *regs)
static int bus_i2c_send(struct udevice *bus, u8 *txbuf, int len) { - struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)devfdt_get_addr(bus); + struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus); + struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base); lpi2c_status_t result = LPI2C_SUCESS;
/* empty tx */ @@ -118,7 +119,8 @@ static int bus_i2c_send(struct udevice *bus, u8 *txbuf, int len)
static int bus_i2c_receive(struct udevice *bus, u8 *rxbuf, int len) { - struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)devfdt_get_addr(bus); + struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus); + struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base); lpi2c_status_t result = LPI2C_SUCESS; u32 val; ulong start_time = get_timer(0); @@ -162,8 +164,8 @@ static int bus_i2c_receive(struct udevice *bus, u8 *rxbuf, int len) static int bus_i2c_start(struct udevice *bus, u8 addr, u8 dir) { lpi2c_status_t result; - struct imx_lpi2c_reg *regs = - (struct imx_lpi2c_reg *)devfdt_get_addr(bus); + struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus); + struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base); u32 val;
result = imx_lpci2c_check_busy_bus(regs); @@ -199,8 +201,8 @@ static int bus_i2c_start(struct udevice *bus, u8 addr, u8 dir) static int bus_i2c_stop(struct udevice *bus) { lpi2c_status_t result; - struct imx_lpi2c_reg *regs = - (struct imx_lpi2c_reg *)devfdt_get_addr(bus); + struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus); + struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base); u32 status; ulong start_time;
@@ -271,7 +273,7 @@ u32 __weak imx_get_i2cclk(u32 i2c_num) static int bus_i2c_set_bus_speed(struct udevice *bus, int speed) { struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus); - struct imx_lpi2c_reg *regs; + struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base); u32 val; u32 preescale = 0, best_pre = 0, clkhi = 0; u32 best_clkhi = 0, abs_error = 0, rate; @@ -280,8 +282,6 @@ static int bus_i2c_set_bus_speed(struct udevice *bus, int speed) bool mode; int i;
- regs = (struct imx_lpi2c_reg *)devfdt_get_addr(bus); - if (IS_ENABLED(CONFIG_CLK)) { clock_rate = clk_get_rate(&i2c_bus->per_clk); if (clock_rate <= 0) { @@ -348,11 +348,11 @@ static int bus_i2c_set_bus_speed(struct udevice *bus, int speed)
static int bus_i2c_init(struct udevice *bus, int speed) { - struct imx_lpi2c_reg *regs; u32 val; int ret;
- regs = (struct imx_lpi2c_reg *)devfdt_get_addr(bus); + struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus); + struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base); /* reset peripheral */ writel(LPI2C_MCR_RST_MASK, ®s->mcr); writel(0x0, ®s->mcr);

Hello Ye Li,
Am 10.06.2020 um 05:29 schrieb Ye Li:
Current driver calls the devfdt_get_addr to get the base address of lpi2c controller in each sub-functions. Since the devfdt_get_addr accesses the DTB and translate the address, it introduces much overhead. Improve the codes to use private variable which has recorded the base address from probe.
Signed-off-by: Ye Li ye.li@nxp.com Reviewed-by: Peng Fan peng.fan@nxp.com
drivers/i2c/imx_lpi2c.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
Applied to u-boot-i2c.git master
Thanks!
bye, Heiko

Current mxc_gpio DM driver allocates the platdata in bind function to handle both OF_CONTROL enabled case and disabled case. This implementation puts the devfdt_get_addr in bind, which introduces much overhead especially in board_f phase.
Change the driver to a common way for handling the cases by using ofdata_to_platdata and using DM framework to allocate platdata.
Signed-off-by: Ye Li ye.li@nxp.com Reviewed-by: Peng Fan peng.fan@nxp.com --- drivers/gpio/mxc_gpio.c | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-)
diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c index c924e52..a851893 100644 --- a/drivers/gpio/mxc_gpio.c +++ b/drivers/gpio/mxc_gpio.c @@ -292,46 +292,26 @@ static int mxc_gpio_probe(struct udevice *dev) return 0; }
-static int mxc_gpio_bind(struct udevice *dev) +static int mxc_gpio_ofdata_to_platdata(struct udevice *dev) { - struct mxc_gpio_plat *plat = dev->platdata; fdt_addr_t addr; - - /* - * If platdata already exsits, directly return. - * Actually only when DT is not supported, platdata - * is statically initialized in U_BOOT_DEVICES.Here - * will return. - */ - if (plat) - return 0; + struct mxc_gpio_plat *plat = dev_get_platdata(dev);
addr = devfdt_get_addr(dev); if (addr == FDT_ADDR_T_NONE) return -EINVAL;
- /* - * TODO: - * When every board is converted to driver model and DT is supported, - * this can be done by auto-alloc feature, but not using calloc - * to alloc memory for platdata. - * - * For example mxc_plat below uses platform data rather than device - * tree. - * - * NOTE: DO NOT COPY this code if you are using device tree. - */ - plat = calloc(1, sizeof(*plat)); - if (!plat) - return -ENOMEM; - plat->regs = (struct gpio_regs *)addr; plat->bank_index = dev->req_seq; - dev->platdata = plat;
return 0; }
+static int mxc_gpio_bind(struct udevice *dev) +{ + return 0; +} + static const struct udevice_id mxc_gpio_ids[] = { { .compatible = "fsl,imx35-gpio" }, { } @@ -342,6 +322,8 @@ U_BOOT_DRIVER(gpio_mxc) = { .id = UCLASS_GPIO, .ops = &gpio_mxc_ops, .probe = mxc_gpio_probe, + .ofdata_to_platdata = mxc_gpio_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct mxc_gpio_plat), .priv_auto_alloc_size = sizeof(struct mxc_bank_info), .of_match = mxc_gpio_ids, .bind = mxc_gpio_bind,

Current mxc_gpio DM driver allocates the platdata in bind function to handle both OF_CONTROL enabled case and disabled case. This implementation puts the devfdt_get_addr in bind, which introduces much overhead especially in board_f phase. Change the driver to a common way for handling the cases by using ofdata_to_platdata and using DM framework to allocate platdata. Signed-off-by: Ye Li ye.li@nxp.com Reviewed-by: Peng Fan peng.fan@nxp.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic
participants (3)
-
Heiko Schocher
-
sbabic@denx.de
-
Ye Li