i2c: ocores: use devm_ managed clks
authorWang Zhang <silver_code@hust.edu.cn>
Fri, 26 May 2023 07:05:33 +0000 (15:05 +0800)
committerWolfram Sang <wsa@kernel.org>
Fri, 23 Jun 2023 08:20:40 +0000 (10:20 +0200)
Smatch complains that:
drivers/i2c/busses/i2c-ocores.c:704 ocores_i2c_probe()
warn: missing unwind goto?

If any wrong occurs in ocores_i2c_of_probe, the i2c->clk needs to be
released. But the function returns directly without freeing the clock.

Fix this by updating the code to use devm_clk_get_optional_enabled()
instead. Use dev_err_probe() where appropriate as well since we are
changing those statements.

Fixes: f5f35a92e44a ("i2c: ocores: Add irq support for sparc")
Signed-off-by: Wang Zhang <silver_code@hust.edu.cn>
Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
drivers/i2c/busses/i2c-ocores.c

index 0742b84..4ac77e5 100644 (file)
@@ -552,28 +552,20 @@ static int ocores_i2c_of_probe(struct platform_device *pdev,
                                                        &clock_frequency);
        i2c->bus_clock_khz = 100;
 
-       i2c->clk = devm_clk_get(&pdev->dev, NULL);
-
-       if (!IS_ERR(i2c->clk)) {
-               int ret = clk_prepare_enable(i2c->clk);
-
-               if (ret) {
-                       dev_err(&pdev->dev,
-                               "clk_prepare_enable failed: %d\n", ret);
-                       return ret;
-               }
-               i2c->ip_clock_khz = clk_get_rate(i2c->clk) / 1000;
-               if (clock_frequency_present)
-                       i2c->bus_clock_khz = clock_frequency / 1000;
-       }
-
+       i2c->clk = devm_clk_get_optional_enabled(&pdev->dev, NULL);
+       if (IS_ERR(i2c->clk))
+               return dev_err_probe(&pdev->dev, PTR_ERR(i2c->clk),
+                                    "devm_clk_get_optional_enabled failed\n");
+
+       i2c->ip_clock_khz = clk_get_rate(i2c->clk) / 1000;
+       if (clock_frequency_present)
+               i2c->bus_clock_khz = clock_frequency / 1000;
        if (i2c->ip_clock_khz == 0) {
                if (of_property_read_u32(np, "opencores,ip-clock-frequency",
                                                &val)) {
                        if (!clock_frequency_present) {
                                dev_err(&pdev->dev,
                                        "Missing required parameter 'opencores,ip-clock-frequency'\n");
-                               clk_disable_unprepare(i2c->clk);
                                return -ENODEV;
                        }
                        i2c->ip_clock_khz = clock_frequency / 1000;
@@ -678,8 +670,7 @@ static int ocores_i2c_probe(struct platform_device *pdev)
                default:
                        dev_err(&pdev->dev, "Unsupported I/O width (%d)\n",
                                i2c->reg_io_width);
-                       ret = -EINVAL;
-                       goto err_clk;
+                       return -EINVAL;
                }
        }
 
@@ -710,13 +701,13 @@ static int ocores_i2c_probe(struct platform_device *pdev)
                                                   pdev->name, i2c);
                if (ret) {
                        dev_err(&pdev->dev, "Cannot claim IRQ\n");
-                       goto err_clk;
+                       return ret;
                }
        }
 
        ret = ocores_init(&pdev->dev, i2c);
        if (ret)
-               goto err_clk;
+               return ret;
 
        /* hook up driver to tree */
        platform_set_drvdata(pdev, i2c);
@@ -728,7 +719,7 @@ static int ocores_i2c_probe(struct platform_device *pdev)
        /* add i2c adapter to i2c tree */
        ret = i2c_add_adapter(&i2c->adap);
        if (ret)
-               goto err_clk;
+               return ret;
 
        /* add in known devices to the bus */
        if (pdata) {
@@ -737,10 +728,6 @@ static int ocores_i2c_probe(struct platform_device *pdev)
        }
 
        return 0;
-
-err_clk:
-       clk_disable_unprepare(i2c->clk);
-       return ret;
 }
 
 static void ocores_i2c_remove(struct platform_device *pdev)
@@ -754,9 +741,6 @@ static void ocores_i2c_remove(struct platform_device *pdev)
 
        /* remove adapter & data */
        i2c_del_adapter(&i2c->adap);
-
-       if (!IS_ERR(i2c->clk))
-               clk_disable_unprepare(i2c->clk);
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -769,28 +753,22 @@ static int ocores_i2c_suspend(struct device *dev)
        ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN);
        oc_setreg(i2c, OCI2C_CONTROL, ctrl);
 
-       if (!IS_ERR(i2c->clk))
-               clk_disable_unprepare(i2c->clk);
+       clk_disable_unprepare(i2c->clk);
        return 0;
 }
 
 static int ocores_i2c_resume(struct device *dev)
 {
        struct ocores_i2c *i2c = dev_get_drvdata(dev);
+       unsigned long rate;
+       int ret;
 
-       if (!IS_ERR(i2c->clk)) {
-               unsigned long rate;
-               int ret = clk_prepare_enable(i2c->clk);
-
-               if (ret) {
-                       dev_err(dev,
-                               "clk_prepare_enable failed: %d\n", ret);
-                       return ret;
-               }
-               rate = clk_get_rate(i2c->clk) / 1000;
-               if (rate)
-                       i2c->ip_clock_khz = rate;
-       }
+       ret = clk_prepare_enable(i2c->clk);
+       if (ret)
+               return dev_err_probe(dev, ret, "clk_prepare_enable failed\n");
+       rate = clk_get_rate(i2c->clk) / 1000;
+       if (rate)
+               i2c->ip_clock_khz = rate;
        return ocores_init(dev, i2c);
 }