diff options
author | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2018-04-25 06:14:39 -0400 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2018-09-27 06:01:45 -0400 |
commit | 52bf4a900d9cede3eb14982d0f2c5e6db6d97cc3 (patch) | |
tree | 906874b02bd01b43125047dc82aa700226c94cdb /drivers/clocksource/timer-atmel-pit.c | |
parent | 4451d3f59f2a6f95e5d205c2d04ea072955d080d (diff) |
clocksource/drivers/timer-atmel-pit: Properly handle error cases
The smatch utility reports a possible leak:
smatch warnings:
drivers/clocksource/timer-atmel-pit.c:183 at91sam926x_pit_dt_init() warn: possible memory leak of 'data'
Ensure data is freed before exiting with an error.
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: stable@vger.kernel.org
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Diffstat (limited to 'drivers/clocksource/timer-atmel-pit.c')
-rw-r--r-- | drivers/clocksource/timer-atmel-pit.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/clocksource/timer-atmel-pit.c b/drivers/clocksource/timer-atmel-pit.c index ec8a4376f74f..2fab18fae4fc 100644 --- a/drivers/clocksource/timer-atmel-pit.c +++ b/drivers/clocksource/timer-atmel-pit.c | |||
@@ -180,26 +180,29 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node) | |||
180 | data->base = of_iomap(node, 0); | 180 | data->base = of_iomap(node, 0); |
181 | if (!data->base) { | 181 | if (!data->base) { |
182 | pr_err("Could not map PIT address\n"); | 182 | pr_err("Could not map PIT address\n"); |
183 | return -ENXIO; | 183 | ret = -ENXIO; |
184 | goto exit; | ||
184 | } | 185 | } |
185 | 186 | ||
186 | data->mck = of_clk_get(node, 0); | 187 | data->mck = of_clk_get(node, 0); |
187 | if (IS_ERR(data->mck)) { | 188 | if (IS_ERR(data->mck)) { |
188 | pr_err("Unable to get mck clk\n"); | 189 | pr_err("Unable to get mck clk\n"); |
189 | return PTR_ERR(data->mck); | 190 | ret = PTR_ERR(data->mck); |
191 | goto exit; | ||
190 | } | 192 | } |
191 | 193 | ||
192 | ret = clk_prepare_enable(data->mck); | 194 | ret = clk_prepare_enable(data->mck); |
193 | if (ret) { | 195 | if (ret) { |
194 | pr_err("Unable to enable mck\n"); | 196 | pr_err("Unable to enable mck\n"); |
195 | return ret; | 197 | goto exit; |
196 | } | 198 | } |
197 | 199 | ||
198 | /* Get the interrupts property */ | 200 | /* Get the interrupts property */ |
199 | data->irq = irq_of_parse_and_map(node, 0); | 201 | data->irq = irq_of_parse_and_map(node, 0); |
200 | if (!data->irq) { | 202 | if (!data->irq) { |
201 | pr_err("Unable to get IRQ from DT\n"); | 203 | pr_err("Unable to get IRQ from DT\n"); |
202 | return -EINVAL; | 204 | ret = -EINVAL; |
205 | goto exit; | ||
203 | } | 206 | } |
204 | 207 | ||
205 | /* | 208 | /* |
@@ -227,7 +230,7 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node) | |||
227 | ret = clocksource_register_hz(&data->clksrc, pit_rate); | 230 | ret = clocksource_register_hz(&data->clksrc, pit_rate); |
228 | if (ret) { | 231 | if (ret) { |
229 | pr_err("Failed to register clocksource\n"); | 232 | pr_err("Failed to register clocksource\n"); |
230 | return ret; | 233 | goto exit; |
231 | } | 234 | } |
232 | 235 | ||
233 | /* Set up irq handler */ | 236 | /* Set up irq handler */ |
@@ -236,7 +239,8 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node) | |||
236 | "at91_tick", data); | 239 | "at91_tick", data); |
237 | if (ret) { | 240 | if (ret) { |
238 | pr_err("Unable to setup IRQ\n"); | 241 | pr_err("Unable to setup IRQ\n"); |
239 | return ret; | 242 | clocksource_unregister(&data->clksrc); |
243 | goto exit; | ||
240 | } | 244 | } |
241 | 245 | ||
242 | /* Set up and register clockevents */ | 246 | /* Set up and register clockevents */ |
@@ -254,6 +258,10 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node) | |||
254 | clockevents_register_device(&data->clkevt); | 258 | clockevents_register_device(&data->clkevt); |
255 | 259 | ||
256 | return 0; | 260 | return 0; |
261 | |||
262 | exit: | ||
263 | kfree(data); | ||
264 | return ret; | ||
257 | } | 265 | } |
258 | TIMER_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit", | 266 | TIMER_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit", |
259 | at91sam926x_pit_dt_init); | 267 | at91sam926x_pit_dt_init); |