diff options
author | Geert Uytterhoeven <geert@linux-m68k.org> | 2013-10-29 10:47:22 -0400 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2013-11-11 06:22:17 -0500 |
commit | 0b208e41acf34c133a55a57189af30aa7924e0c6 (patch) | |
tree | aa8f813eb55219b8a57260c9408478829e4d9ad6 /drivers | |
parent | 03e361b25ee8dfb1fd9b890072c23c4aae01c6c7 (diff) |
mfd: Fix memory leak in mfd_add_devices()
If the first call to mfd_add_device() fails, no child devices have been
registered to the parent yet, and thus mfd_remove_devices() won't find
anything to remove nor free.
Hence the previously allocated array of atomic_t objects will leak.
Free the array instead of calling mfd_remove_devices() on failure during
the first loop iteration to fix this.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mfd/mfd-core.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 8736f4539bc0..968775da638a 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c | |||
@@ -187,7 +187,7 @@ int mfd_add_devices(struct device *parent, int id, | |||
187 | int irq_base, struct irq_domain *domain) | 187 | int irq_base, struct irq_domain *domain) |
188 | { | 188 | { |
189 | int i; | 189 | int i; |
190 | int ret = 0; | 190 | int ret; |
191 | atomic_t *cnts; | 191 | atomic_t *cnts; |
192 | 192 | ||
193 | /* initialize reference counting for all cells */ | 193 | /* initialize reference counting for all cells */ |
@@ -200,12 +200,16 @@ int mfd_add_devices(struct device *parent, int id, | |||
200 | ret = mfd_add_device(parent, id, cells + i, cnts + i, mem_base, | 200 | ret = mfd_add_device(parent, id, cells + i, cnts + i, mem_base, |
201 | irq_base, domain); | 201 | irq_base, domain); |
202 | if (ret) | 202 | if (ret) |
203 | break; | 203 | goto fail; |
204 | } | 204 | } |
205 | 205 | ||
206 | if (ret) | 206 | return 0; |
207 | mfd_remove_devices(parent); | ||
208 | 207 | ||
208 | fail: | ||
209 | if (i) | ||
210 | mfd_remove_devices(parent); | ||
211 | else | ||
212 | kfree(cnts); | ||
209 | return ret; | 213 | return ret; |
210 | } | 214 | } |
211 | EXPORT_SYMBOL(mfd_add_devices); | 215 | EXPORT_SYMBOL(mfd_add_devices); |