[PATCH 1/1] i2c: lpi2c: Avoid calling clk_get_rate during transfer
Uwe Kleine-König
u.kleine-koenig at pengutronix.de
Thu Jan 18 02:22:35 PST 2024
On Thu, Jan 18, 2024 at 08:43:32AM +0100, Alexander Stein wrote:
> Instead of repeatedly calling clk_get_rate for each transfer, lock
> the clock rate and cache the value.
> A deadlock has been observed while adding tlv320aic32x4 audio codec to
> the system. When this clock provider adds its clock, the clk mutex is
> locked already, it needs to access i2c, which in return needs the mutex
> for clk_get_rate as well.
>
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> ---
> This is an alternative, lightweight approach replacing the patch [1] and
> depends on [2].
> The issue to address is still removing the call to clk_get_rate() during each
> transfer, which might reuslt in a deadlock. lockdep also complains about this
> call chain.
>
> Instead of adding a clock notifier, lock the peripheral clock rate and cache
> the peripheral clock rate.
> Currently LPI2C is available in the following SoC:
> * i.MX7ULP
> * i.MX8ULP
> * i.MX8DXL
> * i.MX8X
> * i.MX8
> * i.MX93
>
> Additionally I expect both i.MX91 and i.MX95 to also use this driver.
>
> This patch assumes the parent clock rate never changes. This is apparently true
> for i.MX93 as each I2C has it's own lpi2c*_root clock. On i.MX8 and i.MX8X
> clocks are managed by SCU with it's own dedicated firmware. I can't say if the
> clock never changes though. I have no idea about the other SoC.
>
> Best regards,
> Alexander
>
> [1] https://lore.kernel.org/all/20240110120556.519800-1-alexander.stein@ew.tq-group.com/
> [2] https://lore.kernel.org/all/20240104225512.1124519-2-u.kleine-koenig@pengutronix.de/
>
> drivers/i2c/busses/i2c-imx-lpi2c.c | 17 ++++++++++++++++-
> 1 file changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
> index 678b30e90492a..6cbcb27a3b280 100644
> --- a/drivers/i2c/busses/i2c-imx-lpi2c.c
> +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
> @@ -99,6 +99,7 @@ struct lpi2c_imx_struct {
> __u8 *rx_buf;
> __u8 *tx_buf;
> struct completion complete;
> + unsigned long rate_per;
> unsigned int msglen;
> unsigned int delivered;
> unsigned int block_data;
> @@ -207,7 +208,7 @@ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx)
>
> lpi2c_imx_set_mode(lpi2c_imx);
>
> - clk_rate = clk_get_rate(lpi2c_imx->clks[0].clk);
> + clk_rate = lpi2c_imx->rate_per;
> if (!clk_rate)
> return -EINVAL;
After the things you did in lpi2c_imx_probe() you can assume that
clk_rate is not zero, so you could drop the if here.
Otherwise looks good to me (if you want even if you keep the if which is
only a minor optimisation).
Reviewed-by: Uwe Kleine-König <u.kleine-koenig at pengutronix.de>
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | https://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240118/db3b813c/attachment.sig>
More information about the linux-arm-kernel
mailing list