Commit 1fab6caf authored by Timur Tabi's avatar Timur Tabi Committed by Mark Brown

ASoC: claim the IRQ when the fsl_ssi device is probed, not opened

The PowerPC Freescale SSI driver is claiming the IRQ when the IRQ when
the device is opened, which means that the /proc/interrupts entry for
the SSI exists only during playback or capture.  This also meant that
the user won't know that the IRQ number is wrong until he tries to use
the device.  Instead, we should claim the IRQ when the device is probed.
Signed-off-by: default avatarTimur Tabi <timur@freescale.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent f049ffb3
...@@ -289,16 +289,6 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, ...@@ -289,16 +289,6 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
*/ */
if (!ssi_private->playback && !ssi_private->capture) { if (!ssi_private->playback && !ssi_private->capture) {
struct ccsr_ssi __iomem *ssi = ssi_private->ssi; struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
int ret;
/* The 'name' should not have any slashes in it. */
ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0,
ssi_private->name, ssi_private);
if (ret < 0) {
dev_err(substream->pcm->card->dev,
"could not claim irq %u\n", ssi_private->irq);
return ret;
}
/* /*
* Section 16.5 of the MPC8610 reference manual says that the * 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,15 +512,12 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
ssi_private->second_stream = NULL; ssi_private->second_stream = NULL;
/* /*
* If this is the last active substream, disable the SSI and release * If this is the last active substream, disable the SSI.
* the IRQ.
*/ */
if (!ssi_private->playback && !ssi_private->capture) { if (!ssi_private->playback && !ssi_private->capture) {
struct ccsr_ssi __iomem *ssi = ssi_private->ssi; struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
free_irq(ssi_private->irq, ssi_private);
} }
} }
...@@ -675,17 +662,30 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) ...@@ -675,17 +662,30 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
ret = of_address_to_resource(np, 0, &res); ret = of_address_to_resource(np, 0, &res);
if (ret) { if (ret) {
dev_err(&pdev->dev, "could not determine device resources\n"); dev_err(&pdev->dev, "could not determine device resources\n");
kfree(ssi_private); goto error_kmalloc;
return ret;
} }
ssi_private->ssi = of_iomap(np, 0); ssi_private->ssi = of_iomap(np, 0);
if (!ssi_private->ssi) { if (!ssi_private->ssi) {
dev_err(&pdev->dev, "could not map device resources\n"); dev_err(&pdev->dev, "could not map device resources\n");
kfree(ssi_private); ret = -ENOMEM;
return -ENOMEM; goto error_kmalloc;
} }
ssi_private->ssi_phys = res.start; ssi_private->ssi_phys = res.start;
ssi_private->irq = irq_of_parse_and_map(np, 0); ssi_private->irq = irq_of_parse_and_map(np, 0);
if (ssi_private->irq == NO_IRQ) {
dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
ret = -ENXIO;
goto error_iomap;
}
/* The 'name' should not have any slashes in it. */
ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, ssi_private->name,
ssi_private);
if (ret < 0) {
dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq);
goto error_irqmap;
}
/* Are the RX and the TX clocks locked? */ /* Are the RX and the TX clocks locked? */
if (of_find_property(np, "fsl,ssi-asynchronous", NULL)) if (of_find_property(np, "fsl,ssi-asynchronous", NULL))
...@@ -711,7 +711,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) ...@@ -711,7 +711,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
if (ret) { if (ret) {
dev_err(&pdev->dev, "could not create sysfs %s file\n", dev_err(&pdev->dev, "could not create sysfs %s file\n",
ssi_private->dev_attr.attr.name); ssi_private->dev_attr.attr.name);
goto error; goto error_irq;
} }
/* Register with ASoC */ /* Register with ASoC */
...@@ -720,7 +720,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) ...@@ -720,7 +720,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv); ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
goto error; goto error_dev;
} }
/* Trigger the machine driver's probe function. The platform driver /* 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,18 +741,28 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
if (IS_ERR(ssi_private->pdev)) { if (IS_ERR(ssi_private->pdev)) {
ret = PTR_ERR(ssi_private->pdev); ret = PTR_ERR(ssi_private->pdev);
dev_err(&pdev->dev, "failed to register platform: %d\n", ret); dev_err(&pdev->dev, "failed to register platform: %d\n", ret);
goto error; goto error_dai;
} }
return 0; return 0;
error: error_dai:
snd_soc_unregister_dai(&pdev->dev); snd_soc_unregister_dai(&pdev->dev);
error_dev:
dev_set_drvdata(&pdev->dev, NULL); dev_set_drvdata(&pdev->dev, NULL);
if (dev_attr)
device_remove_file(&pdev->dev, dev_attr); device_remove_file(&pdev->dev, dev_attr);
error_irq:
free_irq(ssi_private->irq, ssi_private);
error_irqmap:
irq_dispose_mapping(ssi_private->irq); irq_dispose_mapping(ssi_private->irq);
error_iomap:
iounmap(ssi_private->ssi); iounmap(ssi_private->ssi);
error_kmalloc:
kfree(ssi_private); kfree(ssi_private);
return ret; return ret;
...@@ -766,6 +776,9 @@ static int fsl_ssi_remove(struct platform_device *pdev) ...@@ -766,6 +776,9 @@ static int fsl_ssi_remove(struct platform_device *pdev)
snd_soc_unregister_dai(&pdev->dev); snd_soc_unregister_dai(&pdev->dev);
device_remove_file(&pdev->dev, &ssi_private->dev_attr); device_remove_file(&pdev->dev, &ssi_private->dev_attr);
free_irq(ssi_private->irq, ssi_private);
irq_dispose_mapping(ssi_private->irq);
kfree(ssi_private); kfree(ssi_private);
dev_set_drvdata(&pdev->dev, NULL); dev_set_drvdata(&pdev->dev, NULL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment