aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-msm/iommu_dev.c
diff options
context:
space:
mode:
authorVasiliy Kulikov <segooon@gmail.com>2010-10-17 10:51:37 -0400
committerDaniel Walker <dwalker@codeaurora.org>2010-10-27 17:24:02 -0400
commita86c44d48a03dcd73972ddadb55a77e6b308fa0b (patch)
treefef441538decf37de14808f889b9177d56f478df /arch/arm/mach-msm/iommu_dev.c
parentefdfb2b118cc11c88adcbcb8036795eb34f419a8 (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.c22
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
129static int msm_iommu_probe(struct platform_device *pdev) 129static 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
240fail_io:
241 iounmap(regs_base);
242fail_mem:
243 release_mem_region(r->start, len);
240fail: 244fail:
241 kfree(drvdata); 245 kfree(drvdata);
242 return ret; 246 return ret;