diff options
author | Alexander Popov <a13xp0p0v88@gmail.com> | 2014-04-23 09:53:26 -0400 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2014-05-02 13:06:22 -0400 |
commit | baca66f7960f60a7ed5884acf4eb1a76d868c43c (patch) | |
tree | 45f3997cc14ac18aa465ddf5bf179b44b1089f4c /drivers | |
parent | 62057d3375a5237c24f1dee82cb6c860081cc4ff (diff) |
dma: mpc512x: fix freeing resources in mpc_dma_probe() and mpc_dma_remove()
Fix mpc_dma_probe() error path and mpc_dma_remove(): manually free IRQs and
dispose IRQ mappings before devm_* takes care of other resources.
Moreover replace devm_request_irq() with request_irq() since there is no need
to use it because the original code always frees IRQ manually with
devm_free_irq(). Replace devm_free_irq() with free_irq() accordingly.
Signed-off-by: Alexander Popov <a13xp0p0v88@gmail.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/dma/mpc512x_dma.c | 55 |
1 files changed, 38 insertions, 17 deletions
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 0b17f4db1908..96104f4eebe8 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c | |||
@@ -657,13 +657,15 @@ static int mpc_dma_probe(struct platform_device *op) | |||
657 | mdma = devm_kzalloc(dev, sizeof(struct mpc_dma), GFP_KERNEL); | 657 | mdma = devm_kzalloc(dev, sizeof(struct mpc_dma), GFP_KERNEL); |
658 | if (!mdma) { | 658 | if (!mdma) { |
659 | dev_err(dev, "Memory exhausted!\n"); | 659 | dev_err(dev, "Memory exhausted!\n"); |
660 | return -ENOMEM; | 660 | retval = -ENOMEM; |
661 | goto err; | ||
661 | } | 662 | } |
662 | 663 | ||
663 | mdma->irq = irq_of_parse_and_map(dn, 0); | 664 | mdma->irq = irq_of_parse_and_map(dn, 0); |
664 | if (mdma->irq == NO_IRQ) { | 665 | if (mdma->irq == NO_IRQ) { |
665 | dev_err(dev, "Error mapping IRQ!\n"); | 666 | dev_err(dev, "Error mapping IRQ!\n"); |
666 | return -EINVAL; | 667 | retval = -EINVAL; |
668 | goto err; | ||
667 | } | 669 | } |
668 | 670 | ||
669 | if (of_device_is_compatible(dn, "fsl,mpc8308-dma")) { | 671 | if (of_device_is_compatible(dn, "fsl,mpc8308-dma")) { |
@@ -671,14 +673,15 @@ static int mpc_dma_probe(struct platform_device *op) | |||
671 | mdma->irq2 = irq_of_parse_and_map(dn, 1); | 673 | mdma->irq2 = irq_of_parse_and_map(dn, 1); |
672 | if (mdma->irq2 == NO_IRQ) { | 674 | if (mdma->irq2 == NO_IRQ) { |
673 | dev_err(dev, "Error mapping IRQ!\n"); | 675 | dev_err(dev, "Error mapping IRQ!\n"); |
674 | return -EINVAL; | 676 | retval = -EINVAL; |
677 | goto err_dispose1; | ||
675 | } | 678 | } |
676 | } | 679 | } |
677 | 680 | ||
678 | retval = of_address_to_resource(dn, 0, &res); | 681 | retval = of_address_to_resource(dn, 0, &res); |
679 | if (retval) { | 682 | if (retval) { |
680 | dev_err(dev, "Error parsing memory region!\n"); | 683 | dev_err(dev, "Error parsing memory region!\n"); |
681 | return retval; | 684 | goto err_dispose2; |
682 | } | 685 | } |
683 | 686 | ||
684 | regs_start = res.start; | 687 | regs_start = res.start; |
@@ -686,31 +689,34 @@ static int mpc_dma_probe(struct platform_device *op) | |||
686 | 689 | ||
687 | if (!devm_request_mem_region(dev, regs_start, regs_size, DRV_NAME)) { | 690 | if (!devm_request_mem_region(dev, regs_start, regs_size, DRV_NAME)) { |
688 | dev_err(dev, "Error requesting memory region!\n"); | 691 | dev_err(dev, "Error requesting memory region!\n"); |
689 | return -EBUSY; | 692 | retval = -EBUSY; |
693 | goto err_dispose2; | ||
690 | } | 694 | } |
691 | 695 | ||
692 | mdma->regs = devm_ioremap(dev, regs_start, regs_size); | 696 | mdma->regs = devm_ioremap(dev, regs_start, regs_size); |
693 | if (!mdma->regs) { | 697 | if (!mdma->regs) { |
694 | dev_err(dev, "Error mapping memory region!\n"); | 698 | dev_err(dev, "Error mapping memory region!\n"); |
695 | return -ENOMEM; | 699 | retval = -ENOMEM; |
700 | goto err_dispose2; | ||
696 | } | 701 | } |
697 | 702 | ||
698 | mdma->tcd = (struct mpc_dma_tcd *)((u8 *)(mdma->regs) | 703 | mdma->tcd = (struct mpc_dma_tcd *)((u8 *)(mdma->regs) |
699 | + MPC_DMA_TCD_OFFSET); | 704 | + MPC_DMA_TCD_OFFSET); |
700 | 705 | ||
701 | retval = devm_request_irq(dev, mdma->irq, &mpc_dma_irq, 0, DRV_NAME, | 706 | retval = request_irq(mdma->irq, &mpc_dma_irq, 0, DRV_NAME, mdma); |
702 | mdma); | ||
703 | if (retval) { | 707 | if (retval) { |
704 | dev_err(dev, "Error requesting IRQ!\n"); | 708 | dev_err(dev, "Error requesting IRQ!\n"); |
705 | return -EINVAL; | 709 | retval = -EINVAL; |
710 | goto err_dispose2; | ||
706 | } | 711 | } |
707 | 712 | ||
708 | if (mdma->is_mpc8308) { | 713 | if (mdma->is_mpc8308) { |
709 | retval = devm_request_irq(dev, mdma->irq2, &mpc_dma_irq, 0, | 714 | retval = request_irq(mdma->irq2, &mpc_dma_irq, 0, |
710 | DRV_NAME, mdma); | 715 | DRV_NAME, mdma); |
711 | if (retval) { | 716 | if (retval) { |
712 | dev_err(dev, "Error requesting IRQ2!\n"); | 717 | dev_err(dev, "Error requesting IRQ2!\n"); |
713 | return -EINVAL; | 718 | retval = -EINVAL; |
719 | goto err_free1; | ||
714 | } | 720 | } |
715 | } | 721 | } |
716 | 722 | ||
@@ -793,12 +799,23 @@ static int mpc_dma_probe(struct platform_device *op) | |||
793 | /* Register DMA engine */ | 799 | /* Register DMA engine */ |
794 | dev_set_drvdata(dev, mdma); | 800 | dev_set_drvdata(dev, mdma); |
795 | retval = dma_async_device_register(dma); | 801 | retval = dma_async_device_register(dma); |
796 | if (retval) { | 802 | if (retval) |
797 | devm_free_irq(dev, mdma->irq, mdma); | 803 | goto err_free2; |
798 | irq_dispose_mapping(mdma->irq); | ||
799 | } | ||
800 | 804 | ||
801 | return retval; | 805 | return retval; |
806 | |||
807 | err_free2: | ||
808 | if (mdma->is_mpc8308) | ||
809 | free_irq(mdma->irq2, mdma); | ||
810 | err_free1: | ||
811 | free_irq(mdma->irq, mdma); | ||
812 | err_dispose2: | ||
813 | if (mdma->is_mpc8308) | ||
814 | irq_dispose_mapping(mdma->irq2); | ||
815 | err_dispose1: | ||
816 | irq_dispose_mapping(mdma->irq); | ||
817 | err: | ||
818 | return retval; | ||
802 | } | 819 | } |
803 | 820 | ||
804 | static int mpc_dma_remove(struct platform_device *op) | 821 | static int mpc_dma_remove(struct platform_device *op) |
@@ -807,7 +824,11 @@ static int mpc_dma_remove(struct platform_device *op) | |||
807 | struct mpc_dma *mdma = dev_get_drvdata(dev); | 824 | struct mpc_dma *mdma = dev_get_drvdata(dev); |
808 | 825 | ||
809 | dma_async_device_unregister(&mdma->dma); | 826 | dma_async_device_unregister(&mdma->dma); |
810 | devm_free_irq(dev, mdma->irq, mdma); | 827 | if (mdma->is_mpc8308) { |
828 | free_irq(mdma->irq2, mdma); | ||
829 | irq_dispose_mapping(mdma->irq2); | ||
830 | } | ||
831 | free_irq(mdma->irq, mdma); | ||
811 | irq_dispose_mapping(mdma->irq); | 832 | irq_dispose_mapping(mdma->irq); |
812 | 833 | ||
813 | return 0; | 834 | return 0; |