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 | |
| 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>
| -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; |
