rtc: ftrtc010: Fix error handling in ftrtc010_rtc_probe

In the error handling path, the clk_prepare_enable() function
call should be balanced by a corresponding 'clk_disable_unprepare()'
call , as already done in the remove function.

clk_disable_unprepare calls clk_disable() and clk_unprepare().
They will use IS_ERR_OR_NULL to check the argument.

Fixes: ac05fba39cc5 ("rtc: gemini: Add optional clock handling")
Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://lore.kernel.org/r/20220403054912.31739-1-linmq006@gmail.com

authored by Miaoqian Lin and committed by Alexandre Belloni b520cbe5 d3b43eb5

+24 -10
+24 -10
drivers/rtc/rtc-ftrtc010.c
··· 137 137 ret = clk_prepare_enable(rtc->extclk); 138 138 if (ret) { 139 139 dev_err(dev, "failed to enable EXTCLK\n"); 140 - return ret; 140 + goto err_disable_pclk; 141 141 } 142 142 } 143 143 144 144 rtc->rtc_irq = platform_get_irq(pdev, 0); 145 - if (rtc->rtc_irq < 0) 146 - return rtc->rtc_irq; 145 + if (rtc->rtc_irq < 0) { 146 + ret = rtc->rtc_irq; 147 + goto err_disable_extclk; 148 + } 147 149 148 150 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 149 - if (!res) 150 - return -ENODEV; 151 + if (!res) { 152 + ret = -ENODEV; 153 + goto err_disable_extclk; 154 + } 151 155 152 156 rtc->rtc_base = devm_ioremap(dev, res->start, 153 157 resource_size(res)); 154 - if (!rtc->rtc_base) 155 - return -ENOMEM; 158 + if (!rtc->rtc_base) { 159 + ret = -ENOMEM; 160 + goto err_disable_extclk; 161 + } 156 162 157 163 rtc->rtc_dev = devm_rtc_allocate_device(dev); 158 - if (IS_ERR(rtc->rtc_dev)) 159 - return PTR_ERR(rtc->rtc_dev); 164 + if (IS_ERR(rtc->rtc_dev)) { 165 + ret = PTR_ERR(rtc->rtc_dev); 166 + goto err_disable_extclk; 167 + } 160 168 161 169 rtc->rtc_dev->ops = &ftrtc010_rtc_ops; 162 170 ··· 180 172 ret = devm_request_irq(dev, rtc->rtc_irq, ftrtc010_rtc_interrupt, 181 173 IRQF_SHARED, pdev->name, dev); 182 174 if (unlikely(ret)) 183 - return ret; 175 + goto err_disable_extclk; 184 176 185 177 return devm_rtc_register_device(rtc->rtc_dev); 178 + 179 + err_disable_extclk: 180 + clk_disable_unprepare(rtc->extclk); 181 + err_disable_pclk: 182 + clk_disable_unprepare(rtc->pclk); 183 + return ret; 186 184 } 187 185 188 186 static int ftrtc010_rtc_remove(struct platform_device *pdev)