From ef1bb8e21b0ad4fe43a76f69ea14b9fd31e4bdee Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Wed, 30 Sep 2020 09:19:54 +0200 Subject: hw_random: mxc-rngc: fix read of uninitialized variable err is evaluated in a ternary condition on return, but if the while loop is never entered, it is left uninitialized. Fix this. Reported-by: clang-analyzer-10 Signed-off-by: Ahmad Fatoum Signed-off-by: Sascha Hauer --- drivers/hw_random/mxc-rngc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hw_random/mxc-rngc.c b/drivers/hw_random/mxc-rngc.c index 3ed25aa61d..075c20e437 100644 --- a/drivers/hw_random/mxc-rngc.c +++ b/drivers/hw_random/mxc-rngc.c @@ -133,7 +133,7 @@ static int mxc_rngc_data_present(struct hwrng *rng) static int mxc_rngc_read(struct hwrng *rng, void *buf, size_t max, bool wait) { struct mxc_rngc *rngc = container_of(rng, struct mxc_rngc, rng); - unsigned int err; + unsigned int err = 0; int count = 0; u32 *data = buf; -- cgit v1.2.3 From f245581eb865c1ed62fb6b8a382ab7bf6b0f6d38 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Wed, 30 Sep 2020 09:19:57 +0200 Subject: watchdog: fix division-by-zero when clock rate == 0 Instead of storing the clk into the driver's device-specific private data, just store the rate and make sure it's != 0 on probe. This aligns us with what Linux does for the STM32 IWDG and DW WDT. Reported-by: clang-analyzer-10 Cc: Oleksij Rempel Signed-off-by: Ahmad Fatoum Signed-off-by: Sascha Hauer --- drivers/watchdog/ar9344_wdt.c | 21 ++++++++++++++------- drivers/watchdog/dw_wdt.c | 19 ++++++++++++------- drivers/watchdog/stm32_iwdg.c | 2 ++ 3 files changed, 28 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/ar9344_wdt.c b/drivers/watchdog/ar9344_wdt.c index 4615288631..c7cd552dc7 100644 --- a/drivers/watchdog/ar9344_wdt.c +++ b/drivers/watchdog/ar9344_wdt.c @@ -34,8 +34,8 @@ struct ar9344_wd { struct watchdog wd; void __iomem *base; - struct clk *clk; struct device_d *dev; + unsigned int rate; }; static int ar9344_watchdog_set_timeout(struct watchdog *wd, unsigned timeout) @@ -45,7 +45,7 @@ static int ar9344_watchdog_set_timeout(struct watchdog *wd, unsigned timeout) if (timeout) { ctrl = AR9344_WD_CTRL_ACTION_FCR; - val = timeout * clk_get_rate(priv->clk); + val = timeout * priv->rate; } else { ctrl = AR9344_WD_CTRL_ACTION_NONE; val = U32_MAX; @@ -74,6 +74,7 @@ static int ar9344_wdt_probe(struct device_d *dev) { struct resource *iores; struct ar9344_wd *priv; + struct clk *clk; int ret; priv = xzalloc(sizeof(struct ar9344_wd)); @@ -93,16 +94,22 @@ static int ar9344_wdt_probe(struct device_d *dev) ar9344_watchdog_detect_reset_source(priv); - priv->clk = clk_get(dev, NULL); - if (IS_ERR(priv->clk)) { + clk = clk_get(dev, NULL); + if (IS_ERR(clk)) { dev_err(dev, "could not get clk\n"); - ret = PTR_ERR(priv->clk); + ret = PTR_ERR(clk); goto on_error; } - clk_enable(priv->clk); + clk_enable(clk); - priv->wd.timeout_max = U32_MAX / clk_get_rate(priv->clk); + priv->rate = clk_get_rate(clk); + if (priv->rate == 0) { + ret = -EINVAL; + goto on_error; + } + + priv->wd.timeout_max = U32_MAX / priv->rate; ret = watchdog_register(&priv->wd); if (ret) diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index cb0d17e361..17771c7126 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -41,10 +41,10 @@ struct dw_wdt { void __iomem *regs; - struct clk *clk; struct restart_handler restart; struct watchdog wdd; struct reset_control *rst; + unsigned int rate; }; #define to_dw_wdt(wdd) container_of(wdd, struct dw_wdt, wdd) @@ -55,7 +55,7 @@ static inline int dw_wdt_top_in_seconds(struct dw_wdt *dw_wdt, unsigned top) * There are 16 possible timeout values in 0..15 where the number of * cycles is 2 ^ (16 + i) and the watchdog counts down. */ - return (1U << (16 + top)) / clk_get_rate(dw_wdt->clk); + return (1U << (16 + top)) / dw_wdt->rate; } static int dw_wdt_start(struct watchdog *wdd) @@ -134,6 +134,7 @@ static int dw_wdt_drv_probe(struct device_d *dev) struct watchdog *wdd; struct dw_wdt *dw_wdt; struct resource *mem; + struct clk *clk; int ret; dw_wdt = xzalloc(sizeof(*dw_wdt)); @@ -143,11 +144,11 @@ static int dw_wdt_drv_probe(struct device_d *dev) if (IS_ERR(dw_wdt->regs)) return PTR_ERR(dw_wdt->regs); - dw_wdt->clk = clk_get(dev, NULL); - if (IS_ERR(dw_wdt->clk)) - return PTR_ERR(dw_wdt->clk); + clk = clk_get(dev, NULL); + if (IS_ERR(clk)) + return PTR_ERR(clk); - ret = clk_enable(dw_wdt->clk); + ret = clk_enable(clk); if (ret) return ret; @@ -160,6 +161,10 @@ static int dw_wdt_drv_probe(struct device_d *dev) wdd->hwdev = dev; wdd->set_timeout = dw_wdt_set_timeout; + dw_wdt->rate = clk_get_rate(clk); + if (dw_wdt->rate == 0) + return -EINVAL; + ret = watchdog_register(wdd); if (ret) goto out_disable_clk; @@ -179,7 +184,7 @@ static int dw_wdt_drv_probe(struct device_d *dev) return 0; out_disable_clk: - clk_disable(dw_wdt->clk); + clk_disable(clk); return ret; } diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c index 9e38f1a669..4d7a263b7e 100644 --- a/drivers/watchdog/stm32_iwdg.c +++ b/drivers/watchdog/stm32_iwdg.c @@ -157,6 +157,8 @@ static int stm32_iwdg_probe(struct device_d *dev) return ret; wd->rate = clk_get_rate(clk); + if (wd->rate == 0) + return -EINVAL; if (data->has_pclk) { clk = clk_get(dev, "pclk"); -- cgit v1.2.3 From 4dd5c073c750618054fd4366dcf141770559af46 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Wed, 30 Sep 2020 09:19:58 +0200 Subject: net: usb: asix: propagate errors from MDIO accessors The primitives asix_mdio_write and asix_mdio_read use return errors, but are unchecked. Propagate them instead. Reported-by: clang-analyzer-10 [afa: Untested on real hardware] Signed-off-by: Ahmad Fatoum Signed-off-by: Sascha Hauer --- drivers/net/usb/asix.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 3ca27ff027..1140be9d16 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -252,11 +252,19 @@ static int asix_mdio_read(struct mii_bus *bus, int phy_id, int loc) { struct usbnet *dev = bus->priv; __le16 res; + int ret; - asix_set_sw_mii(dev); - asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, - (__u16)loc, 2, &res); - asix_set_hw_mii(dev); + ret = asix_set_sw_mii(dev); + if (ret < 0) + return ret; + + ret = asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, &res); + if (ret < 0) + return ret; + + ret = asix_set_hw_mii(dev); + if (ret < 0) + return ret; dev_dbg(&dev->edev.dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", phy_id, loc, le16_to_cpu(res)); @@ -268,13 +276,22 @@ static int asix_mdio_write(struct mii_bus *bus, int phy_id, int loc, u16 val) { struct usbnet *dev = bus->priv; __le16 res = cpu_to_le16(val); + int ret; dev_dbg(&dev->edev.dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", phy_id, loc, val); - asix_set_sw_mii(dev); - asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res); - asix_set_hw_mii(dev); + ret = asix_set_sw_mii(dev); + if (ret < 0) + return ret; + + ret = asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res); + if (ret < 0) + return ret; + + ret = asix_set_hw_mii(dev); + if (ret < 0) + return ret; return 0; } -- cgit v1.2.3 From 01bc873f4e03eff83ce7d8e92c3907eaf559ade6 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Wed, 30 Sep 2020 09:20:01 +0200 Subject: USB: musb: remove dead stores Reading the interrupt registers has a side-effect, so their value need not be used for anythig. Storing it into a variable never read obfuscates this however. Cast to (void) for clarity. Reported-by: clang-analyzer-10 Signed-off-by: Ahmad Fatoum Signed-off-by: Sascha Hauer --- drivers/usb/musb/musb_core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 9fdef8679b..266663a9b0 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -330,7 +330,6 @@ void musb_load_testpacket(struct musb *musb) static void musb_generic_disable(struct musb *musb) { void __iomem *mbase = musb->mregs; - u16 temp; /* disable interrupts */ musb_writeb(mbase, MUSB_INTRUSBE, 0); @@ -343,9 +342,9 @@ static void musb_generic_disable(struct musb *musb) musb_writeb(mbase, MUSB_DEVCTL, 0); /* flush pending interrupts */ - temp = musb_readb(mbase, MUSB_INTRUSB); - temp = musb_readw(mbase, MUSB_INTRTX); - temp = musb_readw(mbase, MUSB_INTRRX); + (void)musb_readb(mbase, MUSB_INTRUSB); + (void)musb_readw(mbase, MUSB_INTRTX); + (void)musb_readw(mbase, MUSB_INTRRX); } -- cgit v1.2.3 From ecf602fb0f00a3a31d8ece9c8ef97050249485c3 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Wed, 30 Sep 2020 09:20:03 +0200 Subject: reset: remove dead initialization rstc is never read before written, so just drop the initializer. Reported-by: clang-analyzer-10 Signed-off-by: Ahmad Fatoum Signed-off-by: Sascha Hauer --- drivers/reset/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 99b9c80655..26a54f21df 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -150,7 +150,7 @@ EXPORT_SYMBOL_GPL(reset_control_deassert); static struct reset_control *of_reset_control_get(struct device_node *node, const char *id) { - struct reset_control *rstc = ERR_PTR(-ENODEV); + struct reset_control *rstc; struct reset_controller_dev *r, *rcdev; struct of_phandle_args args; int index = 0; -- cgit v1.2.3