* [PATCH v2 1/3] i2c: lpc2k: Add check for clk_enable()
@ 2024-11-05 16:18 Jiasheng Jiang
2024-11-05 16:18 ` [PATCH v2 2/3] i2c: pxa: Add check for clk_enable() and clk_prepare_enable() Jiasheng Jiang
2024-11-05 16:18 ` [PATCH v2 3/3] i2c: rk3x: Add check for clk_enable() Jiasheng Jiang
0 siblings, 2 replies; 6+ messages in thread
From: Jiasheng Jiang @ 2024-11-05 16:18 UTC (permalink / raw)
To: andi.shyti
Cc: rmk, max.schwarz, dianders, david.wu, heiko, vz, wsa, manabian,
linux-arm-kernel, linux-rockchip, linux-i2c, linux-kernel,
Jiasheng Jiang
Add check for the return value of clk_enable() in order to catch the
potential exception.
Signed-off-by: Jiasheng Jiang <jiashengjiangcool@gmail.com>
---
Changelog:
v1 -> v2:
1. Remove the Fixes tag.
2. Use dev_err_probe to simplify error handling.
---
drivers/i2c/busses/i2c-lpc2k.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-lpc2k.c b/drivers/i2c/busses/i2c-lpc2k.c
index 9fb33cbf7419..0fe7d4421a31 100644
--- a/drivers/i2c/busses/i2c-lpc2k.c
+++ b/drivers/i2c/busses/i2c-lpc2k.c
@@ -442,8 +442,12 @@ static int i2c_lpc2k_suspend(struct device *dev)
static int i2c_lpc2k_resume(struct device *dev)
{
struct lpc2k_i2c *i2c = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_enable(i2c->clk);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to enable clock: %d\n", ret);
- clk_enable(i2c->clk);
i2c_lpc2k_reset(i2c);
return 0;
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 2/3] i2c: pxa: Add check for clk_enable() and clk_prepare_enable()
2024-11-05 16:18 [PATCH v2 1/3] i2c: lpc2k: Add check for clk_enable() Jiasheng Jiang
@ 2024-11-05 16:18 ` Jiasheng Jiang
2024-11-05 16:18 ` [PATCH v2 3/3] i2c: rk3x: Add check for clk_enable() Jiasheng Jiang
1 sibling, 0 replies; 6+ messages in thread
From: Jiasheng Jiang @ 2024-11-05 16:18 UTC (permalink / raw)
To: andi.shyti
Cc: rmk, max.schwarz, dianders, david.wu, heiko, vz, wsa, manabian,
linux-arm-kernel, linux-rockchip, linux-i2c, linux-kernel,
Jiasheng Jiang
Add check for the return values of clk_enable() and clk_prepare_enable()
in order to catch the potential exceptions.
Signed-off-by: Jiasheng Jiang <jiashengjiangcool@gmail.com>
---
Changelog:
v1 -> v2:
1. Remove the Fixes tag.
2. Use dev_err_probe to simplify error handling.
---
drivers/i2c/busses/i2c-pxa.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 4d76e71cdd4b..0ee6fe83de40 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -1503,7 +1503,9 @@ static int i2c_pxa_probe(struct platform_device *dev)
i2c->adap.name);
}
- clk_prepare_enable(i2c->clk);
+ ret = clk_prepare_enable(i2c->clk);
+ if (ret)
+ return dev_err_probe(&dev->dev, ret, "failed to enable clock: %d\n", ret);
if (i2c->use_pio) {
i2c->adap.algo = &i2c_pxa_pio_algorithm;
@@ -1560,8 +1562,12 @@ static int i2c_pxa_suspend_noirq(struct device *dev)
static int i2c_pxa_resume_noirq(struct device *dev)
{
struct pxa_i2c *i2c = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_enable(i2c->clk);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to enable clock: %d\n", ret);
- clk_enable(i2c->clk);
i2c_pxa_reset(i2c);
return 0;
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 3/3] i2c: rk3x: Add check for clk_enable()
2024-11-05 16:18 [PATCH v2 1/3] i2c: lpc2k: Add check for clk_enable() Jiasheng Jiang
2024-11-05 16:18 ` [PATCH v2 2/3] i2c: pxa: Add check for clk_enable() and clk_prepare_enable() Jiasheng Jiang
@ 2024-11-05 16:18 ` Jiasheng Jiang
2024-11-05 21:29 ` Doug Anderson
1 sibling, 1 reply; 6+ messages in thread
From: Jiasheng Jiang @ 2024-11-05 16:18 UTC (permalink / raw)
To: andi.shyti
Cc: rmk, max.schwarz, dianders, david.wu, heiko, vz, wsa, manabian,
linux-arm-kernel, linux-rockchip, linux-i2c, linux-kernel,
Jiasheng Jiang
Add check for the return value of clk_enable() in order to catch the
potential exception. Moreover, convert the return type of
rk3x_i2c_adapt_div() into int and add the check.
Signed-off-by: Jiasheng Jiang <jiashengjiangcool@gmail.com>
---
Changelog:
v1 -> v2:
1. Remove the Fixes tag.
2. Use dev_err_probe to simplify error handling.
---
drivers/i2c/busses/i2c-rk3x.c | 51 +++++++++++++++++++++++++----------
1 file changed, 37 insertions(+), 14 deletions(-)
diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
index 4ef9bad77b85..57c2d37fc7c3 100644
--- a/drivers/i2c/busses/i2c-rk3x.c
+++ b/drivers/i2c/busses/i2c-rk3x.c
@@ -871,7 +871,7 @@ static int rk3x_i2c_v1_calc_timings(unsigned long clk_rate,
return ret;
}
-static void rk3x_i2c_adapt_div(struct rk3x_i2c *i2c, unsigned long clk_rate)
+static int rk3x_i2c_adapt_div(struct rk3x_i2c *i2c, unsigned long clk_rate)
{
struct i2c_timings *t = &i2c->t;
struct rk3x_i2c_calced_timings calc;
@@ -883,7 +883,9 @@ static void rk3x_i2c_adapt_div(struct rk3x_i2c *i2c, unsigned long clk_rate)
ret = i2c->soc_data->calc_timings(clk_rate, t, &calc);
WARN_ONCE(ret != 0, "Could not reach SCL freq %u", t->bus_freq_hz);
- clk_enable(i2c->pclk);
+ ret = clk_enable(i2c->pclk);
+ if (ret)
+ return dev_err_probe(i2c->dev, ret, "Can't enable bus clk for rk3399: %d\n", ret);
spin_lock_irqsave(&i2c->lock, flags);
val = i2c_readl(i2c, REG_CON);
@@ -904,6 +906,8 @@ static void rk3x_i2c_adapt_div(struct rk3x_i2c *i2c, unsigned long clk_rate)
clk_rate / 1000,
1000000000 / t->bus_freq_hz,
t_low_ns, t_high_ns);
+
+ return 0;
}
/**
@@ -942,19 +946,27 @@ static int rk3x_i2c_clk_notifier_cb(struct notifier_block *nb, unsigned long
return NOTIFY_STOP;
/* scale up */
- if (ndata->new_rate > ndata->old_rate)
- rk3x_i2c_adapt_div(i2c, ndata->new_rate);
+ if (ndata->new_rate > ndata->old_rate) {
+ if (rk3x_i2c_adapt_div(i2c, ndata->new_rate))
+ return NOTIFY_STOP;
+ }
return NOTIFY_OK;
case POST_RATE_CHANGE:
/* scale down */
- if (ndata->new_rate < ndata->old_rate)
- rk3x_i2c_adapt_div(i2c, ndata->new_rate);
+ if (ndata->new_rate < ndata->old_rate) {
+ if (rk3x_i2c_adapt_div(i2c, ndata->new_rate))
+ return NOTIFY_STOP;
+ }
+
return NOTIFY_OK;
case ABORT_RATE_CHANGE:
/* scale up */
- if (ndata->new_rate > ndata->old_rate)
- rk3x_i2c_adapt_div(i2c, ndata->old_rate);
+ if (ndata->new_rate > ndata->old_rate) {
+ if (rk3x_i2c_adapt_div(i2c, ndata->old_rate))
+ return NOTIFY_STOP;
+ }
+
return NOTIFY_OK;
default:
return NOTIFY_DONE;
@@ -1068,8 +1080,18 @@ static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
spin_lock_irqsave(&i2c->lock, flags);
- clk_enable(i2c->clk);
- clk_enable(i2c->pclk);
+ ret = clk_enable(i2c->clk);
+ if (ret) {
+ spin_unlock_irqrestore(&i2c->lock, flags);
+ return dev_err_probe(i2c->dev, ret, "Can't enable bus clk: %d\n", ret);
+ }
+
+ ret = clk_enable(i2c->pclk);
+ if (ret) {
+ clk_disable(i2c->clk);
+ spin_unlock_irqrestore(&i2c->lock, flags);
+ return dev_err_probe(i2c->dev, ret, "Can't enable bus clk for rk3399: %d\n", ret);
+ }
i2c->is_last_msg = false;
@@ -1149,9 +1171,7 @@ static __maybe_unused int rk3x_i2c_resume(struct device *dev)
{
struct rk3x_i2c *i2c = dev_get_drvdata(dev);
- rk3x_i2c_adapt_div(i2c, clk_get_rate(i2c->clk));
-
- return 0;
+ return rk3x_i2c_adapt_div(i2c, clk_get_rate(i2c->clk));
}
static u32 rk3x_i2c_func(struct i2c_adapter *adap)
@@ -1365,9 +1385,12 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
}
clk_rate = clk_get_rate(i2c->clk);
- rk3x_i2c_adapt_div(i2c, clk_rate);
+ ret = rk3x_i2c_adapt_div(i2c, clk_rate);
clk_disable(i2c->clk);
+ if (ret)
+ goto err_clk_notifier;
+
ret = i2c_add_adapter(&i2c->adap);
if (ret < 0)
goto err_clk_notifier;
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 3/3] i2c: rk3x: Add check for clk_enable()
2024-11-05 16:18 ` [PATCH v2 3/3] i2c: rk3x: Add check for clk_enable() Jiasheng Jiang
@ 2024-11-05 21:29 ` Doug Anderson
2024-11-06 23:01 ` Andi Shyti
0 siblings, 1 reply; 6+ messages in thread
From: Doug Anderson @ 2024-11-05 21:29 UTC (permalink / raw)
To: Jiasheng Jiang
Cc: andi.shyti, rmk, max.schwarz, david.wu, heiko, vz, wsa, manabian,
linux-arm-kernel, linux-rockchip, linux-i2c, linux-kernel
Hi,
On Tue, Nov 5, 2024 at 8:18 AM Jiasheng Jiang
<jiashengjiangcool@gmail.com> wrote:
>
> Add check for the return value of clk_enable() in order to catch the
> potential exception. Moreover, convert the return type of
> rk3x_i2c_adapt_div() into int and add the check.
>
> Signed-off-by: Jiasheng Jiang <jiashengjiangcool@gmail.com>
> ---
> Changelog:
>
> v1 -> v2:
>
> 1. Remove the Fixes tag.
> 2. Use dev_err_probe to simplify error handling.
> ---
> drivers/i2c/busses/i2c-rk3x.c | 51 +++++++++++++++++++++++++----------
> 1 file changed, 37 insertions(+), 14 deletions(-)
Wow, this is a whole lot of code to add to check for an error that
can't really happen as far as I'm aware. Turning on a clock is just
some MMIO writes and can't fail, right? Is this really worth it? Maybe
just wrap clk_enable() and spam an error to the logs if it fails? If
we ever see that error we can figure out what's going on and if
there's a sensible reason it could fail we could add the more complex
code.
> @@ -883,7 +883,9 @@ static void rk3x_i2c_adapt_div(struct rk3x_i2c *i2c, unsigned long clk_rate)
> ret = i2c->soc_data->calc_timings(clk_rate, t, &calc);
> WARN_ONCE(ret != 0, "Could not reach SCL freq %u", t->bus_freq_hz);
>
> - clk_enable(i2c->pclk);
> + ret = clk_enable(i2c->pclk);
> + if (ret)
> + return dev_err_probe(i2c->dev, ret, "Can't enable bus clk for rk3399: %d\n", ret);
Officially you're only supposed to use "dev_err_probe()" from probe or
calls indirectly called from probe. You're now using it in a whole lot
of other places.
...also note that dev_err_probe() already prints the error so you
don't need to include it in your error message.
> @@ -942,19 +946,27 @@ static int rk3x_i2c_clk_notifier_cb(struct notifier_block *nb, unsigned long
> return NOTIFY_STOP;
>
> /* scale up */
> - if (ndata->new_rate > ndata->old_rate)
> - rk3x_i2c_adapt_div(i2c, ndata->new_rate);
> + if (ndata->new_rate > ndata->old_rate) {
> + if (rk3x_i2c_adapt_div(i2c, ndata->new_rate))
> + return NOTIFY_STOP;
> + }
>
> return NOTIFY_OK;
> case POST_RATE_CHANGE:
> /* scale down */
> - if (ndata->new_rate < ndata->old_rate)
> - rk3x_i2c_adapt_div(i2c, ndata->new_rate);
> + if (ndata->new_rate < ndata->old_rate) {
> + if (rk3x_i2c_adapt_div(i2c, ndata->new_rate))
> + return NOTIFY_STOP;
> + }
> +
> return NOTIFY_OK;
> case ABORT_RATE_CHANGE:
> /* scale up */
> - if (ndata->new_rate > ndata->old_rate)
> - rk3x_i2c_adapt_div(i2c, ndata->old_rate);
> + if (ndata->new_rate > ndata->old_rate) {
> + if (rk3x_i2c_adapt_div(i2c, ndata->old_rate))
> + return NOTIFY_STOP;
I'm not convinced you can actually return NODIFY_STOP from the
POST_RATE_CHANGE or ABORT_RATE_CHANGE. Have you confirmed that is
actually sensible?
> @@ -1365,9 +1385,12 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
> }
>
> clk_rate = clk_get_rate(i2c->clk);
> - rk3x_i2c_adapt_div(i2c, clk_rate);
> + ret = rk3x_i2c_adapt_div(i2c, clk_rate);
> clk_disable(i2c->clk);
>
> + if (ret)
> + goto err_clk_notifier;
This one seems especially comical to add since the only way
rk3x_i2c_adapt_div() could fail would be if a nested clk_enable()
failed. ...and I'm 99% sure that's not possible.
-Doug
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 3/3] i2c: rk3x: Add check for clk_enable()
2024-11-05 21:29 ` Doug Anderson
@ 2024-11-06 23:01 ` Andi Shyti
2024-11-08 2:27 ` Jiasheng Jiang
0 siblings, 1 reply; 6+ messages in thread
From: Andi Shyti @ 2024-11-06 23:01 UTC (permalink / raw)
To: Doug Anderson
Cc: Jiasheng Jiang, rmk, max.schwarz, david.wu, heiko, vz, wsa,
manabian, linux-arm-kernel, linux-rockchip, linux-i2c,
linux-kernel
Hi Doug,
On Tue, Nov 05, 2024 at 01:29:40PM -0800, Doug Anderson wrote:
> On Tue, Nov 5, 2024 at 8:18 AM Jiasheng Jiang
> > Add check for the return value of clk_enable() in order to catch the
> > potential exception. Moreover, convert the return type of
> > rk3x_i2c_adapt_div() into int and add the check.
> >
> > Signed-off-by: Jiasheng Jiang <jiashengjiangcool@gmail.com>
> > ---
> > Changelog:
> >
> > v1 -> v2:
> >
> > 1. Remove the Fixes tag.
> > 2. Use dev_err_probe to simplify error handling.
> > ---
> > drivers/i2c/busses/i2c-rk3x.c | 51 +++++++++++++++++++++++++----------
> > 1 file changed, 37 insertions(+), 14 deletions(-)
>
> Wow, this is a whole lot of code to add to check for an error that
> can't really happen as far as I'm aware. Turning on a clock is just
> some MMIO writes and can't fail, right? Is this really worth it? Maybe
> just wrap clk_enable() and spam an error to the logs if it fails? If
> we ever see that error we can figure out what's going on and if
> there's a sensible reason it could fail we could add the more complex
> code.
We've had this discussion several times. I'm of the school that
if a function can return an error, that error should be checked.
It's not spam, we do it everywhere.
On the other hand, there is another school, bigger than mine,
that doesn't want such a check.
I decided not to bother. If someone adds the check, I'm going to
accept it. If someone doesn't add the check, I won't bother
asking for it.
Said that, MMIO reads and writes can fail: in other drivers I'm
seeing bogus reads due to some firmware failures during device
reset.
I agree with you with the rest of the comments and thanks for
checking this out.
Andi
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 3/3] i2c: rk3x: Add check for clk_enable()
2024-11-06 23:01 ` Andi Shyti
@ 2024-11-08 2:27 ` Jiasheng Jiang
0 siblings, 0 replies; 6+ messages in thread
From: Jiasheng Jiang @ 2024-11-08 2:27 UTC (permalink / raw)
To: Andi Shyti
Cc: Doug Anderson, rmk, max.schwarz, david.wu, heiko, vz, wsa,
manabian, linux-arm-kernel, linux-rockchip, linux-i2c,
linux-kernel
On Wed, Nov 6, 2024 at 6:01 PM Andi Shyti <andi.shyti@kernel.org> wrote:
>
> Hi Doug,
>
> On Tue, Nov 05, 2024 at 01:29:40PM -0800, Doug Anderson wrote:
> > On Tue, Nov 5, 2024 at 8:18 AM Jiasheng Jiang
> > > Add check for the return value of clk_enable() in order to catch the
> > > potential exception. Moreover, convert the return type of
> > > rk3x_i2c_adapt_div() into int and add the check.
> > >
> > > Signed-off-by: Jiasheng Jiang <jiashengjiangcool@gmail.com>
> > > ---
> > > Changelog:
> > >
> > > v1 -> v2:
> > >
> > > 1. Remove the Fixes tag.
> > > 2. Use dev_err_probe to simplify error handling.
> > > ---
> > > drivers/i2c/busses/i2c-rk3x.c | 51 +++++++++++++++++++++++++----------
> > > 1 file changed, 37 insertions(+), 14 deletions(-)
> >
> > Wow, this is a whole lot of code to add to check for an error that
> > can't really happen as far as I'm aware. Turning on a clock is just
> > some MMIO writes and can't fail, right? Is this really worth it? Maybe
> > just wrap clk_enable() and spam an error to the logs if it fails? If
> > we ever see that error we can figure out what's going on and if
> > there's a sensible reason it could fail we could add the more complex
> > code.
>
> We've had this discussion several times. I'm of the school that
> if a function can return an error, that error should be checked.
> It's not spam, we do it everywhere.
>
> On the other hand, there is another school, bigger than mine,
> that doesn't want such a check.
>
> I decided not to bother. If someone adds the check, I'm going to
> accept it. If someone doesn't add the check, I won't bother
> asking for it.
>
> Said that, MMIO reads and writes can fail: in other drivers I'm
> seeing bogus reads due to some firmware failures during device
> reset.
>
> I agree with you with the rest of the comments and thanks for
> checking this out.
>
> Andi
Thanks, I have submitted a v3 series to fix these problems.
-Jiasheng
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-11-08 2:27 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-05 16:18 [PATCH v2 1/3] i2c: lpc2k: Add check for clk_enable() Jiasheng Jiang
2024-11-05 16:18 ` [PATCH v2 2/3] i2c: pxa: Add check for clk_enable() and clk_prepare_enable() Jiasheng Jiang
2024-11-05 16:18 ` [PATCH v2 3/3] i2c: rk3x: Add check for clk_enable() Jiasheng Jiang
2024-11-05 21:29 ` Doug Anderson
2024-11-06 23:01 ` Andi Shyti
2024-11-08 2:27 ` Jiasheng Jiang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox