aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/timer-atmel-pit.c
diff options
context:
space:
mode:
authorAlexandre Belloni <alexandre.belloni@bootlin.com>2018-04-25 06:14:39 -0400
committerDaniel Lezcano <daniel.lezcano@linaro.org>2018-09-27 06:01:45 -0400
commit52bf4a900d9cede3eb14982d0f2c5e6db6d97cc3 (patch)
tree906874b02bd01b43125047dc82aa700226c94cdb /drivers/clocksource/timer-atmel-pit.c
parent4451d3f59f2a6f95e5d205c2d04ea072955d080d (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.c20
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
262exit:
263 kfree(data);
264 return ret;
257} 265}
258TIMER_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit", 266TIMER_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit",
259 at91sam926x_pit_dt_init); 267 at91sam926x_pit_dt_init);