aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/fsl/fsl_ssi.c61
1 files changed, 37 insertions, 24 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index d48afea5d93d..06ac2b92faf3 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -289,16 +289,6 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
289 */ 289 */
290 if (!ssi_private->playback && !ssi_private->capture) { 290 if (!ssi_private->playback && !ssi_private->capture) {
291 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 291 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
292 int ret;
293
294 /* The 'name' should not have any slashes in it. */
295 ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0,
296 ssi_private->name, ssi_private);
297 if (ret < 0) {
298 dev_err(substream->pcm->card->dev,
299 "could not claim irq %u\n", ssi_private->irq);
300 return ret;
301 }
302 292
303 /* 293 /*
304 * Section 16.5 of the MPC8610 reference manual says that the 294 * Section 16.5 of the MPC8610 reference manual says that the
@@ -522,15 +512,12 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
522 ssi_private->second_stream = NULL; 512 ssi_private->second_stream = NULL;
523 513
524 /* 514 /*
525 * If this is the last active substream, disable the SSI and release 515 * If this is the last active substream, disable the SSI.
526 * the IRQ.
527 */ 516 */
528 if (!ssi_private->playback && !ssi_private->capture) { 517 if (!ssi_private->playback && !ssi_private->capture) {
529 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 518 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
530 519
531 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 520 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
532
533 free_irq(ssi_private->irq, ssi_private);
534 } 521 }
535} 522}
536 523
@@ -675,17 +662,30 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
675 ret = of_address_to_resource(np, 0, &res); 662 ret = of_address_to_resource(np, 0, &res);
676 if (ret) { 663 if (ret) {
677 dev_err(&pdev->dev, "could not determine device resources\n"); 664 dev_err(&pdev->dev, "could not determine device resources\n");
678 kfree(ssi_private); 665 goto error_kmalloc;
679 return ret;
680 } 666 }
681 ssi_private->ssi = of_iomap(np, 0); 667 ssi_private->ssi = of_iomap(np, 0);
682 if (!ssi_private->ssi) { 668 if (!ssi_private->ssi) {
683 dev_err(&pdev->dev, "could not map device resources\n"); 669 dev_err(&pdev->dev, "could not map device resources\n");
684 kfree(ssi_private); 670 ret = -ENOMEM;
685 return -ENOMEM; 671 goto error_kmalloc;
686 } 672 }
687 ssi_private->ssi_phys = res.start; 673 ssi_private->ssi_phys = res.start;
674
688 ssi_private->irq = irq_of_parse_and_map(np, 0); 675 ssi_private->irq = irq_of_parse_and_map(np, 0);
676 if (ssi_private->irq == NO_IRQ) {
677 dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
678 ret = -ENXIO;
679 goto error_iomap;
680 }
681
682 /* The 'name' should not have any slashes in it. */
683 ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, ssi_private->name,
684 ssi_private);
685 if (ret < 0) {
686 dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq);
687 goto error_irqmap;
688 }
689 689
690 /* Are the RX and the TX clocks locked? */ 690 /* Are the RX and the TX clocks locked? */
691 if (of_find_property(np, "fsl,ssi-asynchronous", NULL)) 691 if (of_find_property(np, "fsl,ssi-asynchronous", NULL))
@@ -711,7 +711,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
711 if (ret) { 711 if (ret) {
712 dev_err(&pdev->dev, "could not create sysfs %s file\n", 712 dev_err(&pdev->dev, "could not create sysfs %s file\n",
713 ssi_private->dev_attr.attr.name); 713 ssi_private->dev_attr.attr.name);
714 goto error; 714 goto error_irq;
715 } 715 }
716 716
717 /* Register with ASoC */ 717 /* Register with ASoC */
@@ -720,7 +720,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
720 ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv); 720 ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv);
721 if (ret) { 721 if (ret) {
722 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); 722 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
723 goto error; 723 goto error_dev;
724 } 724 }
725 725
726 /* Trigger the machine driver's probe function. The platform driver 726 /* Trigger the machine driver's probe function. The platform driver
@@ -741,18 +741,28 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
741 if (IS_ERR(ssi_private->pdev)) { 741 if (IS_ERR(ssi_private->pdev)) {
742 ret = PTR_ERR(ssi_private->pdev); 742 ret = PTR_ERR(ssi_private->pdev);
743 dev_err(&pdev->dev, "failed to register platform: %d\n", ret); 743 dev_err(&pdev->dev, "failed to register platform: %d\n", ret);
744 goto error; 744 goto error_dai;
745 } 745 }
746 746
747 return 0; 747 return 0;
748 748
749error: 749error_dai:
750 snd_soc_unregister_dai(&pdev->dev); 750 snd_soc_unregister_dai(&pdev->dev);
751
752error_dev:
751 dev_set_drvdata(&pdev->dev, NULL); 753 dev_set_drvdata(&pdev->dev, NULL);
752 if (dev_attr) 754 device_remove_file(&pdev->dev, dev_attr);
753 device_remove_file(&pdev->dev, dev_attr); 755
756error_irq:
757 free_irq(ssi_private->irq, ssi_private);
758
759error_irqmap:
754 irq_dispose_mapping(ssi_private->irq); 760 irq_dispose_mapping(ssi_private->irq);
761
762error_iomap:
755 iounmap(ssi_private->ssi); 763 iounmap(ssi_private->ssi);
764
765error_kmalloc:
756 kfree(ssi_private); 766 kfree(ssi_private);
757 767
758 return ret; 768 return ret;
@@ -766,6 +776,9 @@ static int fsl_ssi_remove(struct platform_device *pdev)
766 snd_soc_unregister_dai(&pdev->dev); 776 snd_soc_unregister_dai(&pdev->dev);
767 device_remove_file(&pdev->dev, &ssi_private->dev_attr); 777 device_remove_file(&pdev->dev, &ssi_private->dev_attr);
768 778
779 free_irq(ssi_private->irq, ssi_private);
780 irq_dispose_mapping(ssi_private->irq);
781
769 kfree(ssi_private); 782 kfree(ssi_private);
770 dev_set_drvdata(&pdev->dev, NULL); 783 dev_set_drvdata(&pdev->dev, NULL);
771 784