Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2fd44d2b authored by Qinrun Dai's avatar Qinrun Dai Committed by Greg Kroah-Hartman
Browse files

clocksource/drivers/davinci: Fix memory leak in davinci_timer_register when init fails



[ 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: 721154f9 ("clocksource/drivers/davinci: Add support for clockevents")
Signed-off-by: default avatarQinrun Dai <flno@hust.edu.cn>
Link: https://lore.kernel.org/r/20230413135037.1505799-1-flno@hust.edu.cn


Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent f2aaf419
Loading
Loading
Loading
Loading
+24 −6
Original line number Diff line number Diff line
@@ -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)