aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl/fsl_ssi.c
diff options
context:
space:
mode:
authorTimur Tabi <timur@freescale.com>2010-08-03 18:55:28 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2010-08-12 09:00:17 -0400
commit87a0632b29410bab5c1783d7eb979c8d942d4209 (patch)
tree16762ec323b99ead5ab618b05ce99da234950800 /sound/soc/fsl/fsl_ssi.c
parent1a3c5a491af6756dbba6ee166a9dee72bb414ba8 (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.c29
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
719error:
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 */
728static int fsl_ssi_remove(struct of_device *of_dev) 731static 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);