From: Qinrun Dai flno@hust.edu.cn
[ Upstream commit fb73556386e074e9bee9fa2d253aeaefe4e063e0 ]
Smatch reports: drivers/clocksource/timer-davinci.c:332 davinci_timer_register() warn: 'base' from ioremap() not released on lines: 274.
Fix this and other potential memory leak problems by adding a set of corresponding exit lables.
Fixes: 721154f972aa ("clocksource/drivers/davinci: Add support for clockevents") Signed-off-by: Qinrun Dai flno@hust.edu.cn Link: https://lore.kernel.org/r/20230413135037.1505799-1-flno@hust.edu.cn Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clocksource/timer-davinci.c | 30 +++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/drivers/clocksource/timer-davinci.c b/drivers/clocksource/timer-davinci.c index bb4eee31ae082..3dc0c6ceed027 100644 --- a/drivers/clocksource/timer-davinci.c +++ b/drivers/clocksource/timer-davinci.c @@ -258,21 +258,25 @@ int __init davinci_timer_register(struct clk *clk, resource_size(&timer_cfg->reg), "davinci-timer")) { pr_err("Unable to request memory region\n"); - return -EBUSY; + rv = -EBUSY; + goto exit_clk_disable; }
base = ioremap(timer_cfg->reg.start, resource_size(&timer_cfg->reg)); if (!base) { pr_err("Unable to map the register range\n"); - return -ENOMEM; + rv = -ENOMEM; + goto exit_mem_region; }
davinci_timer_init(base); tick_rate = clk_get_rate(clk);
clockevent = kzalloc(sizeof(*clockevent), GFP_KERNEL); - if (!clockevent) - return -ENOMEM; + if (!clockevent) { + rv = -ENOMEM; + goto exit_iounmap_base; + }
clockevent->dev.name = "tim12"; clockevent->dev.features = CLOCK_EVT_FEAT_ONESHOT; @@ -297,7 +301,7 @@ int __init davinci_timer_register(struct clk *clk, "clockevent/tim12", clockevent); if (rv) { pr_err("Unable to request the clockevent interrupt\n"); - return rv; + goto exit_free_clockevent; }
davinci_clocksource.dev.rating = 300; @@ -324,13 +328,27 @@ int __init davinci_timer_register(struct clk *clk, rv = clocksource_register_hz(&davinci_clocksource.dev, tick_rate); if (rv) { pr_err("Unable to register clocksource\n"); - return rv; + goto exit_free_irq; }
sched_clock_register(davinci_timer_read_sched_clock, DAVINCI_TIMER_CLKSRC_BITS, tick_rate);
return 0; + +exit_free_irq: + free_irq(timer_cfg->irq[DAVINCI_TIMER_CLOCKEVENT_IRQ].start, + clockevent); +exit_free_clockevent: + kfree(clockevent); +exit_iounmap_base: + iounmap(base); +exit_mem_region: + release_mem_region(timer_cfg->reg.start, + resource_size(&timer_cfg->reg)); +exit_clk_disable: + clk_disable_unprepare(clk); + return rv; }
static int __init of_davinci_timer_register(struct device_node *np)