diff options
author | Vasiliy Kulikov <segooon@gmail.com> | 2010-10-17 10:51:37 -0400 |
---|---|---|
committer | Daniel Walker <dwalker@codeaurora.org> | 2010-10-27 17:24:02 -0400 |
commit | a86c44d48a03dcd73972ddadb55a77e6b308fa0b (patch) | |
tree | fef441538decf37de14808f889b9177d56f478df /arch/arm/mach-msm/iommu_dev.c | |
parent | efdfb2b118cc11c88adcbcb8036795eb34f419a8 (diff) |
arm: mach-msm: fix error handling in msm_iommu_probe()
msm_iommu_probe() didn't free mem_region and mapped IO.
Also if request_mem_region() failed then error handling
code dereferenced NULL pointer.
Signed-off-by: Vasiliy Kulikov <segooon@gmail.com>
Acked-by: Stepan Moskovchenko <stepanm@codeaurora.org>
Signed-off-by: Daniel Walker <dwalker@codeaurora.org>
Diffstat (limited to 'arch/arm/mach-msm/iommu_dev.c')
-rw-r--r-- | arch/arm/mach-msm/iommu_dev.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/arch/arm/mach-msm/iommu_dev.c b/arch/arm/mach-msm/iommu_dev.c index c33ae786c41f..9019cee2907b 100644 --- a/arch/arm/mach-msm/iommu_dev.c +++ b/arch/arm/mach-msm/iommu_dev.c | |||
@@ -128,7 +128,7 @@ static void msm_iommu_reset(void __iomem *base) | |||
128 | 128 | ||
129 | static int msm_iommu_probe(struct platform_device *pdev) | 129 | static int msm_iommu_probe(struct platform_device *pdev) |
130 | { | 130 | { |
131 | struct resource *r; | 131 | struct resource *r, *r2; |
132 | struct clk *iommu_clk; | 132 | struct clk *iommu_clk; |
133 | struct msm_iommu_drvdata *drvdata; | 133 | struct msm_iommu_drvdata *drvdata; |
134 | struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data; | 134 | struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data; |
@@ -183,27 +183,27 @@ static int msm_iommu_probe(struct platform_device *pdev) | |||
183 | 183 | ||
184 | len = r->end - r->start + 1; | 184 | len = r->end - r->start + 1; |
185 | 185 | ||
186 | r = request_mem_region(r->start, len, r->name); | 186 | r2 = request_mem_region(r->start, len, r->name); |
187 | if (!r) { | 187 | if (!r2) { |
188 | pr_err("Could not request memory region: " | 188 | pr_err("Could not request memory region: " |
189 | "start=%p, len=%d\n", (void *) r->start, len); | 189 | "start=%p, len=%d\n", (void *) r->start, len); |
190 | ret = -EBUSY; | 190 | ret = -EBUSY; |
191 | goto fail; | 191 | goto fail; |
192 | } | 192 | } |
193 | 193 | ||
194 | regs_base = ioremap(r->start, len); | 194 | regs_base = ioremap(r2->start, len); |
195 | 195 | ||
196 | if (!regs_base) { | 196 | if (!regs_base) { |
197 | pr_err("Could not ioremap: start=%p, len=%d\n", | 197 | pr_err("Could not ioremap: start=%p, len=%d\n", |
198 | (void *) r->start, len); | 198 | (void *) r2->start, len); |
199 | ret = -EBUSY; | 199 | ret = -EBUSY; |
200 | goto fail; | 200 | goto fail_mem; |
201 | } | 201 | } |
202 | 202 | ||
203 | irq = platform_get_irq_byname(pdev, "secure_irq"); | 203 | irq = platform_get_irq_byname(pdev, "secure_irq"); |
204 | if (irq < 0) { | 204 | if (irq < 0) { |
205 | ret = -ENODEV; | 205 | ret = -ENODEV; |
206 | goto fail; | 206 | goto fail_io; |
207 | } | 207 | } |
208 | 208 | ||
209 | mb(); | 209 | mb(); |
@@ -211,14 +211,14 @@ static int msm_iommu_probe(struct platform_device *pdev) | |||
211 | if (GET_IDR(regs_base) == 0) { | 211 | if (GET_IDR(regs_base) == 0) { |
212 | pr_err("Invalid IDR value detected\n"); | 212 | pr_err("Invalid IDR value detected\n"); |
213 | ret = -ENODEV; | 213 | ret = -ENODEV; |
214 | goto fail; | 214 | goto fail_io; |
215 | } | 215 | } |
216 | 216 | ||
217 | ret = request_irq(irq, msm_iommu_fault_handler, 0, | 217 | ret = request_irq(irq, msm_iommu_fault_handler, 0, |
218 | "msm_iommu_secure_irpt_handler", drvdata); | 218 | "msm_iommu_secure_irpt_handler", drvdata); |
219 | if (ret) { | 219 | if (ret) { |
220 | pr_err("Request IRQ %d failed with ret=%d\n", irq, ret); | 220 | pr_err("Request IRQ %d failed with ret=%d\n", irq, ret); |
221 | goto fail; | 221 | goto fail_io; |
222 | } | 222 | } |
223 | 223 | ||
224 | msm_iommu_reset(regs_base); | 224 | msm_iommu_reset(regs_base); |
@@ -237,6 +237,10 @@ static int msm_iommu_probe(struct platform_device *pdev) | |||
237 | 237 | ||
238 | return 0; | 238 | return 0; |
239 | 239 | ||
240 | fail_io: | ||
241 | iounmap(regs_base); | ||
242 | fail_mem: | ||
243 | release_mem_region(r->start, len); | ||
240 | fail: | 244 | fail: |
241 | kfree(drvdata); | 245 | kfree(drvdata); |
242 | return ret; | 246 | return ret; |