watchdog: Avoid division by zero from clk_get_rate()
cover watchdog: Avoid division by zero from clk_get_rate()
The series is a follow-up of [1].
[1] https://lore.kernel.org/all/[email protected]
Tzung-Bi Shih (3):
watchdog: digicolor: Avoid division by zero
watchdog: rtd119x: Avoid division by zero
watchdog: rzv2h: Avoid division by zero
drivers/watchdog/digicolor_wdt.c | 13 +++++++++---- drivers/watchdog/rtd119x_wdt.c | 7 ++++++- drivers/watchdog/rzv2h_wdt.c | 7 ++++++- 3 files changed, 21 insertions(+), 6 deletions(-)
Signature · 1 line
2.53.0
PATCH 1/3 watchdog: digicolor: Avoid division by zero
clk_get_rate() could return 0. Avoid a division by zero panic.
Since get_timeleft() cannot propagate errors, check the clock rate early in probe() and cache the rate in the driver data as it is unlikely to change at runtime.
--- drivers/watchdog/digicolor_wdt.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/watchdog/digicolor_wdt.c +9 -4
@@ -25,6 +25,7 @@ struct dc_wdt {void __iomem *base;struct clk *clk;spinlock_t lock; +unsigned long rate; };static unsigned timeout;
@@ -61,7 +62,7 @@ static int dc_wdt_start(struct watchdog_device *wdog) {struct dc_wdt *wdt =watchdog_get_drvdata (wdog); -dc_wdt_set (wdt, wdog->timeout *clk_get_rate (wdt->clk)); +dc_wdt_set (wdt, wdog->timeout * wdt->rate);return 0 ; }
@@ -79,7 +80,7 @@ static int dc_wdt_set_timeout(struct watchdog_device *wdog, unsigned int t) {struct dc_wdt *wdt =watchdog_get_drvdata (wdog); -dc_wdt_set (wdt, t *clk_get_rate (wdt->clk)); +dc_wdt_set (wdt, t * wdt->rate); wdog->timeout = t;return 0 ;
@@ -90,7 +91,7 @@ static unsigned int dc_wdt_get_timeleft(struct watchdog_device *wdog)struct dc_wdt *wdt =watchdog_get_drvdata (wdog);uint32_t count =readl_relaxed (wdt->base +TIMER_A_COUNT ); -return count /clk_get_rate (wdt->clk); +return count / wdt->rate; }static const struct watchdog_ops dc_wdt_ops = {
@@ -130,7 +131,11 @@ static int dc_wdt_probe(struct platform_device *pdev) wdt->clk =devm_clk_get (dev,NULL );if (IS_ERR (wdt->clk))return PTR_ERR (wdt->clk); - dc_wdt_wdd.max_timeout =U32_MAX /clk_get_rate (wdt->clk); + + wdt->rate =clk_get_rate (wdt->clk); +if (!wdt->rate) +return -EINVAL ; + dc_wdt_wdd.max_timeout =U32_MAX / wdt->rate; dc_wdt_wdd.timeout = dc_wdt_wdd.max_timeout; dc_wdt_wdd.parent = dev;
Signature · 1 line
2.53.0
Re: [PATCH 1/3] watchdog: digicolor: Avoid division by zero
Hi Tzung-Bi Shih,
Quoted 8 lines · Tzung-Bi Shih
clk_get_rate()could return 0. Avoid a division by zero panic.Since
get_timeleft()cannot propagate errors, check the clock rate early inprobe()and cache the rate in the driver data as it is unlikely to change at runtime.Fixes 336694a01dae ("watchdog: digicolor: driver for Conexant Digicolor CX92755 SoC")Signed-off-by Tzung-Bi Shih <[email protected]>
Thanks,
baruch
Quoted 55 lines
--- drivers/watchdog/digicolor_wdt.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)drivers/watchdog/digicolor_wdt.c +9
-4@@ -25,6 +25,7 @@ struct dc_wdt {void __iomem *base;struct clk *clk;spinlock_t lock; +unsigned long rate; };static unsigned timeout;@@ -61,7 +62,7 @@ static int dc_wdt_start(struct watchdog_device *wdog) {struct dc_wdt *wdt =watchdog_get_drvdata (wdog); -dc_wdt_set (wdt, wdog->timeout *clk_get_rate (wdt->clk)); +dc_wdt_set (wdt, wdog->timeout * wdt->rate);return 0 ; }@@ -79,7 +80,7 @@ static int dc_wdt_set_timeout(struct watchdog_device *wdog, unsigned int t) {struct dc_wdt *wdt =watchdog_get_drvdata (wdog); -dc_wdt_set (wdt, t *clk_get_rate (wdt->clk)); +dc_wdt_set (wdt, t * wdt->rate); wdog->timeout = t;return 0 ;@@ -90,7 +91,7 @@ static unsigned int dc_wdt_get_timeleft(struct watchdog_device *wdog)struct dc_wdt *wdt =watchdog_get_drvdata (wdog);uint32_t count =readl_relaxed (wdt->base +TIMER_A_COUNT ); -return count /clk_get_rate (wdt->clk); +return count / wdt->rate; }static const struct watchdog_ops dc_wdt_ops = {@@ -130,7 +131,11 @@ static int dc_wdt_probe(struct platform_device *pdev) wdt->clk =devm_clk_get (dev,NULL );if (IS_ERR (wdt->clk))return PTR_ERR (wdt->clk); - dc_wdt_wdd.max_timeout =U32_MAX /clk_get_rate (wdt->clk); + + wdt->rate =clk_get_rate (wdt->clk); +if (!wdt->rate) +return -EINVAL ; + dc_wdt_wdd.max_timeout =U32_MAX / wdt->rate; dc_wdt_wdd.timeout = dc_wdt_wdd.max_timeout; dc_wdt_wdd.parent = dev;
Signature · 3 lines
~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- [email protected] - tel: +972.52.368.4656, http://www.tkos.co.il -Re: [PATCH 1/3] watchdog: digicolor: Avoid division by zero
In reply to Tzung-Bi ShihQuoted 9 lines · Tzung-Bi Shih
clk_get_rate()could return 0. Avoid a division by zero panic.Since
get_timeleft()cannot propagate errors, check the clock rate early inprobe()and cache the rate in the driver data as it is unlikely to change at runtime.Fixes 336694a01dae ("watchdog: digicolor: driver for Conexant Digicolor CX92755 SoC")Signed-off-by Tzung-Bi Shih <[email protected]>Acked-by Baruch Siach <[email protected]>
Applied.
Thanks,
Guenter
PATCH 2/3 watchdog: rtd119x: Avoid division by zero
In reply to Tzung-Bi Shihclk_get_rate() could return 0. Avoid a division by zero panic.
--- drivers/watchdog/rtd119x_wdt.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/watchdog/rtd119x_wdt.c +6 -1
@@ -98,6 +98,7 @@ static int rtd119x_wdt_probe(struct platform_device *pdev) {struct device *dev = &pdev->dev;struct rtd119x_watchdog_device *data; +unsigned long rate; data =devm_kzalloc (dev,sizeof (*data),GFP_KERNEL );if (!data)
@@ -111,10 +112,14 @@ static int rtd119x_wdt_probe(struct platform_device *pdev)if (IS_ERR (data->clk))return PTR_ERR (data->clk); + rate =clk_get_rate (data->clk); +if (!rate) +return -EINVAL ; + data->wdt_dev.info = &rtd119x_wdt_info; data->wdt_dev.ops = &rtd119x_wdt_ops; data->wdt_dev.timeout =120 ; - data->wdt_dev.max_timeout =0xffffffff /clk_get_rate (data->clk); + data->wdt_dev.max_timeout =0xffffffff / rate; data->wdt_dev.min_timeout =1 ; data->wdt_dev.parent = dev;
Signature · 1 line
2.53.0
Re: [PATCH 2/3] watchdog: rtd119x: Avoid division by zero
Quoted 4 lines · Tzung-Bi Shih
clk_get_rate()could return 0. Avoid a division by zero panic.Fixes 2bdf6acbfead ("watchdog: Add Realtek RTD1295")Signed-off-by Tzung-Bi Shih <[email protected]>
Applied.
Thanks,
Guenter
PATCH 3/3 watchdog: rzv2h: Avoid division by zero
In reply to Tzung-Bi Shihclk_get_rate() could return 0. Avoid a division by zero panic.
--- drivers/watchdog/rzv2h_wdt.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/watchdog/rzv2h_wdt.c +6 -1
@@ -278,6 +278,7 @@ static int rzv2h_wdt_probe(struct platform_device *pdev)struct device *dev = &pdev->dev;struct rzv2h_wdt_priv *priv;struct clk *count_clk; +unsigned long rate;int ret; priv =devm_kzalloc (dev,sizeof (*priv),GFP_KERNEL );
@@ -314,8 +315,12 @@ static int rzv2h_wdt_probe(struct platform_device *pdev)return dev_err_probe (dev, -EINVAL ,"Invalid count source\n" ); } + rate =clk_get_rate (count_clk); +if (!rate) +return dev_err_probe (dev, -EINVAL ,"Invalid clock rate\n" ); + priv->wdev.max_hw_heartbeat_ms = (MILLI * priv->of_data->timeout_cycles * - priv->of_data->cks_div) /clk_get_rate (count_clk); + priv->of_data->cks_div) / rate;dev_dbg (dev,"max hw timeout of %dms\n" , priv->wdev.max_hw_heartbeat_ms); ret =devm_pm_runtime_enable (dev);
Signature · 1 line
2.53.0
Re: [PATCH 3/3] watchdog: rzv2h: Avoid division by zero
Quoted 4 lines · Tzung-Bi Shih
clk_get_rate()could return 0. Avoid a division by zero panic.Fixes f6febd0a30b6 ("watchdog: Add Watchdog Timer driver for RZ/V2H(P)")Signed-off-by Tzung-Bi Shih <[email protected]>
Applied.
Thanks,
Guenter