diff options
author | Sudip Mukherjee <sudipm.mukherjee@gmail.com> | 2016-12-18 17:26:36 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-12-19 05:19:57 -0500 |
commit | c9435f35ae64ee162555a82b6a3586b160093957 (patch) | |
tree | bf2e4cb2375b202d0affeead14cdcdbc03b7b9f2 | |
parent | b0b3a37b908b5906524c11f3ca12cd7c9d4adc1c (diff) |
clocksource/drivers/moxart: Plug memory and mapping leaks
If of_iomap() or any other subsequent function fails moxart_timer_init()
exits without freeing memory and unmapping the timer base.
Add proper cleanup points.
Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
Link: http://lkml.kernel.org/r/1482099996-1524-1-git-send-email-sudipm.mukherjee@gmail.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | drivers/clocksource/moxart_timer.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/clocksource/moxart_timer.c b/drivers/clocksource/moxart_timer.c index 2a8f4705c734..7f3430654fbd 100644 --- a/drivers/clocksource/moxart_timer.c +++ b/drivers/clocksource/moxart_timer.c | |||
@@ -161,19 +161,22 @@ static int __init moxart_timer_init(struct device_node *node) | |||
161 | timer->base = of_iomap(node, 0); | 161 | timer->base = of_iomap(node, 0); |
162 | if (!timer->base) { | 162 | if (!timer->base) { |
163 | pr_err("%s: of_iomap failed\n", node->full_name); | 163 | pr_err("%s: of_iomap failed\n", node->full_name); |
164 | return -ENXIO; | 164 | ret = -ENXIO; |
165 | goto out_free; | ||
165 | } | 166 | } |
166 | 167 | ||
167 | irq = irq_of_parse_and_map(node, 0); | 168 | irq = irq_of_parse_and_map(node, 0); |
168 | if (irq <= 0) { | 169 | if (irq <= 0) { |
169 | pr_err("%s: irq_of_parse_and_map failed\n", node->full_name); | 170 | pr_err("%s: irq_of_parse_and_map failed\n", node->full_name); |
170 | return -EINVAL; | 171 | ret = -EINVAL; |
172 | goto out_unmap; | ||
171 | } | 173 | } |
172 | 174 | ||
173 | clk = of_clk_get(node, 0); | 175 | clk = of_clk_get(node, 0); |
174 | if (IS_ERR(clk)) { | 176 | if (IS_ERR(clk)) { |
175 | pr_err("%s: of_clk_get failed\n", node->full_name); | 177 | pr_err("%s: of_clk_get failed\n", node->full_name); |
176 | return PTR_ERR(clk); | 178 | ret = PTR_ERR(clk); |
179 | goto out_unmap; | ||
177 | } | 180 | } |
178 | 181 | ||
179 | pclk = clk_get_rate(clk); | 182 | pclk = clk_get_rate(clk); |
@@ -186,7 +189,8 @@ static int __init moxart_timer_init(struct device_node *node) | |||
186 | timer->t1_disable_val = ASPEED_TIMER1_DISABLE; | 189 | timer->t1_disable_val = ASPEED_TIMER1_DISABLE; |
187 | } else { | 190 | } else { |
188 | pr_err("%s: unknown platform\n", node->full_name); | 191 | pr_err("%s: unknown platform\n", node->full_name); |
189 | return -EINVAL; | 192 | ret = -EINVAL; |
193 | goto out_unmap; | ||
190 | } | 194 | } |
191 | 195 | ||
192 | timer->count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ); | 196 | timer->count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ); |
@@ -208,14 +212,14 @@ static int __init moxart_timer_init(struct device_node *node) | |||
208 | clocksource_mmio_readl_down); | 212 | clocksource_mmio_readl_down); |
209 | if (ret) { | 213 | if (ret) { |
210 | pr_err("%s: clocksource_mmio_init failed\n", node->full_name); | 214 | pr_err("%s: clocksource_mmio_init failed\n", node->full_name); |
211 | return ret; | 215 | goto out_unmap; |
212 | } | 216 | } |
213 | 217 | ||
214 | ret = request_irq(irq, moxart_timer_interrupt, IRQF_TIMER, | 218 | ret = request_irq(irq, moxart_timer_interrupt, IRQF_TIMER, |
215 | node->name, &timer->clkevt); | 219 | node->name, &timer->clkevt); |
216 | if (ret) { | 220 | if (ret) { |
217 | pr_err("%s: setup_irq failed\n", node->full_name); | 221 | pr_err("%s: setup_irq failed\n", node->full_name); |
218 | return ret; | 222 | goto out_unmap; |
219 | } | 223 | } |
220 | 224 | ||
221 | /* Clear match registers */ | 225 | /* Clear match registers */ |
@@ -241,6 +245,12 @@ static int __init moxart_timer_init(struct device_node *node) | |||
241 | clockevents_config_and_register(&timer->clkevt, pclk, 0x4, 0xfffffffe); | 245 | clockevents_config_and_register(&timer->clkevt, pclk, 0x4, 0xfffffffe); |
242 | 246 | ||
243 | return 0; | 247 | return 0; |
248 | |||
249 | out_unmap: | ||
250 | iounmap(timer->base); | ||
251 | out_free: | ||
252 | kfree(timer); | ||
253 | return ret; | ||
244 | } | 254 | } |
245 | CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", moxart_timer_init); | 255 | CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", moxart_timer_init); |
246 | CLOCKSOURCE_OF_DECLARE(aspeed, "aspeed,ast2400-timer", moxart_timer_init); | 256 | CLOCKSOURCE_OF_DECLARE(aspeed, "aspeed,ast2400-timer", moxart_timer_init); |