dma: mpc512x: fix freeing resources in mpc_dma_probe() and mpc_dma_remove()
[deliverable/linux.git] / drivers / dma / mpc512x_dma.c
index 0b17f4db1908c91e2c5761c294da7ec1447952cd..96104f4eebe8d0d40b791bf453c0af646df23959 100644 (file)
@@ -657,13 +657,15 @@ static int mpc_dma_probe(struct platform_device *op)
        mdma = devm_kzalloc(dev, sizeof(struct mpc_dma), GFP_KERNEL);
        if (!mdma) {
                dev_err(dev, "Memory exhausted!\n");
-               return -ENOMEM;
+               retval = -ENOMEM;
+               goto err;
        }
 
        mdma->irq = irq_of_parse_and_map(dn, 0);
        if (mdma->irq == NO_IRQ) {
                dev_err(dev, "Error mapping IRQ!\n");
-               return -EINVAL;
+               retval = -EINVAL;
+               goto err;
        }
 
        if (of_device_is_compatible(dn, "fsl,mpc8308-dma")) {
@@ -671,14 +673,15 @@ static int mpc_dma_probe(struct platform_device *op)
                mdma->irq2 = irq_of_parse_and_map(dn, 1);
                if (mdma->irq2 == NO_IRQ) {
                        dev_err(dev, "Error mapping IRQ!\n");
-                       return -EINVAL;
+                       retval = -EINVAL;
+                       goto err_dispose1;
                }
        }
 
        retval = of_address_to_resource(dn, 0, &res);
        if (retval) {
                dev_err(dev, "Error parsing memory region!\n");
-               return retval;
+               goto err_dispose2;
        }
 
        regs_start = res.start;
@@ -686,31 +689,34 @@ static int mpc_dma_probe(struct platform_device *op)
 
        if (!devm_request_mem_region(dev, regs_start, regs_size, DRV_NAME)) {
                dev_err(dev, "Error requesting memory region!\n");
-               return -EBUSY;
+               retval = -EBUSY;
+               goto err_dispose2;
        }
 
        mdma->regs = devm_ioremap(dev, regs_start, regs_size);
        if (!mdma->regs) {
                dev_err(dev, "Error mapping memory region!\n");
-               return -ENOMEM;
+               retval = -ENOMEM;
+               goto err_dispose2;
        }
 
        mdma->tcd = (struct mpc_dma_tcd *)((u8 *)(mdma->regs)
                                                        + MPC_DMA_TCD_OFFSET);
 
-       retval = devm_request_irq(dev, mdma->irq, &mpc_dma_irq, 0, DRV_NAME,
-                                                                       mdma);
+       retval = request_irq(mdma->irq, &mpc_dma_irq, 0, DRV_NAME, mdma);
        if (retval) {
                dev_err(dev, "Error requesting IRQ!\n");
-               return -EINVAL;
+               retval = -EINVAL;
+               goto err_dispose2;
        }
 
        if (mdma->is_mpc8308) {
-               retval = devm_request_irq(dev, mdma->irq2, &mpc_dma_irq, 0,
-                               DRV_NAME, mdma);
+               retval = request_irq(mdma->irq2, &mpc_dma_irq, 0,
+                                                       DRV_NAME, mdma);
                if (retval) {
                        dev_err(dev, "Error requesting IRQ2!\n");
-                       return -EINVAL;
+                       retval = -EINVAL;
+                       goto err_free1;
                }
        }
 
@@ -793,12 +799,23 @@ static int mpc_dma_probe(struct platform_device *op)
        /* Register DMA engine */
        dev_set_drvdata(dev, mdma);
        retval = dma_async_device_register(dma);
-       if (retval) {
-               devm_free_irq(dev, mdma->irq, mdma);
-               irq_dispose_mapping(mdma->irq);
-       }
+       if (retval)
+               goto err_free2;
 
        return retval;
+
+err_free2:
+       if (mdma->is_mpc8308)
+               free_irq(mdma->irq2, mdma);
+err_free1:
+       free_irq(mdma->irq, mdma);
+err_dispose2:
+       if (mdma->is_mpc8308)
+               irq_dispose_mapping(mdma->irq2);
+err_dispose1:
+       irq_dispose_mapping(mdma->irq);
+err:
+       return retval;
 }
 
 static int mpc_dma_remove(struct platform_device *op)
@@ -807,7 +824,11 @@ static int mpc_dma_remove(struct platform_device *op)
        struct mpc_dma *mdma = dev_get_drvdata(dev);
 
        dma_async_device_unregister(&mdma->dma);
-       devm_free_irq(dev, mdma->irq, mdma);
+       if (mdma->is_mpc8308) {
+               free_irq(mdma->irq2, mdma);
+               irq_dispose_mapping(mdma->irq2);
+       }
+       free_irq(mdma->irq, mdma);
        irq_dispose_mapping(mdma->irq);
 
        return 0;
This page took 0.028725 seconds and 5 git commands to generate.