[PATCH] net: mv643xx_eth: disable clk on error path in mv643xx_eth_shared_probe()

2019-02-15 Thread Alexey Khoroshilov
If mv643xx_eth_shared_of_probe() fails, mv643xx_eth_shared_probe()
leaves clk undisabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/net/ethernet/marvell/mv643xx_eth.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c 
b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 2f427271a793..292a668ce88e 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -2879,7 +2879,7 @@ static int mv643xx_eth_shared_probe(struct 
platform_device *pdev)
 
ret = mv643xx_eth_shared_of_probe(pdev);
if (ret)
-   return ret;
+   goto err_put_clk;
pd = dev_get_platdata(>dev);
 
msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ?
@@ -2887,6 +2887,11 @@ static int mv643xx_eth_shared_probe(struct 
platform_device *pdev)
infer_hw_params(msp);
 
return 0;
+
+err_put_clk:
+   if (!IS_ERR(msp->clk))
+   clk_disable_unprepare(msp->clk);
+   return ret;
 }
 
 static int mv643xx_eth_shared_remove(struct platform_device *pdev)
-- 
2.7.4



[PATCH] net: stmmac: dwmac-rk: fix error handling in rk_gmac_powerup()

2019-01-26 Thread Alexey Khoroshilov
If phy_power_on() fails in rk_gmac_powerup(), clocks are left enabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 7b923362ee55..3b174eae77c1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1342,8 +1342,10 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
}
 
ret = phy_power_on(bsp_priv, true);
-   if (ret)
+   if (ret) {
+   gmac_clk_enable(bsp_priv, false);
return ret;
+   }
 
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
-- 
2.7.4



[PATCH v2] usb: dwc3: exynos: Fix error handling of clk_prepare_enable

2019-01-21 Thread Alexey Khoroshilov
If clk_prepare_enable() fails in dwc3_exynos_probe() or in
dwc3_exynos_resume(), exynos->clks[0] is left undisabled
because of usage preincrement in while condition.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
Fixes: 9f2168367a0a ("usb: dwc3: exynos: Rework clock handling and prepare for 
new variants")
---
v2: Add fix for the second instance in dwc3_exynos_resume() per Marek 
Szyprowski note.

 drivers/usb/dwc3/dwc3-exynos.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
index cb7fcd7c0ad8..c1e9ea621f41 100644
--- a/drivers/usb/dwc3/dwc3-exynos.c
+++ b/drivers/usb/dwc3/dwc3-exynos.c
@@ -78,7 +78,7 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
for (i = 0; i < exynos->num_clks; i++) {
ret = clk_prepare_enable(exynos->clks[i]);
if (ret) {
-   while (--i > 0)
+   while (i-- > 0)
clk_disable_unprepare(exynos->clks[i]);
return ret;
}
@@ -223,7 +223,7 @@ static int dwc3_exynos_resume(struct device *dev)
for (i = 0; i < exynos->num_clks; i++) {
ret = clk_prepare_enable(exynos->clks[i]);
if (ret) {
-   while (--i > 0)
+   while (i-- > 0)
clk_disable_unprepare(exynos->clks[i]);
return ret;
}
-- 
2.7.4



[PATCH] usb: dwc3: exynos: Fix error handling of clk_prepare_enable

2019-01-18 Thread Alexey Khoroshilov
If clk_prepare_enable() fails in dwc3_exynos_probe(),
exynos->clks[0] is left undisabled because of usage
preincrement in while condition.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
Fixes: 9f2168367a0a ("usb: dwc3: exynos: Rework clock handling and prepare for 
new variants")
---
 drivers/usb/dwc3/dwc3-exynos.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
index cb7fcd7c0ad8..e7f6cff27b9a 100644
--- a/drivers/usb/dwc3/dwc3-exynos.c
+++ b/drivers/usb/dwc3/dwc3-exynos.c
@@ -78,7 +78,7 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
for (i = 0; i < exynos->num_clks; i++) {
ret = clk_prepare_enable(exynos->clks[i]);
if (ret) {
-   while (--i > 0)
+   while (i-- > 0)
clk_disable_unprepare(exynos->clks[i]);
return ret;
}
-- 
2.7.4



[PATCH v2 1/2] media: tw9910: fix failure handling in tw9910_power_on()

2018-12-30 Thread Alexey Khoroshilov
If gpiod_get_optional() fails in tw9910_power_on(), clk is left undisabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
v2: reset pdn_gpio as well as Jacopo Mondi suggested.

 drivers/media/i2c/tw9910.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c
index a54548cc4285..0971f8a34afb 100644
--- a/drivers/media/i2c/tw9910.c
+++ b/drivers/media/i2c/tw9910.c
@@ -610,6 +610,11 @@ static int tw9910_power_on(struct tw9910_priv *priv)
 GPIOD_OUT_LOW);
if (IS_ERR(priv->rstb_gpio)) {
dev_info(>dev, "Unable to get GPIO \"rstb\"");
+   clk_disable_unprepare(priv->clk);
+   if (priv->pdn_gpio) {
+   gpiod_set_value(priv->pdn_gpio, 1);
+   usleep_range(500, 1000);
+   }
return PTR_ERR(priv->rstb_gpio);
}
 
-- 
2.7.4



[PATCH v2 2/2] media: tw9910: add helper function for setting gpiod value

2018-12-30 Thread Alexey Khoroshilov
tw9910 driver tries to sleep for the smae period of time
after each gpiod_set_value(). The patch moves duplicated code
to a helper function.

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/i2c/tw9910.c | 30 +-
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c
index 0971f8a34afb..8d1138e13803 100644
--- a/drivers/media/i2c/tw9910.c
+++ b/drivers/media/i2c/tw9910.c
@@ -584,6 +584,14 @@ static int tw9910_s_register(struct v4l2_subdev *sd,
 }
 #endif
 
+static void tw9910_set_gpio_value(struct gpio_desc *desc, int value)
+{
+   if (desc) {
+   gpiod_set_value(desc, value);
+   usleep_range(500, 1000);
+   }
+}
+
 static int tw9910_power_on(struct tw9910_priv *priv)
 {
struct i2c_client *client = v4l2_get_subdevdata(>subdev);
@@ -595,10 +603,7 @@ static int tw9910_power_on(struct tw9910_priv *priv)
return ret;
}
 
-   if (priv->pdn_gpio) {
-   gpiod_set_value(priv->pdn_gpio, 0);
-   usleep_range(500, 1000);
-   }
+   tw9910_set_gpio_value(priv->pdn_gpio, 0);
 
/*
 * FIXME: The reset signal is connected to a shared GPIO on some
@@ -611,18 +616,13 @@ static int tw9910_power_on(struct tw9910_priv *priv)
if (IS_ERR(priv->rstb_gpio)) {
dev_info(>dev, "Unable to get GPIO \"rstb\"");
clk_disable_unprepare(priv->clk);
-   if (priv->pdn_gpio) {
-   gpiod_set_value(priv->pdn_gpio, 1);
-   usleep_range(500, 1000);
-   }
+   tw9910_set_gpio_value(priv->pdn_gpio, 1);
return PTR_ERR(priv->rstb_gpio);
}
 
if (priv->rstb_gpio) {
-   gpiod_set_value(priv->rstb_gpio, 1);
-   usleep_range(500, 1000);
-   gpiod_set_value(priv->rstb_gpio, 0);
-   usleep_range(500, 1000);
+   tw9910_set_gpio_value(priv->rstb_gpio, 1);
+   tw9910_set_gpio_value(priv->rstb_gpio, 0);
 
gpiod_put(priv->rstb_gpio);
}
@@ -633,11 +633,7 @@ static int tw9910_power_on(struct tw9910_priv *priv)
 static int tw9910_power_off(struct tw9910_priv *priv)
 {
clk_disable_unprepare(priv->clk);
-
-   if (priv->pdn_gpio) {
-   gpiod_set_value(priv->pdn_gpio, 1);
-   usleep_range(500, 1000);
-   }
+   tw9910_set_gpio_value(priv->pdn_gpio, 1);
 
return 0;
 }
-- 
2.7.4



Re: [PATCH] media: tw9910: add missed clk_disable_unprepare() on failure path

2018-12-30 Thread Alexey Khoroshilov
Hi Jacopo,

On 30.12.2018 12:49, Jacopo Mondi wrote:
> On Sun, Dec 30, 2018 at 12:35:20AM +0300, Alexey Khoroshilov wrote:
>> If gpiod_get_optional() fails in tw9910_power_on(), clk is left undisabled.
> 
> Correct, thanks for spotting this.
> 
> I think pdn_gpio should also be handled if rstb_gpio fails.
> What's your opinion?

I would agree. I'll send v2.

Thank you,
Alexey

> 
>> Found by Linux Driver Verification project (linuxtesting.org).
>>
>> Signed-off-by: Alexey Khoroshilov 
>> ---
>>  drivers/media/i2c/tw9910.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c
>> index a54548cc4285..109770d678d2 100644
>> --- a/drivers/media/i2c/tw9910.c
>> +++ b/drivers/media/i2c/tw9910.c
>> @@ -610,6 +610,7 @@ static int tw9910_power_on(struct tw9910_priv *priv)
>>   GPIOD_OUT_LOW);
>>  if (IS_ERR(priv->rstb_gpio)) {
>>  dev_info(>dev, "Unable to get GPIO \"rstb\"");
>> +clk_disable_unprepare(priv->clk);
>>  return PTR_ERR(priv->rstb_gpio);
>>  }
>>
>> --
>> 2.7.4
>>



[PATCH] media: tw9910: add missed clk_disable_unprepare() on failure path

2018-12-29 Thread Alexey Khoroshilov
If gpiod_get_optional() fails in tw9910_power_on(), clk is left undisabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/i2c/tw9910.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c
index a54548cc4285..109770d678d2 100644
--- a/drivers/media/i2c/tw9910.c
+++ b/drivers/media/i2c/tw9910.c
@@ -610,6 +610,7 @@ static int tw9910_power_on(struct tw9910_priv *priv)
 GPIOD_OUT_LOW);
if (IS_ERR(priv->rstb_gpio)) {
dev_info(>dev, "Unable to get GPIO \"rstb\"");
+   clk_disable_unprepare(priv->clk);
return PTR_ERR(priv->rstb_gpio);
}
 
-- 
2.7.4



net: hns: question regarding ae_node device node refcounting

2018-12-22 Thread Alexey Khoroshilov
Hello,

hns_nic_dev_probe() increments refcount of ae_node device node:
ae_node = of_parse_phandle(dev->of_node, "ae-handle", 0);

But there is no of_node_put() for ae_node.
What is the right place to decrement the ae_node refount?

Should it be placed in hns_nic_dev_probe() or in hns_nic_dev_remove()?
Or may be it is managed by fwnode somehow?

--
Alexey Khoroshilov
Linux Verification Center, ISPRAS
web: http://linuxtesting.org



Re: [PATCH] mailbox: imx: Fix clk handling in imx_mu_probe()

2018-12-16 Thread Alexey Khoroshilov
Hi Oleksij,

By chance I took a look at another implementations:

arch/arm/mach-ep93xx/clock.c#L266

int clk_enable(struct clk *clk)
{
unsigned long flags;

if (!clk)
return -EINVAL;
...

arch/c6x/platforms/pll.c#L48

int clk_enable(struct clk *clk)
{
unsigned long flags;

if (clk == NULL || IS_ERR(clk))
return -EINVAL;

So, I am not sure the NULL resistance is a part of the clk_enable()
contract?

--
Alexey


On 17.12.2018 9:01, Oleksij Rempel wrote:
> Hi Alexey,
> 
> On Sun, Dec 16, 2018 at 02:01:44AM +0300, Alexey Khoroshilov wrote:
>> Handling of devm_clk_get() suggests that the driver should support
>> lack of priv->clk. But imx_mu_probe() fails on clk_prepare_enable(NULL)
>> in that case.
>>
>> The patch removes the try to enable absent clk and adds error handling
>> for mbox_controller_register().
>>
>> Found by Linux Driver Verification project (linuxtesting.org).
>>
>> Signed-off-by: Alexey Khoroshilov 
>> ---
>>  drivers/mailbox/imx-mailbox.c | 18 +-
>>  1 file changed, 13 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
>> index 363d35d5e49d..ddde398f576e 100644
>> --- a/drivers/mailbox/imx-mailbox.c
>> +++ b/drivers/mailbox/imx-mailbox.c
>> @@ -292,10 +292,12 @@ static int imx_mu_probe(struct platform_device *pdev)
>>  priv->clk = NULL;
>>  }
>>  
>> -ret = clk_prepare_enable(priv->clk);
>> -if (ret) {
>> -dev_err(dev, "Failed to enable clock\n");
>> -return ret;
>> +if (priv->clk) {
>> +ret = clk_prepare_enable(priv->clk);
>> +if (ret) {
>> +dev_err(dev, "Failed to enable clock\n");
>> +return ret;
>> +}
>>  }
>>  
>>  for (i = 0; i < IMX_MU_CHANS; i++) {
>> @@ -324,7 +326,13 @@ static int imx_mu_probe(struct platform_device *pdev)
>>  
>>  imx_mu_init_generic(priv);
>>  
>> -return mbox_controller_register(>mbox);
>> +ret = mbox_controller_register(>mbox);
>> +if (ret) {
>> +clk_disable_unprepare(priv->clk);
>> +return ret;
>> +}
>> +
>> +return 0;
>>  }
>>  
>>  static int imx_mu_remove(struct platform_device *pdev)
>> -- 
>> 2.7.4
>>
>>
> 
> NACK for this patch.
> 
> Here are code snippets from clk framework:
> 
> /* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
> static inline int clk_prepare_enable(struct clk *clk)
> {
>   int ret;
> 
>   ret = clk_prepare(clk);
>   if (ret)
>   return ret;
>   ret = clk_enable(clk);
>   if (ret)
>   clk_unprepare(clk);
> 
>   return ret;
> }
> 
> int clk_prepare(struct clk *clk)
> {
>   if (!clk)
>   return 0;
> 
>   return clk_core_prepare_lock(clk->core);
> }
> 
> int clk_enable(struct clk *clk)
> {
>   if (!clk)
>   return 0;
> 
>   return clk_core_enable_lock(clk->core);
> }
> 
> 
> As you can see, complete code path is NULL resistant. Are you trying to
> fix some real issue, or it is a theoretical work?
> 



[PATCH] mailbox: imx: Fix clk handling in imx_mu_probe()

2018-12-15 Thread Alexey Khoroshilov
Handling of devm_clk_get() suggests that the driver should support
lack of priv->clk. But imx_mu_probe() fails on clk_prepare_enable(NULL)
in that case.

The patch removes the try to enable absent clk and adds error handling
for mbox_controller_register().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/mailbox/imx-mailbox.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index 363d35d5e49d..ddde398f576e 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -292,10 +292,12 @@ static int imx_mu_probe(struct platform_device *pdev)
priv->clk = NULL;
}
 
-   ret = clk_prepare_enable(priv->clk);
-   if (ret) {
-   dev_err(dev, "Failed to enable clock\n");
-   return ret;
+   if (priv->clk) {
+   ret = clk_prepare_enable(priv->clk);
+   if (ret) {
+   dev_err(dev, "Failed to enable clock\n");
+   return ret;
+   }
}
 
for (i = 0; i < IMX_MU_CHANS; i++) {
@@ -324,7 +326,13 @@ static int imx_mu_probe(struct platform_device *pdev)
 
imx_mu_init_generic(priv);
 
-   return mbox_controller_register(>mbox);
+   ret = mbox_controller_register(>mbox);
+   if (ret) {
+   clk_disable_unprepare(priv->clk);
+   return ret;
+   }
+
+   return 0;
 }
 
 static int imx_mu_remove(struct platform_device *pdev)
-- 
2.7.4



[PATCH] soc: qcom: gsbi: Fix error handling in gsbi_probe()

2018-12-07 Thread Alexey Khoroshilov
If of_platform_populate() fails in gsbi_probe(),
gsbi->hclk is left undisabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/soc/qcom/qcom_gsbi.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c
index 09c669e70d63..038abc377fdb 100644
--- a/drivers/soc/qcom/qcom_gsbi.c
+++ b/drivers/soc/qcom/qcom_gsbi.c
@@ -138,7 +138,7 @@ static int gsbi_probe(struct platform_device *pdev)
struct resource *res;
void __iomem *base;
struct gsbi_info *gsbi;
-   int i;
+   int i, ret;
u32 mask, gsbi_num;
const struct crci_config *config = NULL;
 
@@ -221,7 +221,10 @@ static int gsbi_probe(struct platform_device *pdev)
 
platform_set_drvdata(pdev, gsbi);
 
-   return of_platform_populate(node, NULL, NULL, >dev);
+   ret = of_platform_populate(node, NULL, NULL, >dev);
+   if (ret)
+   clk_disable_unprepare(gsbi->hclk);
+   return ret;
 }
 
 static int gsbi_remove(struct platform_device *pdev)
-- 
2.7.4



[PATCH] soc: qcom: gsbi: Fix error handling in gsbi_probe()

2018-12-07 Thread Alexey Khoroshilov
If of_platform_populate() fails in gsbi_probe(),
gsbi->hclk is left undisabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/soc/qcom/qcom_gsbi.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c
index 09c669e70d63..038abc377fdb 100644
--- a/drivers/soc/qcom/qcom_gsbi.c
+++ b/drivers/soc/qcom/qcom_gsbi.c
@@ -138,7 +138,7 @@ static int gsbi_probe(struct platform_device *pdev)
struct resource *res;
void __iomem *base;
struct gsbi_info *gsbi;
-   int i;
+   int i, ret;
u32 mask, gsbi_num;
const struct crci_config *config = NULL;
 
@@ -221,7 +221,10 @@ static int gsbi_probe(struct platform_device *pdev)
 
platform_set_drvdata(pdev, gsbi);
 
-   return of_platform_populate(node, NULL, NULL, >dev);
+   ret = of_platform_populate(node, NULL, NULL, >dev);
+   if (ret)
+   clk_disable_unprepare(gsbi->hclk);
+   return ret;
 }
 
 static int gsbi_remove(struct platform_device *pdev)
-- 
2.7.4



[PATCH] video: clps711x-fb: release disp device node in probe()

2018-11-02 Thread Alexey Khoroshilov
clps711x_fb_probe() increments refcnt of disp device node by
of_parse_phandle() and leaves it undecremented on both
successful and error paths.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/video/fbdev/clps711x-fb.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/clps711x-fb.c 
b/drivers/video/fbdev/clps711x-fb.c
index ff561073ee4e..42f909618f04 100644
--- a/drivers/video/fbdev/clps711x-fb.c
+++ b/drivers/video/fbdev/clps711x-fb.c
@@ -287,14 +287,17 @@ static int clps711x_fb_probe(struct platform_device *pdev)
}
 
ret = of_get_fb_videomode(disp, >mode, OF_USE_NATIVE_MODE);
-   if (ret)
+   if (ret) {
+   of_node_put(disp);
goto out_fb_release;
+   }
 
of_property_read_u32(disp, "ac-prescale", >ac_prescale);
cfb->cmap_invert = of_property_read_bool(disp, "cmap-invert");
 
ret = of_property_read_u32(disp, "bits-per-pixel",
   >var.bits_per_pixel);
+   of_node_put(disp);
if (ret)
goto out_fb_release;
 
-- 
2.7.4



[PATCH] video: clps711x-fb: release disp device node in probe()

2018-11-02 Thread Alexey Khoroshilov
clps711x_fb_probe() increments refcnt of disp device node by
of_parse_phandle() and leaves it undecremented on both
successful and error paths.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/video/fbdev/clps711x-fb.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/clps711x-fb.c 
b/drivers/video/fbdev/clps711x-fb.c
index ff561073ee4e..42f909618f04 100644
--- a/drivers/video/fbdev/clps711x-fb.c
+++ b/drivers/video/fbdev/clps711x-fb.c
@@ -287,14 +287,17 @@ static int clps711x_fb_probe(struct platform_device *pdev)
}
 
ret = of_get_fb_videomode(disp, >mode, OF_USE_NATIVE_MODE);
-   if (ret)
+   if (ret) {
+   of_node_put(disp);
goto out_fb_release;
+   }
 
of_property_read_u32(disp, "ac-prescale", >ac_prescale);
cfb->cmap_invert = of_property_read_bool(disp, "cmap-invert");
 
ret = of_property_read_u32(disp, "bits-per-pixel",
   >var.bits_per_pixel);
+   of_node_put(disp);
if (ret)
goto out_fb_release;
 
-- 
2.7.4



[PATCH] mfd: ti_am335x_tscadc: release device nodes in ti_tscadc_probe()

2018-10-26 Thread Alexey Khoroshilov
ti_tscadc_probe() increments refcnt of tsc and adc device nodes
and leaves it undecremented.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/mfd/ti_am335x_tscadc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
index c2d47d78705b..6572232a5cef 100644
--- a/drivers/mfd/ti_am335x_tscadc.c
+++ b/drivers/mfd/ti_am335x_tscadc.c
@@ -142,16 +142,19 @@ staticint ti_tscadc_probe(struct platform_device 
*pdev)
node = of_get_child_by_name(pdev->dev.of_node, "tsc");
of_property_read_u32(node, "ti,wires", _wires);
of_property_read_u32(node, "ti,coordiante-readouts", );
+   of_node_put(node);
 
node = of_get_child_by_name(pdev->dev.of_node, "adc");
of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
adc_channels++;
if (val > 7) {
+   of_node_put(node);
dev_err(>dev, " PIN numbers are 0..7 (not %d)\n",
val);
return -EINVAL;
}
}
+   of_node_put(node);
total_channels = tsc_wires + adc_channels;
if (total_channels > 8) {
dev_err(>dev, "Number of i/p channels more than 8\n");
-- 
2.7.4



[PATCH] mfd: ti_am335x_tscadc: release device nodes in ti_tscadc_probe()

2018-10-26 Thread Alexey Khoroshilov
ti_tscadc_probe() increments refcnt of tsc and adc device nodes
and leaves it undecremented.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/mfd/ti_am335x_tscadc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
index c2d47d78705b..6572232a5cef 100644
--- a/drivers/mfd/ti_am335x_tscadc.c
+++ b/drivers/mfd/ti_am335x_tscadc.c
@@ -142,16 +142,19 @@ staticint ti_tscadc_probe(struct platform_device 
*pdev)
node = of_get_child_by_name(pdev->dev.of_node, "tsc");
of_property_read_u32(node, "ti,wires", _wires);
of_property_read_u32(node, "ti,coordiante-readouts", );
+   of_node_put(node);
 
node = of_get_child_by_name(pdev->dev.of_node, "adc");
of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
adc_channels++;
if (val > 7) {
+   of_node_put(node);
dev_err(>dev, " PIN numbers are 0..7 (not %d)\n",
val);
return -EINVAL;
}
}
+   of_node_put(node);
total_channels = tsc_wires + adc_channels;
if (total_channels > 8) {
dev_err(>dev, "Number of i/p channels more than 8\n");
-- 
2.7.4



mfd: syscon: syscon_node_to_regmap() and device_node refcounting

2018-10-13 Thread Alexey Khoroshilov
Hello,

Could you please clarify why it is safe to store device_node pointer
in of_syscon_register()? Who is responsible to make sure that 
it is not disappear?

static struct syscon *of_syscon_register(struct device_node *np)
{
...
syscon->np = np;
}


--
Thank you,
Alexey Khoroshilov
Linux Verification Center, ISPRAS
web: http://linuxtesting.org



mfd: syscon: syscon_node_to_regmap() and device_node refcounting

2018-10-13 Thread Alexey Khoroshilov
Hello,

Could you please clarify why it is safe to store device_node pointer
in of_syscon_register()? Who is responsible to make sure that 
it is not disappear?

static struct syscon *of_syscon_register(struct device_node *np)
{
...
syscon->np = np;
}


--
Thank you,
Alexey Khoroshilov
Linux Verification Center, ISPRAS
web: http://linuxtesting.org



[PATCH] watchdog: ts4800: release syscon device node in ts4800_wdt_probe()

2018-10-13 Thread Alexey Khoroshilov
Put syscon device node when it is not needed anymore.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/watchdog/ts4800_wdt.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/watchdog/ts4800_wdt.c b/drivers/watchdog/ts4800_wdt.c
index 2b8de8602b67..89843b16b04a 100644
--- a/drivers/watchdog/ts4800_wdt.c
+++ b/drivers/watchdog/ts4800_wdt.c
@@ -135,6 +135,7 @@ static int ts4800_wdt_probe(struct platform_device *pdev)
/* set regmap and offset to know where to write */
wdt->feed_offset = reg;
wdt->regmap = syscon_node_to_regmap(syscon_np);
+   of_node_put(syscon_np);
if (IS_ERR(wdt->regmap)) {
dev_err(>dev, "cannot get parent's regmap\n");
return PTR_ERR(wdt->regmap);
-- 
2.7.4



[PATCH] watchdog: ts4800: release syscon device node in ts4800_wdt_probe()

2018-10-13 Thread Alexey Khoroshilov
Put syscon device node when it is not needed anymore.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/watchdog/ts4800_wdt.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/watchdog/ts4800_wdt.c b/drivers/watchdog/ts4800_wdt.c
index 2b8de8602b67..89843b16b04a 100644
--- a/drivers/watchdog/ts4800_wdt.c
+++ b/drivers/watchdog/ts4800_wdt.c
@@ -135,6 +135,7 @@ static int ts4800_wdt_probe(struct platform_device *pdev)
/* set regmap and offset to know where to write */
wdt->feed_offset = reg;
wdt->regmap = syscon_node_to_regmap(syscon_np);
+   of_node_put(syscon_np);
if (IS_ERR(wdt->regmap)) {
dev_err(>dev, "cannot get parent's regmap\n");
return PTR_ERR(wdt->regmap);
-- 
2.7.4



[PATCH] staging: axis-fifo: add error handling of class_create()

2018-09-28 Thread Alexey Khoroshilov
Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/staging/axis-fifo/axis-fifo.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/staging/axis-fifo/axis-fifo.c 
b/drivers/staging/axis-fifo/axis-fifo.c
index abeee0ecc122..63c8efd1b8db 100644
--- a/drivers/staging/axis-fifo/axis-fifo.c
+++ b/drivers/staging/axis-fifo/axis-fifo.c
@@ -1089,6 +1089,8 @@ static int __init axis_fifo_init(void)
pr_info("axis-fifo driver loaded with parameters read_timeout = %i, 
write_timeout = %i\n",
read_timeout, write_timeout);
axis_fifo_driver_class = class_create(THIS_MODULE, DRIVER_NAME);
+   if (IS_ERR(axis_fifo_driver_class))
+   return PTR_ERR(axis_fifo_driver_class);
return platform_driver_register(_fifo_driver);
 }
 
-- 
2.7.4



[PATCH] staging: axis-fifo: add error handling of class_create()

2018-09-28 Thread Alexey Khoroshilov
Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/staging/axis-fifo/axis-fifo.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/staging/axis-fifo/axis-fifo.c 
b/drivers/staging/axis-fifo/axis-fifo.c
index abeee0ecc122..63c8efd1b8db 100644
--- a/drivers/staging/axis-fifo/axis-fifo.c
+++ b/drivers/staging/axis-fifo/axis-fifo.c
@@ -1089,6 +1089,8 @@ static int __init axis_fifo_init(void)
pr_info("axis-fifo driver loaded with parameters read_timeout = %i, 
write_timeout = %i\n",
read_timeout, write_timeout);
axis_fifo_driver_class = class_create(THIS_MODULE, DRIVER_NAME);
+   if (IS_ERR(axis_fifo_driver_class))
+   return PTR_ERR(axis_fifo_driver_class);
return platform_driver_register(_fifo_driver);
 }
 
-- 
2.7.4



[PATCH] iio: adc: imx25-gcq: Fix leak of device_node in mx25_gcq_setup_cfgs()

2018-09-21 Thread Alexey Khoroshilov
Leaving for_each_child_of_node loop we should release child device node,
if it is not stored for future use.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/iio/adc/fsl-imx25-gcq.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c
index ea264fa9e567..929c617db364 100644
--- a/drivers/iio/adc/fsl-imx25-gcq.c
+++ b/drivers/iio/adc/fsl-imx25-gcq.c
@@ -209,12 +209,14 @@ static int mx25_gcq_setup_cfgs(struct platform_device 
*pdev,
ret = of_property_read_u32(child, "reg", );
if (ret) {
dev_err(dev, "Failed to get reg property\n");
+   of_node_put(child);
return ret;
}
 
if (reg >= MX25_NUM_CFGS) {
dev_err(dev,
"reg value is greater than the number of 
available configuration registers\n");
+   of_node_put(child);
return -EINVAL;
}
 
@@ -228,6 +230,7 @@ static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
if (IS_ERR(priv->vref[refp])) {
dev_err(dev, "Error, trying to use external 
voltage reference without a vref-%s regulator.",
mx25_gcq_refp_names[refp]);
+   of_node_put(child);
return PTR_ERR(priv->vref[refp]);
}
priv->channel_vref_mv[reg] =
@@ -240,6 +243,7 @@ static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
break;
default:
dev_err(dev, "Invalid positive reference %d\n", refp);
+   of_node_put(child);
return -EINVAL;
}
 
@@ -254,10 +258,12 @@ static int mx25_gcq_setup_cfgs(struct platform_device 
*pdev,
 
if ((refp & MX25_ADCQ_CFG_REFP_MASK) != refp) {
dev_err(dev, "Invalid fsl,adc-refp property value\n");
+   of_node_put(child);
return -EINVAL;
}
if ((refn & MX25_ADCQ_CFG_REFN_MASK) != refn) {
dev_err(dev, "Invalid fsl,adc-refn property value\n");
+   of_node_put(child);
return -EINVAL;
}
 
-- 
2.7.4



[PATCH] iio: adc: imx25-gcq: Fix leak of device_node in mx25_gcq_setup_cfgs()

2018-09-21 Thread Alexey Khoroshilov
Leaving for_each_child_of_node loop we should release child device node,
if it is not stored for future use.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/iio/adc/fsl-imx25-gcq.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c
index ea264fa9e567..929c617db364 100644
--- a/drivers/iio/adc/fsl-imx25-gcq.c
+++ b/drivers/iio/adc/fsl-imx25-gcq.c
@@ -209,12 +209,14 @@ static int mx25_gcq_setup_cfgs(struct platform_device 
*pdev,
ret = of_property_read_u32(child, "reg", );
if (ret) {
dev_err(dev, "Failed to get reg property\n");
+   of_node_put(child);
return ret;
}
 
if (reg >= MX25_NUM_CFGS) {
dev_err(dev,
"reg value is greater than the number of 
available configuration registers\n");
+   of_node_put(child);
return -EINVAL;
}
 
@@ -228,6 +230,7 @@ static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
if (IS_ERR(priv->vref[refp])) {
dev_err(dev, "Error, trying to use external 
voltage reference without a vref-%s regulator.",
mx25_gcq_refp_names[refp]);
+   of_node_put(child);
return PTR_ERR(priv->vref[refp]);
}
priv->channel_vref_mv[reg] =
@@ -240,6 +243,7 @@ static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
break;
default:
dev_err(dev, "Invalid positive reference %d\n", refp);
+   of_node_put(child);
return -EINVAL;
}
 
@@ -254,10 +258,12 @@ static int mx25_gcq_setup_cfgs(struct platform_device 
*pdev,
 
if ((refp & MX25_ADCQ_CFG_REFP_MASK) != refp) {
dev_err(dev, "Invalid fsl,adc-refp property value\n");
+   of_node_put(child);
return -EINVAL;
}
if ((refn & MX25_ADCQ_CFG_REFN_MASK) != refn) {
dev_err(dev, "Invalid fsl,adc-refn property value\n");
+   of_node_put(child);
return -EINVAL;
}
 
-- 
2.7.4



[PATCH] spi: pic32-sqi: remove unnecessary of_node_get()

2018-09-14 Thread Alexey Khoroshilov
Almost all spi drivers assign spi master->dev.of_node from
its parent platform device without additional refcounting.
It seems of_node_get() in pic32_sqi_probe() is unnecessary
and there is no corresponding of_node_put().

Found by Linux Driver Verification project (linuxtesting.org)

Signed-off-by: Alexey Khoroshilov 
---
 drivers/spi/spi-pic32-sqi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-pic32-sqi.c b/drivers/spi/spi-pic32-sqi.c
index bd1c6b53283f..62e6bf1f50b1 100644
--- a/drivers/spi/spi-pic32-sqi.c
+++ b/drivers/spi/spi-pic32-sqi.c
@@ -656,7 +656,7 @@ static int pic32_sqi_probe(struct platform_device *pdev)
master->max_speed_hz= clk_get_rate(sqi->base_clk);
master->dma_alignment   = 32;
master->max_dma_len = PESQI_BD_BUF_LEN_MAX;
-   master->dev.of_node = of_node_get(pdev->dev.of_node);
+   master->dev.of_node = pdev->dev.of_node;
master->mode_bits   = SPI_MODE_3 | SPI_MODE_0 | SPI_TX_DUAL |
  SPI_RX_DUAL | SPI_TX_QUAD | SPI_RX_QUAD;
master->flags   = SPI_MASTER_HALF_DUPLEX;
-- 
2.7.4



[PATCH] spi: pic32-sqi: remove unnecessary of_node_get()

2018-09-14 Thread Alexey Khoroshilov
Almost all spi drivers assign spi master->dev.of_node from
its parent platform device without additional refcounting.
It seems of_node_get() in pic32_sqi_probe() is unnecessary
and there is no corresponding of_node_put().

Found by Linux Driver Verification project (linuxtesting.org)

Signed-off-by: Alexey Khoroshilov 
---
 drivers/spi/spi-pic32-sqi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-pic32-sqi.c b/drivers/spi/spi-pic32-sqi.c
index bd1c6b53283f..62e6bf1f50b1 100644
--- a/drivers/spi/spi-pic32-sqi.c
+++ b/drivers/spi/spi-pic32-sqi.c
@@ -656,7 +656,7 @@ static int pic32_sqi_probe(struct platform_device *pdev)
master->max_speed_hz= clk_get_rate(sqi->base_clk);
master->dma_alignment   = 32;
master->max_dma_len = PESQI_BD_BUF_LEN_MAX;
-   master->dev.of_node = of_node_get(pdev->dev.of_node);
+   master->dev.of_node = pdev->dev.of_node;
master->mode_bits   = SPI_MODE_3 | SPI_MODE_0 | SPI_TX_DUAL |
  SPI_RX_DUAL | SPI_TX_QUAD | SPI_RX_QUAD;
master->flags   = SPI_MASTER_HALF_DUPLEX;
-- 
2.7.4



[PATCH] spi: pic32: remove unnecessary of_node_get()

2018-09-06 Thread Alexey Khoroshilov
Almost all spi drivers assign spi master->dev.of_node from
its parent platform device without additional refcounting.
It seems of_node_get() in pic32_spi_probe() is unnecessary
and there is no corresponding of_node_put().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/spi/spi-pic32.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-pic32.c b/drivers/spi/spi-pic32.c
index f8a45af1fa9f..46ff76193ee1 100644
--- a/drivers/spi/spi-pic32.c
+++ b/drivers/spi/spi-pic32.c
@@ -774,7 +774,7 @@ static int pic32_spi_probe(struct platform_device *pdev)
if (ret)
goto err_master;
 
-   master->dev.of_node = of_node_get(pdev->dev.of_node);
+   master->dev.of_node = pdev->dev.of_node;
master->mode_bits   = SPI_MODE_3 | SPI_MODE_0 | SPI_CS_HIGH;
master->num_chipselect  = 1; /* single chip-select */
master->max_speed_hz= clk_get_rate(pic32s->clk);
-- 
2.7.4



[PATCH] spi: pic32: remove unnecessary of_node_get()

2018-09-06 Thread Alexey Khoroshilov
Almost all spi drivers assign spi master->dev.of_node from
its parent platform device without additional refcounting.
It seems of_node_get() in pic32_spi_probe() is unnecessary
and there is no corresponding of_node_put().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/spi/spi-pic32.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-pic32.c b/drivers/spi/spi-pic32.c
index f8a45af1fa9f..46ff76193ee1 100644
--- a/drivers/spi/spi-pic32.c
+++ b/drivers/spi/spi-pic32.c
@@ -774,7 +774,7 @@ static int pic32_spi_probe(struct platform_device *pdev)
if (ret)
goto err_master;
 
-   master->dev.of_node = of_node_get(pdev->dev.of_node);
+   master->dev.of_node = pdev->dev.of_node;
master->mode_bits   = SPI_MODE_3 | SPI_MODE_0 | SPI_CS_HIGH;
master->num_chipselect  = 1; /* single chip-select */
master->max_speed_hz= clk_get_rate(pic32s->clk);
-- 
2.7.4



[PATCH] gpio: dwapb: Fix error handling in dwapb_gpio_probe()

2018-08-28 Thread Alexey Khoroshilov
If dwapb_gpio_add_port() fails in dwapb_gpio_probe(),
gpio->clk is left undisabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/gpio/gpio-dwapb.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
index 28da700f5f52..044888fd96a1 100644
--- a/drivers/gpio/gpio-dwapb.c
+++ b/drivers/gpio/gpio-dwapb.c
@@ -728,6 +728,7 @@ static int dwapb_gpio_probe(struct platform_device *pdev)
 out_unregister:
dwapb_gpio_unregister(gpio);
dwapb_irq_teardown(gpio);
+   clk_disable_unprepare(gpio->clk);
 
return err;
 }
-- 
2.7.4



[PATCH] gpio: dwapb: Fix error handling in dwapb_gpio_probe()

2018-08-28 Thread Alexey Khoroshilov
If dwapb_gpio_add_port() fails in dwapb_gpio_probe(),
gpio->clk is left undisabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/gpio/gpio-dwapb.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
index 28da700f5f52..044888fd96a1 100644
--- a/drivers/gpio/gpio-dwapb.c
+++ b/drivers/gpio/gpio-dwapb.c
@@ -728,6 +728,7 @@ static int dwapb_gpio_probe(struct platform_device *pdev)
 out_unregister:
dwapb_gpio_unregister(gpio);
dwapb_irq_teardown(gpio);
+   clk_disable_unprepare(gpio->clk);
 
return err;
 }
-- 
2.7.4



[PATCH] clk: cdce925: release child device nodes

2018-08-21 Thread Alexey Khoroshilov
of_get_child_by_name() returns device node with refcount incremented,
but there is no decrement in cdce925_probe(). The patch adds one.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/clk/clk-cdce925.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c
index 0a7e7d5a7506..e9c3ffad4ac3 100644
--- a/drivers/clk/clk-cdce925.c
+++ b/drivers/clk/clk-cdce925.c
@@ -703,6 +703,7 @@ static int cdce925_probe(struct i2c_client *client,
0x12 + (i*CDCE925_OFFSET_PLL),
0x07, value & 0x07);
}
+   of_node_put(np_output);
}
 
/* Register output clock Y1 */
-- 
2.7.4



[PATCH] clk: cdce925: release child device nodes

2018-08-21 Thread Alexey Khoroshilov
of_get_child_by_name() returns device node with refcount incremented,
but there is no decrement in cdce925_probe(). The patch adds one.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/clk/clk-cdce925.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c
index 0a7e7d5a7506..e9c3ffad4ac3 100644
--- a/drivers/clk/clk-cdce925.c
+++ b/drivers/clk/clk-cdce925.c
@@ -703,6 +703,7 @@ static int cdce925_probe(struct i2c_client *client,
0x12 + (i*CDCE925_OFFSET_PLL),
0x07, value & 0x07);
}
+   of_node_put(np_output);
}
 
/* Register output clock Y1 */
-- 
2.7.4



[PATCH] rtc: isl1208: fix error handling in isl1208_probe()

2018-08-08 Thread Alexey Khoroshilov
After moving rtc_register_device() sysfs group is left unremoved
on the error path.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
Fixes: 236b7187034e ("rtc: isl1208: switch to rtc_register_device")
---
 drivers/rtc/rtc-isl1208.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index 1a2c38cc0178..4b5df9bfb8d4 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -674,7 +674,12 @@ isl1208_probe(struct i2c_client *client, const struct 
i2c_device_id *id)
}
}
 
-   return rtc_register_device(rtc);
+   rc = rtc_register_device(rtc);
+   if (rc) {
+   sysfs_remove_group(>dev.kobj, _rtc_sysfs_files);
+   return rc;
+   }
+   return 0;
 }
 
 static int
-- 
2.7.4



[PATCH] rtc: isl1208: fix error handling in isl1208_probe()

2018-08-08 Thread Alexey Khoroshilov
After moving rtc_register_device() sysfs group is left unremoved
on the error path.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
Fixes: 236b7187034e ("rtc: isl1208: switch to rtc_register_device")
---
 drivers/rtc/rtc-isl1208.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index 1a2c38cc0178..4b5df9bfb8d4 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -674,7 +674,12 @@ isl1208_probe(struct i2c_client *client, const struct 
i2c_device_id *id)
}
}
 
-   return rtc_register_device(rtc);
+   rc = rtc_register_device(rtc);
+   if (rc) {
+   sysfs_remove_group(>dev.kobj, _rtc_sysfs_files);
+   return rc;
+   }
+   return 0;
 }
 
 static int
-- 
2.7.4



[PATCH] ASoC: tegra_alc5632: fix device_node refcounting

2018-07-27 Thread Alexey Khoroshilov
tegra_alc5632_probe() increments reference count of device nodes
with of_parse_phandle(), but there is no code decrementing them
in the driver.

The patch adds of_node_put() to tegra_alc5632_remove() and
to error handling paths in the probe.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 sound/soc/tegra/tegra_alc5632.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index 5197d6b18cb6..98d87801d57a 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -190,14 +190,14 @@ static int tegra_alc5632_probe(struct platform_device 
*pdev)
dev_err(>dev,
"Property 'nvidia,i2s-controller' missing or 
invalid\n");
ret = -EINVAL;
-   goto err;
+   goto err_put_codec_of_node;
}
 
tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_of_node;
 
ret = tegra_asoc_utils_init(>util_data, >dev);
if (ret)
-   goto err;
+   goto err_put_cpu_of_node;
 
ret = snd_soc_register_card(card);
if (ret) {
@@ -210,6 +210,13 @@ static int tegra_alc5632_probe(struct platform_device 
*pdev)
 
 err_fini_utils:
tegra_asoc_utils_fini(>util_data);
+err_put_cpu_of_node:
+   of_node_put(tegra_alc5632_dai.cpu_of_node);
+   tegra_alc5632_dai.cpu_of_node = NULL;
+   tegra_alc5632_dai.platform_of_node = NULL;
+err_put_codec_of_node:
+   of_node_put(tegra_alc5632_dai.codec_of_node);
+   tegra_alc5632_dai.codec_of_node = NULL;
 err:
return ret;
 }
@@ -223,6 +230,12 @@ static int tegra_alc5632_remove(struct platform_device 
*pdev)
 
tegra_asoc_utils_fini(>util_data);
 
+   of_node_put(tegra_alc5632_dai.cpu_of_node);
+   tegra_alc5632_dai.cpu_of_node = NULL;
+   tegra_alc5632_dai.platform_of_node = NULL;
+   of_node_put(tegra_alc5632_dai.codec_of_node);
+   tegra_alc5632_dai.codec_of_node = NULL;
+
return 0;
 }
 
-- 
2.7.4



[PATCH] ASoC: tegra_alc5632: fix device_node refcounting

2018-07-27 Thread Alexey Khoroshilov
tegra_alc5632_probe() increments reference count of device nodes
with of_parse_phandle(), but there is no code decrementing them
in the driver.

The patch adds of_node_put() to tegra_alc5632_remove() and
to error handling paths in the probe.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 sound/soc/tegra/tegra_alc5632.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index 5197d6b18cb6..98d87801d57a 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -190,14 +190,14 @@ static int tegra_alc5632_probe(struct platform_device 
*pdev)
dev_err(>dev,
"Property 'nvidia,i2s-controller' missing or 
invalid\n");
ret = -EINVAL;
-   goto err;
+   goto err_put_codec_of_node;
}
 
tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_of_node;
 
ret = tegra_asoc_utils_init(>util_data, >dev);
if (ret)
-   goto err;
+   goto err_put_cpu_of_node;
 
ret = snd_soc_register_card(card);
if (ret) {
@@ -210,6 +210,13 @@ static int tegra_alc5632_probe(struct platform_device 
*pdev)
 
 err_fini_utils:
tegra_asoc_utils_fini(>util_data);
+err_put_cpu_of_node:
+   of_node_put(tegra_alc5632_dai.cpu_of_node);
+   tegra_alc5632_dai.cpu_of_node = NULL;
+   tegra_alc5632_dai.platform_of_node = NULL;
+err_put_codec_of_node:
+   of_node_put(tegra_alc5632_dai.codec_of_node);
+   tegra_alc5632_dai.codec_of_node = NULL;
 err:
return ret;
 }
@@ -223,6 +230,12 @@ static int tegra_alc5632_remove(struct platform_device 
*pdev)
 
tegra_asoc_utils_fini(>util_data);
 
+   of_node_put(tegra_alc5632_dai.cpu_of_node);
+   tegra_alc5632_dai.cpu_of_node = NULL;
+   tegra_alc5632_dai.platform_of_node = NULL;
+   of_node_put(tegra_alc5632_dai.codec_of_node);
+   tegra_alc5632_dai.codec_of_node = NULL;
+
return 0;
 }
 
-- 
2.7.4



regulator: bcm590xx: of_node_put(np) missing

2018-07-21 Thread Alexey Khoroshilov
Hello,

bcm590xx_parse_dt_reg_data() calls of_node_get(np),
but there is nowhere of_node_put(np) in the driver.
Should we add of_node_put(np) and what is timeframe of_node_get(np) required 
for?

Found by Linux Driver Verification project (linuxtesting.org).

--
Alexey Khoroshilov
Linux Verification Center, ISPRAS
web: http://linuxtesting.org



regulator: bcm590xx: of_node_put(np) missing

2018-07-21 Thread Alexey Khoroshilov
Hello,

bcm590xx_parse_dt_reg_data() calls of_node_get(np),
but there is nowhere of_node_put(np) in the driver.
Should we add of_node_put(np) and what is timeframe of_node_get(np) required 
for?

Found by Linux Driver Verification project (linuxtesting.org).

--
Alexey Khoroshilov
Linux Verification Center, ISPRAS
web: http://linuxtesting.org



Re: [PATCH] Input: pxrc - fix leak of usb_device

2018-07-15 Thread Alexey Khoroshilov
Dear Marcus,

On 15.07.2018 10:42, Marcus Folkesson wrote:
> On Sat, Jul 14, 2018 at 08:51:09AM +, Dmitry Torokhov wrote:
>> On Sat, Jul 14, 2018 at 10:09:20AM +0200, Marcus Folkesson wrote:
>>> Hi Alexey,
>>>
>>> Good catch!
>>>
>>> On Fri, Jul 13, 2018 at 11:07:57PM +0300, Alexey Khoroshilov wrote:
>>>> pxrc_probe() calls usb_get_dev(), but there is no usb_put_dev()
>>>> anywhere in the driver.
>>>>
>>>> The patch adds one to error handling code and to pxrc_isconnect().
>>>>
>>>> Found by Linux Driver Verification project (linuxtesting.org).
>>>>
>>>> Signed-off-by: Alexey Khoroshilov 
>>>
>>> Reviewed-by: Marcus Folkesson 
>>
>> Hmm, the biggest question however if we need to "take" the device, as I
>> do not think interface can outlive the device, and whether we actually
>> need to store it in pxrc, as we only need it during set up, as far as I
>> can see.
> 
> Yep, the device is only used during setup.
> I interpret the comments for usb_get_dev() as you should take a
> reference count on the device even if you only use the interface, but I
> could be wrong.
> 
>>From usb_get_dev()::
> 
>* usb_get_dev - increments the reference count of the usb device 
> structure
>* @dev: the device being referenced
>*
>* Each live reference to a device should be refcounted.
>*
>* Drivers for USB interfaces should normally record such references in
>* their probe() methods, when they bind to an interface, and release
>* them by calling usb_put_dev(), in their disconnect() methods.
> 
> I can fix the driver to not take the device if that is what we want.
> If not Alexey want to fix it of course, it is his catch :-)

As far as I can see the proposed solution requires some refactoring of
the init code. So, I believe the author is in the better position to do
that.

Best regards,
Alexey


Re: [PATCH] Input: pxrc - fix leak of usb_device

2018-07-15 Thread Alexey Khoroshilov
Dear Marcus,

On 15.07.2018 10:42, Marcus Folkesson wrote:
> On Sat, Jul 14, 2018 at 08:51:09AM +, Dmitry Torokhov wrote:
>> On Sat, Jul 14, 2018 at 10:09:20AM +0200, Marcus Folkesson wrote:
>>> Hi Alexey,
>>>
>>> Good catch!
>>>
>>> On Fri, Jul 13, 2018 at 11:07:57PM +0300, Alexey Khoroshilov wrote:
>>>> pxrc_probe() calls usb_get_dev(), but there is no usb_put_dev()
>>>> anywhere in the driver.
>>>>
>>>> The patch adds one to error handling code and to pxrc_isconnect().
>>>>
>>>> Found by Linux Driver Verification project (linuxtesting.org).
>>>>
>>>> Signed-off-by: Alexey Khoroshilov 
>>>
>>> Reviewed-by: Marcus Folkesson 
>>
>> Hmm, the biggest question however if we need to "take" the device, as I
>> do not think interface can outlive the device, and whether we actually
>> need to store it in pxrc, as we only need it during set up, as far as I
>> can see.
> 
> Yep, the device is only used during setup.
> I interpret the comments for usb_get_dev() as you should take a
> reference count on the device even if you only use the interface, but I
> could be wrong.
> 
>>From usb_get_dev()::
> 
>* usb_get_dev - increments the reference count of the usb device 
> structure
>* @dev: the device being referenced
>*
>* Each live reference to a device should be refcounted.
>*
>* Drivers for USB interfaces should normally record such references in
>* their probe() methods, when they bind to an interface, and release
>* them by calling usb_put_dev(), in their disconnect() methods.
> 
> I can fix the driver to not take the device if that is what we want.
> If not Alexey want to fix it of course, it is his catch :-)

As far as I can see the proposed solution requires some refactoring of
the init code. So, I believe the author is in the better position to do
that.

Best regards,
Alexey


[PATCH] Input: pxrc - fix leak of usb_device

2018-07-13 Thread Alexey Khoroshilov
pxrc_probe() calls usb_get_dev(), but there is no usb_put_dev()
anywhere in the driver.

The patch adds one to error handling code and to pxrc_disconnect().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/input/joystick/pxrc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/input/joystick/pxrc.c b/drivers/input/joystick/pxrc.c
index 07a0dbd3ced2..0a31de63ac8e 100644
--- a/drivers/input/joystick/pxrc.c
+++ b/drivers/input/joystick/pxrc.c
@@ -221,6 +221,7 @@ static int pxrc_probe(struct usb_interface *intf,
usb_free_urb(pxrc->urb);
 
 error:
+   usb_put_dev(pxrc->udev);
return retval;
 }
 
@@ -229,6 +230,7 @@ static void pxrc_disconnect(struct usb_interface *intf)
struct pxrc *pxrc = usb_get_intfdata(intf);
 
usb_free_urb(pxrc->urb);
+   usb_put_dev(pxrc->udev);
usb_set_intfdata(intf, NULL);
 }
 
-- 
2.7.4



[PATCH] Input: pxrc - fix leak of usb_device

2018-07-13 Thread Alexey Khoroshilov
pxrc_probe() calls usb_get_dev(), but there is no usb_put_dev()
anywhere in the driver.

The patch adds one to error handling code and to pxrc_disconnect().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/input/joystick/pxrc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/input/joystick/pxrc.c b/drivers/input/joystick/pxrc.c
index 07a0dbd3ced2..0a31de63ac8e 100644
--- a/drivers/input/joystick/pxrc.c
+++ b/drivers/input/joystick/pxrc.c
@@ -221,6 +221,7 @@ static int pxrc_probe(struct usb_interface *intf,
usb_free_urb(pxrc->urb);
 
 error:
+   usb_put_dev(pxrc->udev);
return retval;
 }
 
@@ -229,6 +230,7 @@ static void pxrc_disconnect(struct usb_interface *intf)
struct pxrc *pxrc = usb_get_intfdata(intf);
 
usb_free_urb(pxrc->urb);
+   usb_put_dev(pxrc->udev);
usb_set_intfdata(intf, NULL);
 }
 
-- 
2.7.4



[PATCH] sample: vfio-mdev: avoid deadlock in mdev_access()

2018-07-06 Thread Alexey Khoroshilov
mdev_access() calls mbochs_get_page() with mdev_state->ops_lock held,
while mbochs_get_page() locks the mutex by itself.
It leads to unavoidable deadlock.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 samples/vfio-mdev/mbochs.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index 2960e26c6ea4..6295a21381eb 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -178,6 +178,8 @@ static const char *vbe_name(u32 index)
return "(invalid)";
 }
 
+static struct page *__mbochs_get_page(struct mdev_state *mdev_state,
+ pgoff_t pgoff);
 static struct page *mbochs_get_page(struct mdev_state *mdev_state,
pgoff_t pgoff);
 
@@ -394,7 +396,7 @@ static ssize_t mdev_access(struct mdev_device *mdev, char 
*buf, size_t count,
   MBOCHS_MEMORY_BAR_OFFSET + mdev_state->memsize) {
pos -= MBOCHS_MMIO_BAR_OFFSET;
poff = pos & ~PAGE_MASK;
-   pg = mbochs_get_page(mdev_state, pos >> PAGE_SHIFT);
+   pg = __mbochs_get_page(mdev_state, pos >> PAGE_SHIFT);
map = kmap(pg);
if (is_write)
memcpy(map + poff, buf, count);
-- 
2.7.4



[PATCH] sample: vfio-mdev: avoid deadlock in mdev_access()

2018-07-06 Thread Alexey Khoroshilov
mdev_access() calls mbochs_get_page() with mdev_state->ops_lock held,
while mbochs_get_page() locks the mutex by itself.
It leads to unavoidable deadlock.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 samples/vfio-mdev/mbochs.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index 2960e26c6ea4..6295a21381eb 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -178,6 +178,8 @@ static const char *vbe_name(u32 index)
return "(invalid)";
 }
 
+static struct page *__mbochs_get_page(struct mdev_state *mdev_state,
+ pgoff_t pgoff);
 static struct page *mbochs_get_page(struct mdev_state *mdev_state,
pgoff_t pgoff);
 
@@ -394,7 +396,7 @@ static ssize_t mdev_access(struct mdev_device *mdev, char 
*buf, size_t count,
   MBOCHS_MEMORY_BAR_OFFSET + mdev_state->memsize) {
pos -= MBOCHS_MMIO_BAR_OFFSET;
poff = pos & ~PAGE_MASK;
-   pg = mbochs_get_page(mdev_state, pos >> PAGE_SHIFT);
+   pg = __mbochs_get_page(mdev_state, pos >> PAGE_SHIFT);
map = kmap(pg);
if (is_write)
memcpy(map + poff, buf, count);
-- 
2.7.4



[PATCH] ASoC: tegra: fix device_node refcounting

2018-06-15 Thread Alexey Khoroshilov
tegra_rt5677_probe() gets a couple of device nodes with of_parse_phandle(),
but there is no release of them.

The patch adds the release to tegra_rt5677_remove() and
to error handling paths in the probe.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 sound/soc/tegra/tegra_rt5677.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/sound/soc/tegra/tegra_rt5677.c b/sound/soc/tegra/tegra_rt5677.c
index 0e4805c7b4ca..7081f15302cc 100644
--- a/sound/soc/tegra/tegra_rt5677.c
+++ b/sound/soc/tegra/tegra_rt5677.c
@@ -264,13 +264,13 @@ static int tegra_rt5677_probe(struct platform_device 
*pdev)
dev_err(>dev,
"Property 'nvidia,i2s-controller' missing or 
invalid\n");
ret = -EINVAL;
-   goto err;
+   goto err_put_codec_of_node;
}
tegra_rt5677_dai.platform_of_node = tegra_rt5677_dai.cpu_of_node;
 
ret = tegra_asoc_utils_init(>util_data, >dev);
if (ret)
-   goto err;
+   goto err_put_cpu_of_node;
 
ret = snd_soc_register_card(card);
if (ret) {
@@ -283,6 +283,13 @@ static int tegra_rt5677_probe(struct platform_device *pdev)
 
 err_fini_utils:
tegra_asoc_utils_fini(>util_data);
+err_put_cpu_of_node:
+   of_node_put(tegra_rt5677_dai.cpu_of_node);
+   tegra_rt5677_dai.cpu_of_node = NULL;
+   tegra_rt5677_dai.platform_of_node = NULL;
+err_put_codec_of_node:
+   of_node_put(tegra_rt5677_dai.codec_of_node);
+   tegra_rt5677_dai.codec_of_node = NULL;
 err:
return ret;
 }
@@ -296,6 +303,12 @@ static int tegra_rt5677_remove(struct platform_device 
*pdev)
 
tegra_asoc_utils_fini(>util_data);
 
+   tegra_rt5677_dai.platform_of_node = NULL;
+   of_node_put(tegra_rt5677_dai.codec_of_node);
+   tegra_rt5677_dai.codec_of_node = NULL;
+   of_node_put(tegra_rt5677_dai.cpu_of_node);
+   tegra_rt5677_dai.cpu_of_node = NULL;
+
return 0;
 }
 
-- 
2.7.4



[PATCH] ASoC: tegra: fix device_node refcounting

2018-06-15 Thread Alexey Khoroshilov
tegra_rt5677_probe() gets a couple of device nodes with of_parse_phandle(),
but there is no release of them.

The patch adds the release to tegra_rt5677_remove() and
to error handling paths in the probe.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 sound/soc/tegra/tegra_rt5677.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/sound/soc/tegra/tegra_rt5677.c b/sound/soc/tegra/tegra_rt5677.c
index 0e4805c7b4ca..7081f15302cc 100644
--- a/sound/soc/tegra/tegra_rt5677.c
+++ b/sound/soc/tegra/tegra_rt5677.c
@@ -264,13 +264,13 @@ static int tegra_rt5677_probe(struct platform_device 
*pdev)
dev_err(>dev,
"Property 'nvidia,i2s-controller' missing or 
invalid\n");
ret = -EINVAL;
-   goto err;
+   goto err_put_codec_of_node;
}
tegra_rt5677_dai.platform_of_node = tegra_rt5677_dai.cpu_of_node;
 
ret = tegra_asoc_utils_init(>util_data, >dev);
if (ret)
-   goto err;
+   goto err_put_cpu_of_node;
 
ret = snd_soc_register_card(card);
if (ret) {
@@ -283,6 +283,13 @@ static int tegra_rt5677_probe(struct platform_device *pdev)
 
 err_fini_utils:
tegra_asoc_utils_fini(>util_data);
+err_put_cpu_of_node:
+   of_node_put(tegra_rt5677_dai.cpu_of_node);
+   tegra_rt5677_dai.cpu_of_node = NULL;
+   tegra_rt5677_dai.platform_of_node = NULL;
+err_put_codec_of_node:
+   of_node_put(tegra_rt5677_dai.codec_of_node);
+   tegra_rt5677_dai.codec_of_node = NULL;
 err:
return ret;
 }
@@ -296,6 +303,12 @@ static int tegra_rt5677_remove(struct platform_device 
*pdev)
 
tegra_asoc_utils_fini(>util_data);
 
+   tegra_rt5677_dai.platform_of_node = NULL;
+   of_node_put(tegra_rt5677_dai.codec_of_node);
+   tegra_rt5677_dai.codec_of_node = NULL;
+   of_node_put(tegra_rt5677_dai.cpu_of_node);
+   tegra_rt5677_dai.cpu_of_node = NULL;
+
return 0;
 }
 
-- 
2.7.4



[PATCH] ASoC: rockchip: put device_node on remove

2018-06-09 Thread Alexey Khoroshilov
snd_rk_mc_probe() gets a couple of device nodes with of_parse_phandle(),
but there is no release of them.

The patch adds remove handler and proper error handling in the probe.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 sound/soc/rockchip/rockchip_rt5645.c | 27 ---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/sound/soc/rockchip/rockchip_rt5645.c 
b/sound/soc/rockchip/rockchip_rt5645.c
index 4db4fd56db35..881c32498808 100644
--- a/sound/soc/rockchip/rockchip_rt5645.c
+++ b/sound/soc/rockchip/rockchip_rt5645.c
@@ -181,7 +181,8 @@ static int snd_rk_mc_probe(struct platform_device *pdev)
if (!rk_dailink.cpu_of_node) {
dev_err(>dev,
"Property 'rockchip,i2s-controller' missing or 
invalid\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto put_codec_of_node;
}
 
rk_dailink.platform_of_node = rk_dailink.cpu_of_node;
@@ -190,17 +191,36 @@ static int snd_rk_mc_probe(struct platform_device *pdev)
if (ret) {
dev_err(>dev,
"Soc parse card name failed %d\n", ret);
-   return ret;
+   goto put_cpu_of_node;
}
 
ret = devm_snd_soc_register_card(>dev, card);
if (ret) {
dev_err(>dev,
"Soc register card failed %d\n", ret);
-   return ret;
+   goto put_cpu_of_node;
}
 
return ret;
+
+put_cpu_of_node:
+   of_node_put(rk_dailink.cpu_of_node);
+   rk_dailink.cpu_of_node = NULL;
+put_codec_of_node:
+   of_node_put(rk_dailink.codec_of_node);
+   rk_dailink.codec_of_node = NULL;
+
+   return ret;
+}
+
+static int snd_rk_mc_remove(struct platform_device *pdev)
+{
+   of_node_put(rk_dailink.cpu_of_node);
+   rk_dailink.cpu_of_node = NULL;
+   of_node_put(rk_dailink.codec_of_node);
+   rk_dailink.codec_of_node = NULL;
+
+   return 0;
 }
 
 static const struct of_device_id rockchip_rt5645_of_match[] = {
@@ -212,6 +232,7 @@ MODULE_DEVICE_TABLE(of, rockchip_rt5645_of_match);
 
 static struct platform_driver snd_rk_mc_driver = {
.probe = snd_rk_mc_probe,
+   .remove = snd_rk_mc_remove,
.driver = {
.name = DRV_NAME,
.pm = _soc_pm_ops,
-- 
2.7.4



[PATCH] ASoC: rockchip: put device_node on remove

2018-06-09 Thread Alexey Khoroshilov
snd_rk_mc_probe() gets a couple of device nodes with of_parse_phandle(),
but there is no release of them.

The patch adds remove handler and proper error handling in the probe.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 sound/soc/rockchip/rockchip_rt5645.c | 27 ---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/sound/soc/rockchip/rockchip_rt5645.c 
b/sound/soc/rockchip/rockchip_rt5645.c
index 4db4fd56db35..881c32498808 100644
--- a/sound/soc/rockchip/rockchip_rt5645.c
+++ b/sound/soc/rockchip/rockchip_rt5645.c
@@ -181,7 +181,8 @@ static int snd_rk_mc_probe(struct platform_device *pdev)
if (!rk_dailink.cpu_of_node) {
dev_err(>dev,
"Property 'rockchip,i2s-controller' missing or 
invalid\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto put_codec_of_node;
}
 
rk_dailink.platform_of_node = rk_dailink.cpu_of_node;
@@ -190,17 +191,36 @@ static int snd_rk_mc_probe(struct platform_device *pdev)
if (ret) {
dev_err(>dev,
"Soc parse card name failed %d\n", ret);
-   return ret;
+   goto put_cpu_of_node;
}
 
ret = devm_snd_soc_register_card(>dev, card);
if (ret) {
dev_err(>dev,
"Soc register card failed %d\n", ret);
-   return ret;
+   goto put_cpu_of_node;
}
 
return ret;
+
+put_cpu_of_node:
+   of_node_put(rk_dailink.cpu_of_node);
+   rk_dailink.cpu_of_node = NULL;
+put_codec_of_node:
+   of_node_put(rk_dailink.codec_of_node);
+   rk_dailink.codec_of_node = NULL;
+
+   return ret;
+}
+
+static int snd_rk_mc_remove(struct platform_device *pdev)
+{
+   of_node_put(rk_dailink.cpu_of_node);
+   rk_dailink.cpu_of_node = NULL;
+   of_node_put(rk_dailink.codec_of_node);
+   rk_dailink.codec_of_node = NULL;
+
+   return 0;
 }
 
 static const struct of_device_id rockchip_rt5645_of_match[] = {
@@ -212,6 +232,7 @@ MODULE_DEVICE_TABLE(of, rockchip_rt5645_of_match);
 
 static struct platform_driver snd_rk_mc_driver = {
.probe = snd_rk_mc_probe,
+   .remove = snd_rk_mc_remove,
.driver = {
.name = DRV_NAME,
.pm = _soc_pm_ops,
-- 
2.7.4



[PATCH] power: reset: zx-reboot: put device node in zx_reboot_probe()

2018-06-02 Thread Alexey Khoroshilov
zx_reboot_probe() increments refcnt of zx296702-pcu device node by
of_find_compatible_node() and leaves it undecremented on both
successful and error paths.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/power/reset/zx-reboot.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/power/reset/zx-reboot.c b/drivers/power/reset/zx-reboot.c
index c03e96e6a041..186901c96c01 100644
--- a/drivers/power/reset/zx-reboot.c
+++ b/drivers/power/reset/zx-reboot.c
@@ -51,6 +51,7 @@ static int zx_reboot_probe(struct platform_device *pdev)
 
np = of_find_compatible_node(NULL, NULL, "zte,zx296702-pcu");
pcu_base = of_iomap(np, 0);
+   of_node_put(np);
if (!pcu_base) {
iounmap(base);
WARN(1, "failed to map pcu_base address");
-- 
2.7.4



[PATCH] power: reset: zx-reboot: put device node in zx_reboot_probe()

2018-06-02 Thread Alexey Khoroshilov
zx_reboot_probe() increments refcnt of zx296702-pcu device node by
of_find_compatible_node() and leaves it undecremented on both
successful and error paths.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/power/reset/zx-reboot.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/power/reset/zx-reboot.c b/drivers/power/reset/zx-reboot.c
index c03e96e6a041..186901c96c01 100644
--- a/drivers/power/reset/zx-reboot.c
+++ b/drivers/power/reset/zx-reboot.c
@@ -51,6 +51,7 @@ static int zx_reboot_probe(struct platform_device *pdev)
 
np = of_find_compatible_node(NULL, NULL, "zte,zx296702-pcu");
pcu_base = of_iomap(np, 0);
+   of_node_put(np);
if (!pcu_base) {
iounmap(base);
WARN(1, "failed to map pcu_base address");
-- 
2.7.4



[PATCH] media: tc358743: release device_node in tc358743_probe_of()

2018-05-25 Thread Alexey Khoroshilov
of_graph_get_next_endpoint() returns device_node with refcnt increased,
but these is no of_node_put() for it.

The patch adds one on error and normal paths.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/media/i2c/tc358743.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 393baad7..44c41933415a 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -1918,7 +1918,8 @@ static int tc358743_probe_of(struct tc358743_state *state)
endpoint = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep));
if (IS_ERR(endpoint)) {
dev_err(dev, "failed to parse endpoint\n");
-   return PTR_ERR(endpoint);
+   ret = PTR_ERR(endpoint);
+   goto put_node;
}
 
if (endpoint->bus_type != V4L2_MBUS_CSI2 ||
@@ -2013,6 +2014,8 @@ static int tc358743_probe_of(struct tc358743_state *state)
clk_disable_unprepare(refclk);
 free_endpoint:
v4l2_fwnode_endpoint_free(endpoint);
+put_node:
+   of_node_put(ep);
return ret;
 }
 #else
-- 
2.7.4



[PATCH] media: tc358743: release device_node in tc358743_probe_of()

2018-05-25 Thread Alexey Khoroshilov
of_graph_get_next_endpoint() returns device_node with refcnt increased,
but these is no of_node_put() for it.

The patch adds one on error and normal paths.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/media/i2c/tc358743.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 393baad7..44c41933415a 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -1918,7 +1918,8 @@ static int tc358743_probe_of(struct tc358743_state *state)
endpoint = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep));
if (IS_ERR(endpoint)) {
dev_err(dev, "failed to parse endpoint\n");
-   return PTR_ERR(endpoint);
+   ret = PTR_ERR(endpoint);
+   goto put_node;
}
 
if (endpoint->bus_type != V4L2_MBUS_CSI2 ||
@@ -2013,6 +2014,8 @@ static int tc358743_probe_of(struct tc358743_state *state)
clk_disable_unprepare(refclk);
 free_endpoint:
v4l2_fwnode_endpoint_free(endpoint);
+put_node:
+   of_node_put(ep);
return ret;
 }
 #else
-- 
2.7.4



[PATCH] aic94xx: don't return zero on failure paths in aic94xx_init()

2018-05-18 Thread Alexey Khoroshilov
If sas_domain_attach_transport() fails in aic94xx_init(),
it breaks off initialization, deallocates all resources, but returns zero.

The patch adds -ENOMEM as return value in this case.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Peter Melnichenko <melniche...@ispras.ru>
Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/scsi/aic94xx/aic94xx_init.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/aic94xx/aic94xx_init.c 
b/drivers/scsi/aic94xx/aic94xx_init.c
index 6c838865ac5a..4a4746cc6745 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -1030,8 +1030,10 @@ static int __init aic94xx_init(void)
 
aic94xx_transport_template =
sas_domain_attach_transport(_transport_functions);
-   if (!aic94xx_transport_template)
+   if (!aic94xx_transport_template) {
+   err = -ENOMEM;
goto out_destroy_caches;
+   }
 
err = pci_register_driver(_pci_driver);
if (err)
-- 
2.7.4



[PATCH] aic94xx: don't return zero on failure paths in aic94xx_init()

2018-05-18 Thread Alexey Khoroshilov
If sas_domain_attach_transport() fails in aic94xx_init(),
it breaks off initialization, deallocates all resources, but returns zero.

The patch adds -ENOMEM as return value in this case.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Peter Melnichenko 
Signed-off-by: Alexey Khoroshilov 
---
 drivers/scsi/aic94xx/aic94xx_init.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/aic94xx/aic94xx_init.c 
b/drivers/scsi/aic94xx/aic94xx_init.c
index 6c838865ac5a..4a4746cc6745 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -1030,8 +1030,10 @@ static int __init aic94xx_init(void)
 
aic94xx_transport_template =
sas_domain_attach_transport(_transport_functions);
-   if (!aic94xx_transport_template)
+   if (!aic94xx_transport_template) {
+   err = -ENOMEM;
goto out_destroy_caches;
+   }
 
err = pci_register_driver(_pci_driver);
if (err)
-- 
2.7.4



[PATCH v3] mtd: nxp-spifi: release flash_np in nxp_spifi_probe()

2018-05-09 Thread Alexey Khoroshilov
nxp_spifi_probe() increments refcnt of SPI flash device node by
of_get_next_available_child() and leaves it undecremented on both
successful and error paths.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
v3: Move of_node_put() before return value check as Boris Brezillon suggested.

 drivers/mtd/spi-nor/nxp-spifi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/spi-nor/nxp-spifi.c b/drivers/mtd/spi-nor/nxp-spifi.c
index 15374216d4d9..0c9094ec5966 100644
--- a/drivers/mtd/spi-nor/nxp-spifi.c
+++ b/drivers/mtd/spi-nor/nxp-spifi.c
@@ -436,6 +436,7 @@ static int nxp_spifi_probe(struct platform_device *pdev)
}
 
ret = nxp_spifi_setup_flash(spifi, flash_np);
+   of_node_put(flash_np);
if (ret) {
dev_err(>dev, "unable to setup flash chip\n");
goto dis_clks;
-- 
2.7.4



[PATCH v3] mtd: nxp-spifi: release flash_np in nxp_spifi_probe()

2018-05-09 Thread Alexey Khoroshilov
nxp_spifi_probe() increments refcnt of SPI flash device node by
of_get_next_available_child() and leaves it undecremented on both
successful and error paths.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
v3: Move of_node_put() before return value check as Boris Brezillon suggested.

 drivers/mtd/spi-nor/nxp-spifi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/spi-nor/nxp-spifi.c b/drivers/mtd/spi-nor/nxp-spifi.c
index 15374216d4d9..0c9094ec5966 100644
--- a/drivers/mtd/spi-nor/nxp-spifi.c
+++ b/drivers/mtd/spi-nor/nxp-spifi.c
@@ -436,6 +436,7 @@ static int nxp_spifi_probe(struct platform_device *pdev)
}
 
ret = nxp_spifi_setup_flash(spifi, flash_np);
+   of_node_put(flash_np);
if (ret) {
dev_err(>dev, "unable to setup flash chip\n");
goto dis_clks;
-- 
2.7.4



[PATCH v2] mtd: nxp-spifi: release flash_np in nxp_spifi_probe()

2018-05-09 Thread Alexey Khoroshilov
nxp_spifi_probe() increments refcnt of SPI flash device node by
of_get_next_available_child() and leaves it undecremented on both
successful and error paths.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/mtd/spi-nor/nxp-spifi.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/nxp-spifi.c b/drivers/mtd/spi-nor/nxp-spifi.c
index 15374216d4d9..7b047951d0a2 100644
--- a/drivers/mtd/spi-nor/nxp-spifi.c
+++ b/drivers/mtd/spi-nor/nxp-spifi.c
@@ -438,11 +438,15 @@ static int nxp_spifi_probe(struct platform_device *pdev)
ret = nxp_spifi_setup_flash(spifi, flash_np);
if (ret) {
dev_err(>dev, "unable to setup flash chip\n");
-   goto dis_clks;
+   goto put_np;
}
 
+   of_node_put(flash_np);
+
return 0;
 
+put_np:
+   of_node_put(flash_np);
 dis_clks:
clk_disable_unprepare(spifi->clk_spifi);
 dis_clk_reg:
-- 
2.7.4



[PATCH v2] mtd: nxp-spifi: release flash_np in nxp_spifi_probe()

2018-05-09 Thread Alexey Khoroshilov
nxp_spifi_probe() increments refcnt of SPI flash device node by
of_get_next_available_child() and leaves it undecremented on both
successful and error paths.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/mtd/spi-nor/nxp-spifi.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/nxp-spifi.c b/drivers/mtd/spi-nor/nxp-spifi.c
index 15374216d4d9..7b047951d0a2 100644
--- a/drivers/mtd/spi-nor/nxp-spifi.c
+++ b/drivers/mtd/spi-nor/nxp-spifi.c
@@ -438,11 +438,15 @@ static int nxp_spifi_probe(struct platform_device *pdev)
ret = nxp_spifi_setup_flash(spifi, flash_np);
if (ret) {
dev_err(>dev, "unable to setup flash chip\n");
-   goto dis_clks;
+   goto put_np;
}
 
+   of_node_put(flash_np);
+
return 0;
 
+put_np:
+   of_node_put(flash_np);
 dis_clks:
clk_disable_unprepare(spifi->clk_spifi);
 dis_clk_reg:
-- 
2.7.4



Re: [PATCH] mtd: nxp-spifi: decrement flash_np refcnt on error paths

2018-05-09 Thread Alexey Khoroshilov
On 09.05.2018 12:42, Boris Brezillon wrote:
> On Tue,  8 May 2018 23:47:36 +0300
> Alexey Khoroshilov <khoroshi...@ispras.ru> wrote:
> 
>> nxp_spifi_probe() increments refcnt of SPI flash device node by
>> of_get_next_available_child() and then it passes the node
>> to mtd device in nxp_spifi_setup_flash().
>> But if a failure happens before mtd_device_register() succeed,
>> the refcnt is left undecremented.
> 
> Why not doing that in the error path of the probe function? Also, you
> probably want to call of_node_put() in the ->remove() function.
> 


You are right.

I believed that after successful mtd_device_register()
the node is managed by mtd device. I missed that it calls of_node_get()
in add_mtd_device() by itself.

I will prepare v2.
But I guess there is no need to have of_node_put() in ->remove(), since
probe() finishes its own usage of flash_np, while mtd_device incremented
refcnt by itself and will decrement it in ->remove() in
mtd_device_unregister(>nor.mtd). So, I would propose
of_node_put() on both successful and error path.

Thank you,
Alexey


Re: [PATCH] mtd: nxp-spifi: decrement flash_np refcnt on error paths

2018-05-09 Thread Alexey Khoroshilov
On 09.05.2018 12:42, Boris Brezillon wrote:
> On Tue,  8 May 2018 23:47:36 +0300
> Alexey Khoroshilov  wrote:
> 
>> nxp_spifi_probe() increments refcnt of SPI flash device node by
>> of_get_next_available_child() and then it passes the node
>> to mtd device in nxp_spifi_setup_flash().
>> But if a failure happens before mtd_device_register() succeed,
>> the refcnt is left undecremented.
> 
> Why not doing that in the error path of the probe function? Also, you
> probably want to call of_node_put() in the ->remove() function.
> 


You are right.

I believed that after successful mtd_device_register()
the node is managed by mtd device. I missed that it calls of_node_get()
in add_mtd_device() by itself.

I will prepare v2.
But I guess there is no need to have of_node_put() in ->remove(), since
probe() finishes its own usage of flash_np, while mtd_device incremented
refcnt by itself and will decrement it in ->remove() in
mtd_device_unregister(>nor.mtd). So, I would propose
of_node_put() on both successful and error path.

Thank you,
Alexey


[PATCH] mtd: nxp-spifi: decrement flash_np refcnt on error paths

2018-05-08 Thread Alexey Khoroshilov
nxp_spifi_probe() increments refcnt of SPI flash device node by
of_get_next_available_child() and then it passes the node
to mtd device in nxp_spifi_setup_flash().
But if a failure happens before mtd_device_register() succeed,
the refcnt is left undecremented.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/mtd/spi-nor/nxp-spifi.c | 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/spi-nor/nxp-spifi.c b/drivers/mtd/spi-nor/nxp-spifi.c
index 15374216d4d9..8919e31f2ab8 100644
--- a/drivers/mtd/spi-nor/nxp-spifi.c
+++ b/drivers/mtd/spi-nor/nxp-spifi.c
@@ -294,7 +294,8 @@ static int nxp_spifi_setup_flash(struct nxp_spifi *spifi,
break;
default:
dev_err(spifi->dev, "unsupported rx-bus-width\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto err_node_put;
}
}
 
@@ -328,7 +329,8 @@ static int nxp_spifi_setup_flash(struct nxp_spifi *spifi,
break;
default:
dev_err(spifi->dev, "only mode 0 and 3 supported\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto err_node_put;
}
 
writel(ctrl, spifi->io_base + SPIFI_CTRL);
@@ -356,22 +358,26 @@ static int nxp_spifi_setup_flash(struct nxp_spifi *spifi,
ret = spi_nor_scan(>nor, NULL, );
if (ret) {
dev_err(spifi->dev, "device scan failed\n");
-   return ret;
+   goto err_node_put;
}
 
ret = nxp_spifi_setup_memory_cmd(spifi);
if (ret) {
dev_err(spifi->dev, "memory command setup failed\n");
-   return ret;
+   goto err_node_put;
}
 
ret = mtd_device_register(>nor.mtd, NULL, 0);
if (ret) {
dev_err(spifi->dev, "mtd device parse failed\n");
-   return ret;
+   goto err_node_put;
}
 
return 0;
+
+err_node_put:
+   of_node_put(np);
+   return ret;
 }
 
 static int nxp_spifi_probe(struct platform_device *pdev)
-- 
2.7.4



[PATCH] mtd: nxp-spifi: decrement flash_np refcnt on error paths

2018-05-08 Thread Alexey Khoroshilov
nxp_spifi_probe() increments refcnt of SPI flash device node by
of_get_next_available_child() and then it passes the node
to mtd device in nxp_spifi_setup_flash().
But if a failure happens before mtd_device_register() succeed,
the refcnt is left undecremented.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/mtd/spi-nor/nxp-spifi.c | 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/spi-nor/nxp-spifi.c b/drivers/mtd/spi-nor/nxp-spifi.c
index 15374216d4d9..8919e31f2ab8 100644
--- a/drivers/mtd/spi-nor/nxp-spifi.c
+++ b/drivers/mtd/spi-nor/nxp-spifi.c
@@ -294,7 +294,8 @@ static int nxp_spifi_setup_flash(struct nxp_spifi *spifi,
break;
default:
dev_err(spifi->dev, "unsupported rx-bus-width\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto err_node_put;
}
}
 
@@ -328,7 +329,8 @@ static int nxp_spifi_setup_flash(struct nxp_spifi *spifi,
break;
default:
dev_err(spifi->dev, "only mode 0 and 3 supported\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto err_node_put;
}
 
writel(ctrl, spifi->io_base + SPIFI_CTRL);
@@ -356,22 +358,26 @@ static int nxp_spifi_setup_flash(struct nxp_spifi *spifi,
ret = spi_nor_scan(>nor, NULL, );
if (ret) {
dev_err(spifi->dev, "device scan failed\n");
-   return ret;
+   goto err_node_put;
}
 
ret = nxp_spifi_setup_memory_cmd(spifi);
if (ret) {
dev_err(spifi->dev, "memory command setup failed\n");
-   return ret;
+   goto err_node_put;
}
 
ret = mtd_device_register(>nor.mtd, NULL, 0);
if (ret) {
dev_err(spifi->dev, "mtd device parse failed\n");
-   return ret;
+   goto err_node_put;
}
 
return 0;
+
+err_node_put:
+   of_node_put(np);
+   return ret;
 }
 
 static int nxp_spifi_probe(struct platform_device *pdev)
-- 
2.7.4



Re: [PATCH] power: supply: ltc2941-battery-gauge: Release device_node in ltc294x_i2c_probe()

2018-05-08 Thread Alexey Khoroshilov

Hi,

On 01.05.2018 15:39, Sebastian Reichel wrote:
> Hi,
> 
> On Sun, Apr 29, 2018 at 01:35:55AM +0300, Alexey Khoroshilov wrote:
>> There is of_node_get(client->dev.of_node) in ltc294x_i2c_probe(),
>> but these is no of_node_put() somethere in the driver.
>>
>> The patch adds one on error and normal paths.
>>
>> Found by Linux Driver Verification project (linuxtesting.org).
>>
>> Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
> 
> That is ugly. Let's replace of_property_read_u32(np, ...) with
> device_property_read_u32(dev, ...) and get rid of np instead.
> 

Ok, I will prepare v2.

What is the right way to replace
info->supply_desc.name = np->name;
?

If lifetime of 'client->dev.of_node' = 'np' cannot be less than lifetime
of 'client->dev', should we use just
info->supply_desc.name = client->dev.of_node->name;
?

Thank you,
Alexey


Re: [PATCH] power: supply: ltc2941-battery-gauge: Release device_node in ltc294x_i2c_probe()

2018-05-08 Thread Alexey Khoroshilov

Hi,

On 01.05.2018 15:39, Sebastian Reichel wrote:
> Hi,
> 
> On Sun, Apr 29, 2018 at 01:35:55AM +0300, Alexey Khoroshilov wrote:
>> There is of_node_get(client->dev.of_node) in ltc294x_i2c_probe(),
>> but these is no of_node_put() somethere in the driver.
>>
>> The patch adds one on error and normal paths.
>>
>> Found by Linux Driver Verification project (linuxtesting.org).
>>
>> Signed-off-by: Alexey Khoroshilov 
> 
> That is ugly. Let's replace of_property_read_u32(np, ...) with
> device_property_read_u32(dev, ...) and get rid of np instead.
> 

Ok, I will prepare v2.

What is the right way to replace
info->supply_desc.name = np->name;
?

If lifetime of 'client->dev.of_node' = 'np' cannot be less than lifetime
of 'client->dev', should we use just
info->supply_desc.name = client->dev.of_node->name;
?

Thank you,
Alexey


[PATCH v2] spi: meson-spicc: Fix error handling in meson_spicc_probe()

2018-04-28 Thread Alexey Khoroshilov
If devm_spi_register_master() fails in meson_spicc_probe(),
spicc->core is left undisabled. The patch fixes that.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
Reviewed-by: Neil Armstrong <narmstr...@baylibre.com>
---
v2: Fix subject as Neil Armstrong noted.

 drivers/spi/spi-meson-spicc.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c
index 5c82910e3480..7fe4488ace57 100644
--- a/drivers/spi/spi-meson-spicc.c
+++ b/drivers/spi/spi-meson-spicc.c
@@ -574,10 +574,15 @@ static int meson_spicc_probe(struct platform_device *pdev)
master->max_speed_hz = rate >> 2;
 
ret = devm_spi_register_master(>dev, master);
-   if (!ret)
-   return 0;
+   if (ret) {
+   dev_err(>dev, "spi master registration failed\n");
+   goto out_clk;
+   }
 
-   dev_err(>dev, "spi master registration failed\n");
+   return 0;
+
+out_clk:
+   clk_disable_unprepare(spicc->core);
 
 out_master:
spi_master_put(master);
-- 
2.7.4



[PATCH v2] spi: meson-spicc: Fix error handling in meson_spicc_probe()

2018-04-28 Thread Alexey Khoroshilov
If devm_spi_register_master() fails in meson_spicc_probe(),
spicc->core is left undisabled. The patch fixes that.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
Reviewed-by: Neil Armstrong 
---
v2: Fix subject as Neil Armstrong noted.

 drivers/spi/spi-meson-spicc.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c
index 5c82910e3480..7fe4488ace57 100644
--- a/drivers/spi/spi-meson-spicc.c
+++ b/drivers/spi/spi-meson-spicc.c
@@ -574,10 +574,15 @@ static int meson_spicc_probe(struct platform_device *pdev)
master->max_speed_hz = rate >> 2;
 
ret = devm_spi_register_master(>dev, master);
-   if (!ret)
-   return 0;
+   if (ret) {
+   dev_err(>dev, "spi master registration failed\n");
+   goto out_clk;
+   }
 
-   dev_err(>dev, "spi master registration failed\n");
+   return 0;
+
+out_clk:
+   clk_disable_unprepare(spicc->core);
 
 out_master:
spi_master_put(master);
-- 
2.7.4



[PATCH] power: supply: ltc2941-battery-gauge: Release device_node in ltc294x_i2c_probe()

2018-04-28 Thread Alexey Khoroshilov
There is of_node_get(client->dev.of_node) in ltc294x_i2c_probe(),
but these is no of_node_put() somethere in the driver.

The patch adds one on error and normal paths.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/power/supply/ltc2941-battery-gauge.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/power/supply/ltc2941-battery-gauge.c 
b/drivers/power/supply/ltc2941-battery-gauge.c
index 4f129bb4c972..7854a89b3332 100644
--- a/drivers/power/supply/ltc2941-battery-gauge.c
+++ b/drivers/power/supply/ltc2941-battery-gauge.c
@@ -481,7 +481,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
if (ret < 0) {
dev_err(>dev,
"Could not find lltc,resistor-sense in devicetree\n");
-   return ret;
+   goto err_node_put;
}
info->r_sense = r_sense;
 
@@ -511,7 +511,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
if (ret < 0) {
dev_err(>dev,
"Could not read status register\n");
-   return ret;
+   goto err_node_put;
}
if (status & LTC2941_REG_STATUS_CHIP_ID)
info->id = LTC2941_ID;
@@ -550,19 +550,25 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
ret = ltc294x_reset(info, prescaler_exp);
if (ret < 0) {
dev_err(>dev, "Communication with chip failed\n");
-   return ret;
+   goto err_node_put;
}
 
info->supply = power_supply_register(>dev, >supply_desc,
 _cfg);
if (IS_ERR(info->supply)) {
dev_err(>dev, "failed to register ltc2941\n");
-   return PTR_ERR(info->supply);
+   ret = PTR_ERR(info->supply);
+   goto err_node_put;
} else {
schedule_delayed_work(>work, LTC294X_WORK_DELAY * HZ);
}
 
+   of_node_put(np);
return 0;
+
+err_node_put:
+   of_node_put(np);
+   return ret;
 }
 
 static void ltc294x_i2c_shutdown(struct i2c_client *client)
-- 
2.7.4



[PATCH] power: supply: ltc2941-battery-gauge: Release device_node in ltc294x_i2c_probe()

2018-04-28 Thread Alexey Khoroshilov
There is of_node_get(client->dev.of_node) in ltc294x_i2c_probe(),
but these is no of_node_put() somethere in the driver.

The patch adds one on error and normal paths.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/power/supply/ltc2941-battery-gauge.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/power/supply/ltc2941-battery-gauge.c 
b/drivers/power/supply/ltc2941-battery-gauge.c
index 4f129bb4c972..7854a89b3332 100644
--- a/drivers/power/supply/ltc2941-battery-gauge.c
+++ b/drivers/power/supply/ltc2941-battery-gauge.c
@@ -481,7 +481,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
if (ret < 0) {
dev_err(>dev,
"Could not find lltc,resistor-sense in devicetree\n");
-   return ret;
+   goto err_node_put;
}
info->r_sense = r_sense;
 
@@ -511,7 +511,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
if (ret < 0) {
dev_err(>dev,
"Could not read status register\n");
-   return ret;
+   goto err_node_put;
}
if (status & LTC2941_REG_STATUS_CHIP_ID)
info->id = LTC2941_ID;
@@ -550,19 +550,25 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
ret = ltc294x_reset(info, prescaler_exp);
if (ret < 0) {
dev_err(>dev, "Communication with chip failed\n");
-   return ret;
+   goto err_node_put;
}
 
info->supply = power_supply_register(>dev, >supply_desc,
 _cfg);
if (IS_ERR(info->supply)) {
dev_err(>dev, "failed to register ltc2941\n");
-   return PTR_ERR(info->supply);
+   ret = PTR_ERR(info->supply);
+   goto err_node_put;
} else {
schedule_delayed_work(>work, LTC294X_WORK_DELAY * HZ);
}
 
+   of_node_put(np);
return 0;
+
+err_node_put:
+   of_node_put(np);
+   return ret;
 }
 
 static void ltc294x_i2c_shutdown(struct i2c_client *client)
-- 
2.7.4



[PATCH] iio: adc: ad799x: Fix error handling in ad799x_probe()

2018-04-20 Thread Alexey Khoroshilov
In case of errors in write/read config, st->vref is left undisabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
Fixes: 0f7ddcc1bff1 ("iio:adc:ad799x: Write default config on probe and reset 
alert status on probe")
---
 drivers/iio/adc/ad799x.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c
index e1da67d5ee22..9e61720db7ea 100644
--- a/drivers/iio/adc/ad799x.c
+++ b/drivers/iio/adc/ad799x.c
@@ -814,10 +814,10 @@ static int ad799x_probe(struct i2c_client *client,
 
ret = ad799x_write_config(st, st->chip_config->default_config);
if (ret < 0)
-   goto error_disable_reg;
+   goto error_disable_vref;
ret = ad799x_read_config(st);
if (ret < 0)
-   goto error_disable_reg;
+   goto error_disable_vref;
st->config = ret;
 
ret = iio_triggered_buffer_setup(indio_dev, NULL,
-- 
2.7.4



[PATCH] iio: adc: ad799x: Fix error handling in ad799x_probe()

2018-04-20 Thread Alexey Khoroshilov
In case of errors in write/read config, st->vref is left undisabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
Fixes: 0f7ddcc1bff1 ("iio:adc:ad799x: Write default config on probe and reset 
alert status on probe")
---
 drivers/iio/adc/ad799x.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c
index e1da67d5ee22..9e61720db7ea 100644
--- a/drivers/iio/adc/ad799x.c
+++ b/drivers/iio/adc/ad799x.c
@@ -814,10 +814,10 @@ static int ad799x_probe(struct i2c_client *client,
 
ret = ad799x_write_config(st, st->chip_config->default_config);
if (ret < 0)
-   goto error_disable_reg;
+   goto error_disable_vref;
ret = ad799x_read_config(st);
if (ret < 0)
-   goto error_disable_reg;
+   goto error_disable_vref;
st->config = ret;
 
ret = iio_triggered_buffer_setup(indio_dev, NULL,
-- 
2.7.4



[PATCH] spi: meson-axg: Fix error handling in meson_spicc_probe()

2018-04-13 Thread Alexey Khoroshilov
If devm_spi_register_master() fails in meson_spicc_probe(),
spicc->core is left undisabled. The patch fixes that.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/spi/spi-meson-spicc.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c
index 5c82910e3480..7fe4488ace57 100644
--- a/drivers/spi/spi-meson-spicc.c
+++ b/drivers/spi/spi-meson-spicc.c
@@ -574,10 +574,15 @@ static int meson_spicc_probe(struct platform_device *pdev)
master->max_speed_hz = rate >> 2;
 
ret = devm_spi_register_master(>dev, master);
-   if (!ret)
-   return 0;
+   if (ret) {
+   dev_err(>dev, "spi master registration failed\n");
+   goto out_clk;
+   }
 
-   dev_err(>dev, "spi master registration failed\n");
+   return 0;
+
+out_clk:
+   clk_disable_unprepare(spicc->core);
 
 out_master:
spi_master_put(master);
-- 
2.7.4



[PATCH] spi: meson-axg: Fix error handling in meson_spicc_probe()

2018-04-13 Thread Alexey Khoroshilov
If devm_spi_register_master() fails in meson_spicc_probe(),
spicc->core is left undisabled. The patch fixes that.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/spi/spi-meson-spicc.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c
index 5c82910e3480..7fe4488ace57 100644
--- a/drivers/spi/spi-meson-spicc.c
+++ b/drivers/spi/spi-meson-spicc.c
@@ -574,10 +574,15 @@ static int meson_spicc_probe(struct platform_device *pdev)
master->max_speed_hz = rate >> 2;
 
ret = devm_spi_register_master(>dev, master);
-   if (!ret)
-   return 0;
+   if (ret) {
+   dev_err(>dev, "spi master registration failed\n");
+   goto out_clk;
+   }
 
-   dev_err(>dev, "spi master registration failed\n");
+   return 0;
+
+out_clk:
+   clk_disable_unprepare(spicc->core);
 
 out_master:
spi_master_put(master);
-- 
2.7.4



[PATCH] spi: stm32: Fix error handling in stm32_spi_probe()

2018-03-30 Thread Alexey Khoroshilov
clk_get_rate() is below clk_prepare_enable(), so
its error should lead to goto err_clk_disable, not to err_master_put.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/spi/spi-stm32.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
index ba9743fa2326..ad1e55d3d5d5 100644
--- a/drivers/spi/spi-stm32.c
+++ b/drivers/spi/spi-stm32.c
@@ -1129,7 +1129,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
if (!spi->clk_rate) {
dev_err(>dev, "clk rate = 0\n");
ret = -EINVAL;
-   goto err_master_put;
+   goto err_clk_disable;
}
 
spi->rst = devm_reset_control_get_exclusive(>dev, NULL);
-- 
2.7.4



[PATCH] spi: stm32: Fix error handling in stm32_spi_probe()

2018-03-30 Thread Alexey Khoroshilov
clk_get_rate() is below clk_prepare_enable(), so
its error should lead to goto err_clk_disable, not to err_master_put.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/spi/spi-stm32.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
index ba9743fa2326..ad1e55d3d5d5 100644
--- a/drivers/spi/spi-stm32.c
+++ b/drivers/spi/spi-stm32.c
@@ -1129,7 +1129,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
if (!spi->clk_rate) {
dev_err(>dev, "clk rate = 0\n");
ret = -EINVAL;
-   goto err_master_put;
+   goto err_clk_disable;
}
 
spi->rst = devm_reset_control_get_exclusive(>dev, NULL);
-- 
2.7.4



[PATCH] watchdog: davinci_wdt: fix error handling in davinci_wdt_probe()

2018-03-23 Thread Alexey Khoroshilov
clk_disable_unprepare() was added to one error path,
but there is another one. The patch makes sure clk is
disabled at the both of them.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/watchdog/davinci_wdt.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 3e4c592c239f..6c6594261cb7 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -236,15 +236,22 @@ static int davinci_wdt_probe(struct platform_device *pdev)
 
wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
davinci_wdt->base = devm_ioremap_resource(dev, wdt_mem);
-   if (IS_ERR(davinci_wdt->base))
-   return PTR_ERR(davinci_wdt->base);
+   if (IS_ERR(davinci_wdt->base)) {
+   ret = PTR_ERR(davinci_wdt->base);
+   goto err_clk_disable;
+   }
 
ret = watchdog_register_device(wdd);
-   if (ret < 0) {
-   clk_disable_unprepare(davinci_wdt->clk);
+   if (ret) {
dev_err(dev, "cannot register watchdog device\n");
+   goto err_clk_disable;
}
 
+   return 0;
+
+err_clk_disable:
+   clk_disable_unprepare(davinci_wdt->clk);
+
return ret;
 }
 
-- 
2.7.4



[PATCH] watchdog: davinci_wdt: fix error handling in davinci_wdt_probe()

2018-03-23 Thread Alexey Khoroshilov
clk_disable_unprepare() was added to one error path,
but there is another one. The patch makes sure clk is
disabled at the both of them.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/watchdog/davinci_wdt.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 3e4c592c239f..6c6594261cb7 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -236,15 +236,22 @@ static int davinci_wdt_probe(struct platform_device *pdev)
 
wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
davinci_wdt->base = devm_ioremap_resource(dev, wdt_mem);
-   if (IS_ERR(davinci_wdt->base))
-   return PTR_ERR(davinci_wdt->base);
+   if (IS_ERR(davinci_wdt->base)) {
+   ret = PTR_ERR(davinci_wdt->base);
+   goto err_clk_disable;
+   }
 
ret = watchdog_register_device(wdd);
-   if (ret < 0) {
-   clk_disable_unprepare(davinci_wdt->clk);
+   if (ret) {
dev_err(dev, "cannot register watchdog device\n");
+   goto err_clk_disable;
}
 
+   return 0;
+
+err_clk_disable:
+   clk_disable_unprepare(davinci_wdt->clk);
+
return ret;
 }
 
-- 
2.7.4



[PATCH v2] spi: jcore: disable ref_clk after getting its rate

2018-03-17 Thread Alexey Khoroshilov
The driver does not disable ref_clk on remove.
According to the comment, the only reason to enable the clock is to get
its rate. So, it should be safe to disable clk just after that.

By the way, clk_prepare_enable() looks to be more appropriate
than clk_enable() here.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
v2: There is no reason to wait for remove to disable ref_clk.

 drivers/spi/spi-jcore.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/spi/spi-jcore.c b/drivers/spi/spi-jcore.c
index dafed6280df3..702fe573a47b 100644
--- a/drivers/spi/spi-jcore.c
+++ b/drivers/spi/spi-jcore.c
@@ -184,10 +184,11 @@ static int jcore_spi_probe(struct platform_device *pdev)
 */
clock_freq = 5000;
clk = devm_clk_get(>dev, "ref_clk");
-   if (!IS_ERR_OR_NULL(clk)) {
-   if (clk_enable(clk) == 0)
+   if (!IS_ERR(clk)) {
+   if (clk_prepare_enable(clk) == 0) {
clock_freq = clk_get_rate(clk);
-   else
+   clk_disable_unprepare(clk);
+   } else
dev_warn(>dev, "could not enable ref_clk\n");
}
hw->clock_freq = clock_freq;
@@ -198,10 +199,8 @@ static int jcore_spi_probe(struct platform_device *pdev)
 
/* Register our spi controller */
err = devm_spi_register_master(>dev, master);
-   if (err) {
-   clk_disable(clk);
+   if (err)
goto exit;
-   }
 
return 0;
 
-- 
2.7.4



[PATCH v2] spi: jcore: disable ref_clk after getting its rate

2018-03-17 Thread Alexey Khoroshilov
The driver does not disable ref_clk on remove.
According to the comment, the only reason to enable the clock is to get
its rate. So, it should be safe to disable clk just after that.

By the way, clk_prepare_enable() looks to be more appropriate
than clk_enable() here.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
v2: There is no reason to wait for remove to disable ref_clk.

 drivers/spi/spi-jcore.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/spi/spi-jcore.c b/drivers/spi/spi-jcore.c
index dafed6280df3..702fe573a47b 100644
--- a/drivers/spi/spi-jcore.c
+++ b/drivers/spi/spi-jcore.c
@@ -184,10 +184,11 @@ static int jcore_spi_probe(struct platform_device *pdev)
 */
clock_freq = 5000;
clk = devm_clk_get(>dev, "ref_clk");
-   if (!IS_ERR_OR_NULL(clk)) {
-   if (clk_enable(clk) == 0)
+   if (!IS_ERR(clk)) {
+   if (clk_prepare_enable(clk) == 0) {
clock_freq = clk_get_rate(clk);
-   else
+   clk_disable_unprepare(clk);
+   } else
dev_warn(>dev, "could not enable ref_clk\n");
}
hw->clock_freq = clock_freq;
@@ -198,10 +199,8 @@ static int jcore_spi_probe(struct platform_device *pdev)
 
/* Register our spi controller */
err = devm_spi_register_master(>dev, master);
-   if (err) {
-   clk_disable(clk);
+   if (err)
goto exit;
-   }
 
return 0;
 
-- 
2.7.4



[PATCH] spi: jcore: disable clock on remove

2018-03-16 Thread Alexey Khoroshilov
The driver does not disable ref_clk on remove.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/spi/spi-jcore.c | 26 --
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/spi/spi-jcore.c b/drivers/spi/spi-jcore.c
index dafed6280df3..68cac15ff54a 100644
--- a/drivers/spi/spi-jcore.c
+++ b/drivers/spi/spi-jcore.c
@@ -38,6 +38,7 @@ struct jcore_spi {
unsigned int speed_reg;
unsigned int speed_hz;
unsigned int clock_freq;
+   struct clk   *clk;
 };
 
 static int jcore_spi_wait(void __iomem *ctrl_reg)
@@ -143,7 +144,6 @@ static int jcore_spi_probe(struct platform_device *pdev)
struct spi_master *master;
struct resource *res;
u32 clock_freq;
-   struct clk *clk;
int err = -ENODEV;
 
master = spi_alloc_master(>dev, sizeof(struct jcore_spi));
@@ -183,10 +183,10 @@ static int jcore_spi_probe(struct platform_device *pdev)
 * requested rate. If the clock is omitted, 50 MHz is assumed.
 */
clock_freq = 5000;
-   clk = devm_clk_get(>dev, "ref_clk");
-   if (!IS_ERR_OR_NULL(clk)) {
-   if (clk_enable(clk) == 0)
-   clock_freq = clk_get_rate(clk);
+   hw->clk = devm_clk_get(>dev, "ref_clk");
+   if (!IS_ERR_OR_NULL(hw->clk)) {
+   if (clk_enable(hw->clk) == 0)
+   clock_freq = clk_get_rate(hw->clk);
else
dev_warn(>dev, "could not enable ref_clk\n");
}
@@ -199,7 +199,7 @@ static int jcore_spi_probe(struct platform_device *pdev)
/* Register our spi controller */
err = devm_spi_register_master(>dev, master);
if (err) {
-   clk_disable(clk);
+   clk_disable(hw->clk);
goto exit;
}
 
@@ -212,6 +212,19 @@ static int jcore_spi_probe(struct platform_device *pdev)
return err;
 }
 
+static int jcore_spi_remove(struct platform_device *pdev)
+{
+   struct spi_master *master;
+   struct jcore_spi *hw;
+
+   master = platform_get_drvdata(pdev);
+   hw = spi_master_get_devdata(master);
+
+   clk_disable(hw->clk);
+
+   return 0;
+}
+
 static const struct of_device_id jcore_spi_of_match[] = {
{ .compatible = "jcore,spi2" },
{},
@@ -220,6 +233,7 @@ MODULE_DEVICE_TABLE(of, jcore_spi_of_match);
 
 static struct platform_driver jcore_spi_driver = {
.probe = jcore_spi_probe,
+   .remove = jcore_spi_remove,
.driver = {
.name = DRV_NAME,
.of_match_table = jcore_spi_of_match,
-- 
2.7.4



[PATCH] spi: jcore: disable clock on remove

2018-03-16 Thread Alexey Khoroshilov
The driver does not disable ref_clk on remove.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/spi/spi-jcore.c | 26 --
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/spi/spi-jcore.c b/drivers/spi/spi-jcore.c
index dafed6280df3..68cac15ff54a 100644
--- a/drivers/spi/spi-jcore.c
+++ b/drivers/spi/spi-jcore.c
@@ -38,6 +38,7 @@ struct jcore_spi {
unsigned int speed_reg;
unsigned int speed_hz;
unsigned int clock_freq;
+   struct clk   *clk;
 };
 
 static int jcore_spi_wait(void __iomem *ctrl_reg)
@@ -143,7 +144,6 @@ static int jcore_spi_probe(struct platform_device *pdev)
struct spi_master *master;
struct resource *res;
u32 clock_freq;
-   struct clk *clk;
int err = -ENODEV;
 
master = spi_alloc_master(>dev, sizeof(struct jcore_spi));
@@ -183,10 +183,10 @@ static int jcore_spi_probe(struct platform_device *pdev)
 * requested rate. If the clock is omitted, 50 MHz is assumed.
 */
clock_freq = 5000;
-   clk = devm_clk_get(>dev, "ref_clk");
-   if (!IS_ERR_OR_NULL(clk)) {
-   if (clk_enable(clk) == 0)
-   clock_freq = clk_get_rate(clk);
+   hw->clk = devm_clk_get(>dev, "ref_clk");
+   if (!IS_ERR_OR_NULL(hw->clk)) {
+   if (clk_enable(hw->clk) == 0)
+   clock_freq = clk_get_rate(hw->clk);
else
dev_warn(>dev, "could not enable ref_clk\n");
}
@@ -199,7 +199,7 @@ static int jcore_spi_probe(struct platform_device *pdev)
/* Register our spi controller */
err = devm_spi_register_master(>dev, master);
if (err) {
-   clk_disable(clk);
+   clk_disable(hw->clk);
goto exit;
}
 
@@ -212,6 +212,19 @@ static int jcore_spi_probe(struct platform_device *pdev)
return err;
 }
 
+static int jcore_spi_remove(struct platform_device *pdev)
+{
+   struct spi_master *master;
+   struct jcore_spi *hw;
+
+   master = platform_get_drvdata(pdev);
+   hw = spi_master_get_devdata(master);
+
+   clk_disable(hw->clk);
+
+   return 0;
+}
+
 static const struct of_device_id jcore_spi_of_match[] = {
{ .compatible = "jcore,spi2" },
{},
@@ -220,6 +233,7 @@ MODULE_DEVICE_TABLE(of, jcore_spi_of_match);
 
 static struct platform_driver jcore_spi_driver = {
.probe = jcore_spi_probe,
+   .remove = jcore_spi_remove,
.driver = {
.name = DRV_NAME,
.of_match_table = jcore_spi_of_match,
-- 
2.7.4



[PATCH] watchdog: sprd_wdt: Fix error handling in sprd_wdt_enable()

2018-03-08 Thread Alexey Khoroshilov
If clk_prepare_enable(wdt->rtc_enable) fails,
wdt->enable clock is left enabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/watchdog/sprd_wdt.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/watchdog/sprd_wdt.c b/drivers/watchdog/sprd_wdt.c
index a8b280ff33e0..b4d484a42b70 100644
--- a/drivers/watchdog/sprd_wdt.c
+++ b/drivers/watchdog/sprd_wdt.c
@@ -154,8 +154,10 @@ static int sprd_wdt_enable(struct sprd_wdt *wdt)
if (ret)
return ret;
ret = clk_prepare_enable(wdt->rtc_enable);
-   if (ret)
+   if (ret) {
+   clk_disable_unprepare(wdt->enable);
return ret;
+   }
 
sprd_wdt_unlock(wdt->base);
val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);
-- 
2.7.4



[PATCH] watchdog: sprd_wdt: Fix error handling in sprd_wdt_enable()

2018-03-08 Thread Alexey Khoroshilov
If clk_prepare_enable(wdt->rtc_enable) fails,
wdt->enable clock is left enabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/watchdog/sprd_wdt.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/watchdog/sprd_wdt.c b/drivers/watchdog/sprd_wdt.c
index a8b280ff33e0..b4d484a42b70 100644
--- a/drivers/watchdog/sprd_wdt.c
+++ b/drivers/watchdog/sprd_wdt.c
@@ -154,8 +154,10 @@ static int sprd_wdt_enable(struct sprd_wdt *wdt)
if (ret)
return ret;
ret = clk_prepare_enable(wdt->rtc_enable);
-   if (ret)
+   if (ret) {
+   clk_disable_unprepare(wdt->enable);
return ret;
+   }
 
sprd_wdt_unlock(wdt->base);
val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);
-- 
2.7.4



[PATCH] serial: mxs-auart: disable clks of Alphascale ASM9260

2018-03-02 Thread Alexey Khoroshilov
In case of Alphascale ASM9260 probe() enables s->clk and s->clk_ahb
via mxs_get_clks(), but there is no disable of the clocks.
The patch adds it to error paths and to mxs_auart_remove().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
Fixes: 254da0d753fb ("serial: mxs-auart: add Alphascale ASM9260 support")
---
 drivers/tty/serial/mxs-auart.c | 36 +++-
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index 079dc47aa142..531c374a5e3e 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -1674,8 +1674,10 @@ static int mxs_auart_probe(struct platform_device *pdev)
return ret;
 
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   if (!r)
-   return -ENXIO;
+   if (!r) {
+   ret = -ENXIO;
+   goto out_disable_clks;
+   }
 
s->port.mapbase = r->start;
s->port.membase = ioremap(r->start, resource_size(r));
@@ -1690,21 +1692,23 @@ static int mxs_auart_probe(struct platform_device *pdev)
s->mctrl_prev = 0;
 
irq = platform_get_irq(pdev, 0);
-   if (irq < 0)
-   return irq;
+   if (irq < 0) {
+   ret = irq;
+   goto out_disable_clks;
+   }
 
s->port.irq = irq;
ret = devm_request_irq(>dev, irq, mxs_auart_irq_handle, 0,
   dev_name(>dev), s);
if (ret)
-   return ret;
+   goto out_disable_clks;
 
platform_set_drvdata(pdev, s);
 
ret = mxs_auart_init_gpios(s, >dev);
if (ret) {
dev_err(>dev, "Failed to initialize GPIOs.\n");
-   return ret;
+   goto out_disable_clks;
}
 
/*
@@ -1712,7 +1716,7 @@ static int mxs_auart_probe(struct platform_device *pdev)
 */
ret = mxs_auart_request_gpio_irq(s);
if (ret)
-   return ret;
+   goto out_disable_clks;
 
auart_port[s->port.line] = s;
 
@@ -1720,7 +1724,7 @@ static int mxs_auart_probe(struct platform_device *pdev)
 
ret = uart_add_one_port(_driver, >port);
if (ret)
-   goto out_disable_clks_free_qpio_irq;
+   goto out_free_qpio_irq;
 
/* ASM9260 don't have version reg */
if (is_asm9260_auart(s)) {
@@ -1734,13 +1738,15 @@ static int mxs_auart_probe(struct platform_device *pdev)
 
return 0;
 
-out_disable_clks_free_qpio_irq:
-   if (s->clk)
-   clk_disable_unprepare(s->clk_ahb);
-   if (s->clk_ahb)
-   clk_disable_unprepare(s->clk_ahb);
+out_free_qpio_irq:
mxs_auart_free_gpio_irq(s);
auart_port[pdev->id] = NULL;
+
+out_disable_clks:
+   if (is_asm9260_auart(s)) {
+   clk_disable_unprepare(s->clk);
+   clk_disable_unprepare(s->clk_ahb);
+   }
return ret;
 }
 
@@ -1751,6 +1757,10 @@ static int mxs_auart_remove(struct platform_device *pdev)
uart_remove_one_port(_driver, >port);
auart_port[pdev->id] = NULL;
mxs_auart_free_gpio_irq(s);
+   if (is_asm9260_auart(s)) {
+   clk_disable_unprepare(s->clk);
+   clk_disable_unprepare(s->clk_ahb);
+   }
 
return 0;
 }
-- 
2.7.4



[PATCH] serial: mxs-auart: disable clks of Alphascale ASM9260

2018-03-02 Thread Alexey Khoroshilov
In case of Alphascale ASM9260 probe() enables s->clk and s->clk_ahb
via mxs_get_clks(), but there is no disable of the clocks.
The patch adds it to error paths and to mxs_auart_remove().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
Fixes: 254da0d753fb ("serial: mxs-auart: add Alphascale ASM9260 support")
---
 drivers/tty/serial/mxs-auart.c | 36 +++-
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index 079dc47aa142..531c374a5e3e 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -1674,8 +1674,10 @@ static int mxs_auart_probe(struct platform_device *pdev)
return ret;
 
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   if (!r)
-   return -ENXIO;
+   if (!r) {
+   ret = -ENXIO;
+   goto out_disable_clks;
+   }
 
s->port.mapbase = r->start;
s->port.membase = ioremap(r->start, resource_size(r));
@@ -1690,21 +1692,23 @@ static int mxs_auart_probe(struct platform_device *pdev)
s->mctrl_prev = 0;
 
irq = platform_get_irq(pdev, 0);
-   if (irq < 0)
-   return irq;
+   if (irq < 0) {
+   ret = irq;
+   goto out_disable_clks;
+   }
 
s->port.irq = irq;
ret = devm_request_irq(>dev, irq, mxs_auart_irq_handle, 0,
   dev_name(>dev), s);
if (ret)
-   return ret;
+   goto out_disable_clks;
 
platform_set_drvdata(pdev, s);
 
ret = mxs_auart_init_gpios(s, >dev);
if (ret) {
dev_err(>dev, "Failed to initialize GPIOs.\n");
-   return ret;
+   goto out_disable_clks;
}
 
/*
@@ -1712,7 +1716,7 @@ static int mxs_auart_probe(struct platform_device *pdev)
 */
ret = mxs_auart_request_gpio_irq(s);
if (ret)
-   return ret;
+   goto out_disable_clks;
 
auart_port[s->port.line] = s;
 
@@ -1720,7 +1724,7 @@ static int mxs_auart_probe(struct platform_device *pdev)
 
ret = uart_add_one_port(_driver, >port);
if (ret)
-   goto out_disable_clks_free_qpio_irq;
+   goto out_free_qpio_irq;
 
/* ASM9260 don't have version reg */
if (is_asm9260_auart(s)) {
@@ -1734,13 +1738,15 @@ static int mxs_auart_probe(struct platform_device *pdev)
 
return 0;
 
-out_disable_clks_free_qpio_irq:
-   if (s->clk)
-   clk_disable_unprepare(s->clk_ahb);
-   if (s->clk_ahb)
-   clk_disable_unprepare(s->clk_ahb);
+out_free_qpio_irq:
mxs_auart_free_gpio_irq(s);
auart_port[pdev->id] = NULL;
+
+out_disable_clks:
+   if (is_asm9260_auart(s)) {
+   clk_disable_unprepare(s->clk);
+   clk_disable_unprepare(s->clk_ahb);
+   }
return ret;
 }
 
@@ -1751,6 +1757,10 @@ static int mxs_auart_remove(struct platform_device *pdev)
uart_remove_one_port(_driver, >port);
auart_port[pdev->id] = NULL;
mxs_auart_free_gpio_irq(s);
+   if (is_asm9260_auart(s)) {
+   clk_disable_unprepare(s->clk);
+   clk_disable_unprepare(s->clk_ahb);
+   }
 
return 0;
 }
-- 
2.7.4



[PATCH] phy: lpc18xx-usb-otg: error handling in lpc18xx_usb_otg_phy_power_on()

2018-02-22 Thread Alexey Khoroshilov
If regmap_update_bits() fails in lpc18xx_usb_otg_phy_power_on(),
lpc->clk is left enabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/phy/phy-lpc18xx-usb-otg.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/phy-lpc18xx-usb-otg.c 
b/drivers/phy/phy-lpc18xx-usb-otg.c
index 3b7a71eb5b7e..7de280a45421 100644
--- a/drivers/phy/phy-lpc18xx-usb-otg.c
+++ b/drivers/phy/phy-lpc18xx-usb-otg.c
@@ -60,8 +60,14 @@ static int lpc18xx_usb_otg_phy_power_on(struct phy *phy)
return ret;
 
/* The bit in CREG is cleared to enable the PHY */
-   return regmap_update_bits(lpc->reg, LPC18XX_CREG_CREG0,
+   ret = regmap_update_bits(lpc->reg, LPC18XX_CREG_CREG0,
  LPC18XX_CREG_CREG0_USB0PHY, 0);
+   if (ret) {
+   clk_disable(lpc->clk);
+   return ret;
+   }
+
+   return 0;
 }
 
 static int lpc18xx_usb_otg_phy_power_off(struct phy *phy)
-- 
2.7.4



[PATCH] phy: lpc18xx-usb-otg: error handling in lpc18xx_usb_otg_phy_power_on()

2018-02-22 Thread Alexey Khoroshilov
If regmap_update_bits() fails in lpc18xx_usb_otg_phy_power_on(),
lpc->clk is left enabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/phy/phy-lpc18xx-usb-otg.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/phy-lpc18xx-usb-otg.c 
b/drivers/phy/phy-lpc18xx-usb-otg.c
index 3b7a71eb5b7e..7de280a45421 100644
--- a/drivers/phy/phy-lpc18xx-usb-otg.c
+++ b/drivers/phy/phy-lpc18xx-usb-otg.c
@@ -60,8 +60,14 @@ static int lpc18xx_usb_otg_phy_power_on(struct phy *phy)
return ret;
 
/* The bit in CREG is cleared to enable the PHY */
-   return regmap_update_bits(lpc->reg, LPC18XX_CREG_CREG0,
+   ret = regmap_update_bits(lpc->reg, LPC18XX_CREG_CREG0,
  LPC18XX_CREG_CREG0_USB0PHY, 0);
+   if (ret) {
+   clk_disable(lpc->clk);
+   return ret;
+   }
+
+   return 0;
 }
 
 static int lpc18xx_usb_otg_phy_power_off(struct phy *phy)
-- 
2.7.4



[PATCH] tun: fix mismatch in mutex lock-unlock in tun_get_user()

2018-02-16 Thread Alexey Khoroshilov
There is a single error path where tfile->napi_mutex is left unlocked.
It can lead to a deadlock.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/net/tun.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 81e6cc951e7f..0072a9832532 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1879,6 +1879,10 @@ static ssize_t tun_get_user(struct tun_struct *tun, 
struct tun_file *tfile,
default:
this_cpu_inc(tun->pcpu_stats->rx_dropped);
kfree_skb(skb);
+   if (frags) {
+   tfile->napi.skb = NULL;
+   mutex_unlock(>napi_mutex);
+   }
return -EINVAL;
}
}
-- 
2.7.4



[PATCH] tun: fix mismatch in mutex lock-unlock in tun_get_user()

2018-02-16 Thread Alexey Khoroshilov
There is a single error path where tfile->napi_mutex is left unlocked.
It can lead to a deadlock.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/net/tun.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 81e6cc951e7f..0072a9832532 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1879,6 +1879,10 @@ static ssize_t tun_get_user(struct tun_struct *tun, 
struct tun_file *tfile,
default:
this_cpu_inc(tun->pcpu_stats->rx_dropped);
kfree_skb(skb);
+   if (frags) {
+   tfile->napi.skb = NULL;
+   mutex_unlock(>napi_mutex);
+   }
return -EINVAL;
}
}
-- 
2.7.4



[PATCH v2] watchdog: asm9260_wdt: fix error handling in asm9260_wdt_probe()

2018-02-10 Thread Alexey Khoroshilov
If devm_reset_control_get_exclusive() fails, asm9260_wdt_probe()
returns immediately. But clks has been already enabled at that point,
so it is required to disable them or to move the code around.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
v2: Move the code around instead of disabling clks as Guenter Roeck suggested.

 drivers/watchdog/asm9260_wdt.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/watchdog/asm9260_wdt.c b/drivers/watchdog/asm9260_wdt.c
index 7dd0da644a7f..2cf56b459d84 100644
--- a/drivers/watchdog/asm9260_wdt.c
+++ b/drivers/watchdog/asm9260_wdt.c
@@ -292,14 +292,14 @@ static int asm9260_wdt_probe(struct platform_device *pdev)
if (IS_ERR(priv->iobase))
return PTR_ERR(priv->iobase);
 
-   ret = asm9260_wdt_get_dt_clks(priv);
-   if (ret)
-   return ret;
-
priv->rst = devm_reset_control_get_exclusive(>dev, "wdt_rst");
if (IS_ERR(priv->rst))
return PTR_ERR(priv->rst);
 
+   ret = asm9260_wdt_get_dt_clks(priv);
+   if (ret)
+   return ret;
+
wdd = >wdd;
wdd->info = _wdt_ident;
wdd->ops = _wdt_ops;
-- 
2.7.4



[PATCH v2] watchdog: asm9260_wdt: fix error handling in asm9260_wdt_probe()

2018-02-10 Thread Alexey Khoroshilov
If devm_reset_control_get_exclusive() fails, asm9260_wdt_probe()
returns immediately. But clks has been already enabled at that point,
so it is required to disable them or to move the code around.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
v2: Move the code around instead of disabling clks as Guenter Roeck suggested.

 drivers/watchdog/asm9260_wdt.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/watchdog/asm9260_wdt.c b/drivers/watchdog/asm9260_wdt.c
index 7dd0da644a7f..2cf56b459d84 100644
--- a/drivers/watchdog/asm9260_wdt.c
+++ b/drivers/watchdog/asm9260_wdt.c
@@ -292,14 +292,14 @@ static int asm9260_wdt_probe(struct platform_device *pdev)
if (IS_ERR(priv->iobase))
return PTR_ERR(priv->iobase);
 
-   ret = asm9260_wdt_get_dt_clks(priv);
-   if (ret)
-   return ret;
-
priv->rst = devm_reset_control_get_exclusive(>dev, "wdt_rst");
if (IS_ERR(priv->rst))
return PTR_ERR(priv->rst);
 
+   ret = asm9260_wdt_get_dt_clks(priv);
+   if (ret)
+   return ret;
+
wdd = >wdd;
wdd->info = _wdt_ident;
wdd->ops = _wdt_ops;
-- 
2.7.4



[PATCH v4 3/3] mtd: nand: vf610: check mtd_device_register() return code

2018-02-09 Thread Alexey Khoroshilov
vf610_nfc_probe() misses error handling of mtd_device_register().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/mtd/nand/vf610_nfc.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index 9cc5992e88c8..64fed3d9e3d4 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -782,8 +782,13 @@ static int vf610_nfc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, mtd);
 
/* Register device in MTD */
-   return mtd_device_register(mtd, NULL, 0);
+   err = mtd_device_register(mtd, NULL, 0);
+   if (err)
+   goto err_cleanup_nand;
+   return 0;
 
+err_cleanup_nand:
+   nand_cleanup(chip);
 err_disable_clk:
clk_disable_unprepare(nfc->clk);
return err;
-- 
2.7.4



[PATCH v4 2/3] mtd: nand: vf610: improve readability of error label

2018-02-09 Thread Alexey Khoroshilov
Use clearer error labels as Boris Brezillon suggested.

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/mtd/nand/vf610_nfc.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index c4568372c3e3..9cc5992e88c8 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -682,7 +682,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
dev_err(nfc->dev,
"Only one NAND chip supported!\n");
err = -EINVAL;
-   goto err_clk;
+   goto err_disable_clk;
}
 
nand_set_flash_node(chip, child);
@@ -692,7 +692,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
if (!nand_get_flash_node(chip)) {
dev_err(nfc->dev, "NAND chip sub-node missing!\n");
err = -ENODEV;
-   goto err_clk;
+   goto err_disable_clk;
}
 
chip->dev_ready = vf610_nfc_dev_ready;
@@ -712,7 +712,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, mtd);
if (err) {
dev_err(nfc->dev, "Error requesting IRQ!\n");
-   goto err_clk;
+   goto err_disable_clk;
}
 
vf610_nfc_preinit_controller(nfc);
@@ -720,7 +720,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
/* first scan to find the device and get the page size */
err = nand_scan_ident(mtd, 1, NULL);
if (err)
-   goto err_clk;
+   goto err_disable_clk;
 
vf610_nfc_init_controller(nfc);
 
@@ -732,20 +732,20 @@ static int vf610_nfc_probe(struct platform_device *pdev)
if (mtd->writesize + mtd->oobsize > PAGE_2K + OOB_MAX - 8) {
dev_err(nfc->dev, "Unsupported flash page size\n");
err = -ENXIO;
-   goto err_clk;
+   goto err_disable_clk;
}
 
if (chip->ecc.mode == NAND_ECC_HW) {
if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) {
dev_err(nfc->dev, "Unsupported flash with hwecc\n");
err = -ENXIO;
-   goto err_clk;
+   goto err_disable_clk;
}
 
if (chip->ecc.size != mtd->writesize) {
dev_err(nfc->dev, "Step size needs to be page size\n");
err = -ENXIO;
-   goto err_clk;
+   goto err_disable_clk;
}
 
/* Only 64 byte ECC layouts known */
@@ -765,7 +765,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
} else {
dev_err(nfc->dev, "Unsupported ECC strength\n");
err = -ENXIO;
-   goto err_clk;
+   goto err_disable_clk;
}
 
chip->ecc.read_page = vf610_nfc_read_page;
@@ -777,14 +777,14 @@ static int vf610_nfc_probe(struct platform_device *pdev)
/* second phase scan */
err = nand_scan_tail(mtd);
if (err)
-   goto err_clk;
+   goto err_disable_clk;
 
platform_set_drvdata(pdev, mtd);
 
/* Register device in MTD */
return mtd_device_register(mtd, NULL, 0);
 
-err_clk:
+err_disable_clk:
clk_disable_unprepare(nfc->clk);
return err;
 }
-- 
2.7.4



[PATCH v4 3/3] mtd: nand: vf610: check mtd_device_register() return code

2018-02-09 Thread Alexey Khoroshilov
vf610_nfc_probe() misses error handling of mtd_device_register().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov 
---
 drivers/mtd/nand/vf610_nfc.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index 9cc5992e88c8..64fed3d9e3d4 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -782,8 +782,13 @@ static int vf610_nfc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, mtd);
 
/* Register device in MTD */
-   return mtd_device_register(mtd, NULL, 0);
+   err = mtd_device_register(mtd, NULL, 0);
+   if (err)
+   goto err_cleanup_nand;
+   return 0;
 
+err_cleanup_nand:
+   nand_cleanup(chip);
 err_disable_clk:
clk_disable_unprepare(nfc->clk);
return err;
-- 
2.7.4



[PATCH v4 2/3] mtd: nand: vf610: improve readability of error label

2018-02-09 Thread Alexey Khoroshilov
Use clearer error labels as Boris Brezillon suggested.

Signed-off-by: Alexey Khoroshilov 
---
 drivers/mtd/nand/vf610_nfc.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index c4568372c3e3..9cc5992e88c8 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -682,7 +682,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
dev_err(nfc->dev,
"Only one NAND chip supported!\n");
err = -EINVAL;
-   goto err_clk;
+   goto err_disable_clk;
}
 
nand_set_flash_node(chip, child);
@@ -692,7 +692,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
if (!nand_get_flash_node(chip)) {
dev_err(nfc->dev, "NAND chip sub-node missing!\n");
err = -ENODEV;
-   goto err_clk;
+   goto err_disable_clk;
}
 
chip->dev_ready = vf610_nfc_dev_ready;
@@ -712,7 +712,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, mtd);
if (err) {
dev_err(nfc->dev, "Error requesting IRQ!\n");
-   goto err_clk;
+   goto err_disable_clk;
}
 
vf610_nfc_preinit_controller(nfc);
@@ -720,7 +720,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
/* first scan to find the device and get the page size */
err = nand_scan_ident(mtd, 1, NULL);
if (err)
-   goto err_clk;
+   goto err_disable_clk;
 
vf610_nfc_init_controller(nfc);
 
@@ -732,20 +732,20 @@ static int vf610_nfc_probe(struct platform_device *pdev)
if (mtd->writesize + mtd->oobsize > PAGE_2K + OOB_MAX - 8) {
dev_err(nfc->dev, "Unsupported flash page size\n");
err = -ENXIO;
-   goto err_clk;
+   goto err_disable_clk;
}
 
if (chip->ecc.mode == NAND_ECC_HW) {
if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) {
dev_err(nfc->dev, "Unsupported flash with hwecc\n");
err = -ENXIO;
-   goto err_clk;
+   goto err_disable_clk;
}
 
if (chip->ecc.size != mtd->writesize) {
dev_err(nfc->dev, "Step size needs to be page size\n");
err = -ENXIO;
-   goto err_clk;
+   goto err_disable_clk;
}
 
/* Only 64 byte ECC layouts known */
@@ -765,7 +765,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
} else {
dev_err(nfc->dev, "Unsupported ECC strength\n");
err = -ENXIO;
-   goto err_clk;
+   goto err_disable_clk;
}
 
chip->ecc.read_page = vf610_nfc_read_page;
@@ -777,14 +777,14 @@ static int vf610_nfc_probe(struct platform_device *pdev)
/* second phase scan */
err = nand_scan_tail(mtd);
if (err)
-   goto err_clk;
+   goto err_disable_clk;
 
platform_set_drvdata(pdev, mtd);
 
/* Register device in MTD */
return mtd_device_register(mtd, NULL, 0);
 
-err_clk:
+err_disable_clk:
clk_disable_unprepare(nfc->clk);
return err;
 }
-- 
2.7.4



[PATCH v4 1/3] mtd: nand: vf610: remove the unnecessary of_node_put()

2018-02-09 Thread Alexey Khoroshilov
Calling of_node_put() in vf610_nfc_probe() is wrong because nothing in
this code retains a reference to the DT node.

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/mtd/nand/vf610_nfc.c | 18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index 80d31a58e558..c4568372c3e3 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -682,7 +682,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
dev_err(nfc->dev,
"Only one NAND chip supported!\n");
err = -EINVAL;
-   goto error;
+   goto err_clk;
}
 
nand_set_flash_node(chip, child);
@@ -712,7 +712,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, mtd);
if (err) {
dev_err(nfc->dev, "Error requesting IRQ!\n");
-   goto error;
+   goto err_clk;
}
 
vf610_nfc_preinit_controller(nfc);
@@ -720,7 +720,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
/* first scan to find the device and get the page size */
err = nand_scan_ident(mtd, 1, NULL);
if (err)
-   goto error;
+   goto err_clk;
 
vf610_nfc_init_controller(nfc);
 
@@ -732,20 +732,20 @@ static int vf610_nfc_probe(struct platform_device *pdev)
if (mtd->writesize + mtd->oobsize > PAGE_2K + OOB_MAX - 8) {
dev_err(nfc->dev, "Unsupported flash page size\n");
err = -ENXIO;
-   goto error;
+   goto err_clk;
}
 
if (chip->ecc.mode == NAND_ECC_HW) {
if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) {
dev_err(nfc->dev, "Unsupported flash with hwecc\n");
err = -ENXIO;
-   goto error;
+   goto err_clk;
}
 
if (chip->ecc.size != mtd->writesize) {
dev_err(nfc->dev, "Step size needs to be page size\n");
err = -ENXIO;
-   goto error;
+   goto err_clk;
}
 
/* Only 64 byte ECC layouts known */
@@ -765,7 +765,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
} else {
dev_err(nfc->dev, "Unsupported ECC strength\n");
err = -ENXIO;
-   goto error;
+   goto err_clk;
}
 
chip->ecc.read_page = vf610_nfc_read_page;
@@ -777,15 +777,13 @@ static int vf610_nfc_probe(struct platform_device *pdev)
/* second phase scan */
err = nand_scan_tail(mtd);
if (err)
-   goto error;
+   goto err_clk;
 
platform_set_drvdata(pdev, mtd);
 
/* Register device in MTD */
return mtd_device_register(mtd, NULL, 0);
 
-error:
-   of_node_put(nand_get_flash_node(chip));
 err_clk:
clk_disable_unprepare(nfc->clk);
return err;
-- 
2.7.4



[PATCH v4 1/3] mtd: nand: vf610: remove the unnecessary of_node_put()

2018-02-09 Thread Alexey Khoroshilov
Calling of_node_put() in vf610_nfc_probe() is wrong because nothing in
this code retains a reference to the DT node.

Signed-off-by: Alexey Khoroshilov 
---
 drivers/mtd/nand/vf610_nfc.c | 18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index 80d31a58e558..c4568372c3e3 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -682,7 +682,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
dev_err(nfc->dev,
"Only one NAND chip supported!\n");
err = -EINVAL;
-   goto error;
+   goto err_clk;
}
 
nand_set_flash_node(chip, child);
@@ -712,7 +712,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, mtd);
if (err) {
dev_err(nfc->dev, "Error requesting IRQ!\n");
-   goto error;
+   goto err_clk;
}
 
vf610_nfc_preinit_controller(nfc);
@@ -720,7 +720,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
/* first scan to find the device and get the page size */
err = nand_scan_ident(mtd, 1, NULL);
if (err)
-   goto error;
+   goto err_clk;
 
vf610_nfc_init_controller(nfc);
 
@@ -732,20 +732,20 @@ static int vf610_nfc_probe(struct platform_device *pdev)
if (mtd->writesize + mtd->oobsize > PAGE_2K + OOB_MAX - 8) {
dev_err(nfc->dev, "Unsupported flash page size\n");
err = -ENXIO;
-   goto error;
+   goto err_clk;
}
 
if (chip->ecc.mode == NAND_ECC_HW) {
if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) {
dev_err(nfc->dev, "Unsupported flash with hwecc\n");
err = -ENXIO;
-   goto error;
+   goto err_clk;
}
 
if (chip->ecc.size != mtd->writesize) {
dev_err(nfc->dev, "Step size needs to be page size\n");
err = -ENXIO;
-   goto error;
+   goto err_clk;
}
 
/* Only 64 byte ECC layouts known */
@@ -765,7 +765,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
} else {
dev_err(nfc->dev, "Unsupported ECC strength\n");
err = -ENXIO;
-   goto error;
+   goto err_clk;
}
 
chip->ecc.read_page = vf610_nfc_read_page;
@@ -777,15 +777,13 @@ static int vf610_nfc_probe(struct platform_device *pdev)
/* second phase scan */
err = nand_scan_tail(mtd);
if (err)
-   goto error;
+   goto err_clk;
 
platform_set_drvdata(pdev, mtd);
 
/* Register device in MTD */
return mtd_device_register(mtd, NULL, 0);
 
-error:
-   of_node_put(nand_get_flash_node(chip));
 err_clk:
clk_disable_unprepare(nfc->clk);
return err;
-- 
2.7.4



[PATCH v4 0/3] mtd: nand: vf610: fix error handling in vf610_nfc_probe()

2018-02-09 Thread Alexey Khoroshilov
vf610_nfc_probe() misses error handling of mtd_device_register()
and contains unneeded of_node_put() on error path.

v2: Add nand_cleanup() to undone nand_scan_tail() as Boris Brezillon noted.
v3: Rename error labels, remove of_node_put() per Boris Brezillon request.
v4: Separate fix in to 3 patches.

Alexey Khoroshilov (3):
  mtd: nand: vf610: remove the unnecessary of_node_put()
  mtd: nand: vf610: improve readability of error label
  mtd: nand: vf610: check mtd_device_register() return code

 drivers/mtd/nand/vf610_nfc.c | 29 -
 1 file changed, 16 insertions(+), 13 deletions(-)

-- 
2.7.4



[PATCH v4 0/3] mtd: nand: vf610: fix error handling in vf610_nfc_probe()

2018-02-09 Thread Alexey Khoroshilov
vf610_nfc_probe() misses error handling of mtd_device_register()
and contains unneeded of_node_put() on error path.

v2: Add nand_cleanup() to undone nand_scan_tail() as Boris Brezillon noted.
v3: Rename error labels, remove of_node_put() per Boris Brezillon request.
v4: Separate fix in to 3 patches.

Alexey Khoroshilov (3):
  mtd: nand: vf610: remove the unnecessary of_node_put()
  mtd: nand: vf610: improve readability of error label
  mtd: nand: vf610: check mtd_device_register() return code

 drivers/mtd/nand/vf610_nfc.c | 29 -
 1 file changed, 16 insertions(+), 13 deletions(-)

-- 
2.7.4



[PATCH] watchdog: asm9260_wdt: fix error handling in asm9260_wdt_probe()

2018-02-09 Thread Alexey Khoroshilov
If devm_reset_control_get_exclusive() fails, asm9260_wdt_probe()
returns immediately. But clks has been already enabled at that point,
so it is required to disable them.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
---
 drivers/watchdog/asm9260_wdt.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/watchdog/asm9260_wdt.c b/drivers/watchdog/asm9260_wdt.c
index 7dd0da644a7f..de9e538a5fa8 100644
--- a/drivers/watchdog/asm9260_wdt.c
+++ b/drivers/watchdog/asm9260_wdt.c
@@ -297,8 +297,10 @@ static int asm9260_wdt_probe(struct platform_device *pdev)
return ret;
 
priv->rst = devm_reset_control_get_exclusive(>dev, "wdt_rst");
-   if (IS_ERR(priv->rst))
-   return PTR_ERR(priv->rst);
+   if (IS_ERR(priv->rst)) {
+   ret = PTR_ERR(priv->rst);
+   goto clk_off;
+   }
 
wdd = >wdd;
wdd->info = _wdt_ident;
-- 
2.7.4



  1   2   3   4   5   6   7   8   9   >