diff options
author | Timur Tabi <timur@freescale.com> | 2010-08-03 18:55:28 -0400 |
---|---|---|
committer | Liam Girdwood <lrg@slimlogic.co.uk> | 2010-08-12 09:00:17 -0400 |
commit | 87a0632b29410bab5c1783d7eb979c8d942d4209 (patch) | |
tree | 16762ec323b99ead5ab618b05ce99da234950800 /sound/soc/fsl/fsl_ssi.c | |
parent | 1a3c5a491af6756dbba6ee166a9dee72bb414ba8 (diff) |
asoc/multi-component: fsl: fix exit and error paths in DMA and SSI drivers
The error handling code in the OF probe function of the SSI driver is not
freeing all resources correctly.
Since the machine driver no longer calls the DMA driver to provide information
about the SSI, we don't need to keep a list of DMA objects any more. In
addition, the fsl_soc_dma_remove() function is incorrectly removing *all*
DMA objects when it should only remove one.
Signed-off-by: Timur Tabi <timur@freescale.com>
Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'sound/soc/fsl/fsl_ssi.c')
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 51b089f9751c..00e3e625b52a 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -619,7 +619,7 @@ static int __devinit fsl_ssi_probe(struct of_device *of_dev, | |||
619 | { | 619 | { |
620 | struct fsl_ssi_private *ssi_private; | 620 | struct fsl_ssi_private *ssi_private; |
621 | int ret = 0; | 621 | int ret = 0; |
622 | struct device_attribute *dev_attr; | 622 | struct device_attribute *dev_attr = NULL; |
623 | struct device_node *np = of_dev->dev.of_node; | 623 | struct device_node *np = of_dev->dev.of_node; |
624 | const char *p, *sprop; | 624 | const char *p, *sprop; |
625 | struct resource res; | 625 | struct resource res; |
@@ -681,18 +681,16 @@ static int __devinit fsl_ssi_probe(struct of_device *of_dev, | |||
681 | if (ret) { | 681 | if (ret) { |
682 | dev_err(&of_dev->dev, "could not create sysfs %s file\n", | 682 | dev_err(&of_dev->dev, "could not create sysfs %s file\n", |
683 | ssi_private->dev_attr.attr.name); | 683 | ssi_private->dev_attr.attr.name); |
684 | kfree(ssi_private); | 684 | goto error; |
685 | return ret; | ||
686 | } | 685 | } |
687 | 686 | ||
688 | /* Register with ASoC */ | 687 | /* Register with ASoC */ |
689 | dev_set_drvdata(&of_dev->dev, ssi_private); | 688 | dev_set_drvdata(&of_dev->dev, ssi_private); |
690 | 689 | ||
691 | ret = snd_soc_register_dai(&of_dev->dev, &ssi_private->cpu_dai_drv); | 690 | ret = snd_soc_register_dai(&of_dev->dev, &ssi_private->cpu_dai_drv); |
692 | if (ret != 0) { | 691 | if (ret) { |
693 | dev_err(&of_dev->dev, "failed to register DAI: %d\n", ret); | 692 | dev_err(&of_dev->dev, "failed to register DAI: %d\n", ret); |
694 | kfree(ssi_private); | 693 | goto error; |
695 | return ret; | ||
696 | } | 694 | } |
697 | 695 | ||
698 | /* Trigger the machine driver's probe function. The platform driver | 696 | /* Trigger the machine driver's probe function. The platform driver |
@@ -713,18 +711,23 @@ static int __devinit fsl_ssi_probe(struct of_device *of_dev, | |||
713 | if (IS_ERR(ssi_private->pdev)) { | 711 | if (IS_ERR(ssi_private->pdev)) { |
714 | ret = PTR_ERR(ssi_private->pdev); | 712 | ret = PTR_ERR(ssi_private->pdev); |
715 | dev_err(&of_dev->dev, "failed to register platform: %d\n", ret); | 713 | dev_err(&of_dev->dev, "failed to register platform: %d\n", ret); |
716 | kfree(ssi_private); | 714 | goto error; |
717 | return ret; | ||
718 | } | 715 | } |
719 | 716 | ||
720 | return 0; | 717 | return 0; |
718 | |||
719 | error: | ||
720 | snd_soc_unregister_dai(&of_dev->dev); | ||
721 | dev_set_drvdata(&of_dev->dev, NULL); | ||
722 | if (dev_attr) | ||
723 | device_remove_file(&of_dev->dev, dev_attr); | ||
724 | irq_dispose_mapping(ssi_private->irq); | ||
725 | iounmap(ssi_private->ssi); | ||
726 | kfree(ssi_private); | ||
727 | |||
728 | return ret; | ||
721 | } | 729 | } |
722 | 730 | ||
723 | /** | ||
724 | * fsl_ssi_destroy_dai: destroy the snd_soc_dai object | ||
725 | * | ||
726 | * This function undoes the operations of fsl_ssi_probe() | ||
727 | */ | ||
728 | static int fsl_ssi_remove(struct of_device *of_dev) | 731 | static int fsl_ssi_remove(struct of_device *of_dev) |
729 | { | 732 | { |
730 | struct fsl_ssi_private *ssi_private = dev_get_drvdata(&of_dev->dev); | 733 | struct fsl_ssi_private *ssi_private = dev_get_drvdata(&of_dev->dev); |