When clk_get_rate() fails, a pairing PM usage counter decrement
and disable is required to prevent refcount leak. It's the same
for the subsequent error paths. When of_clk_add_hw_provider()
fails, we need to unregister clk_hw.

Signed-off-by: Dinghao Liu <dinghao....@zju.edu.cn>
---
 drivers/clk/renesas/rcar-usb2-clock-sel.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/renesas/rcar-usb2-clock-sel.c 
b/drivers/clk/renesas/rcar-usb2-clock-sel.c
index 3abafd78f7c8..ad7bd50b9d1b 100644
--- a/drivers/clk/renesas/rcar-usb2-clock-sel.c
+++ b/drivers/clk/renesas/rcar-usb2-clock-sel.c
@@ -180,7 +180,8 @@ static int rcar_usb2_clock_sel_probe(struct platform_device 
*pdev)
 
        if (!priv->extal && !priv->xtal) {
                dev_err(dev, "This driver needs usb_extal or usb_xtal\n");
-               return -ENOENT;
+               ret = -ENOENT;
+               goto pm_put;
        }
 
        platform_set_drvdata(pdev, priv);
@@ -194,10 +195,23 @@ static int rcar_usb2_clock_sel_probe(struct 
platform_device *pdev)
        priv->hw.init = &init;
 
        clk = clk_register(NULL, &priv->hw);
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
+       if (IS_ERR(clk)) {
+               ret = PTR_ERR(clk);
+               goto pm_put;
+       }
+
+       ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw);
+       if (ret)
+               goto clk_unregister;
+
+       return 0;
 
-       return of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw);
+clk_unregister:
+       clk_hw_unregister(&priv->hw);
+pm_put:
+       pm_runtime_put(dev);
+       pm_runtime_disable(dev);
+       return ret;
 }
 
 static const struct dev_pm_ops rcar_usb2_clock_sel_pm_ops = {
-- 
2.17.1

Reply via email to