summaryrefslogtreecommitdiff
path: root/sound/soc/sh/rz-ssi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sh/rz-ssi.c')
-rw-r--r--sound/soc/sh/rz-ssi.c69
1 files changed, 46 insertions, 23 deletions
diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c
index 5d6bae33ae34..fe79eb90e1e5 100644
--- a/sound/soc/sh/rz-ssi.c
+++ b/sound/soc/sh/rz-ssi.c
@@ -109,6 +109,7 @@ struct rz_ssi_priv {
int irq_int;
int irq_tx;
int irq_rx;
+ int irq_rt;
spinlock_t lock;
@@ -565,6 +566,17 @@ static irqreturn_t rz_ssi_interrupt(int irq, void *data)
rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0);
}
+ if (irq == ssi->irq_rt) {
+ struct snd_pcm_substream *substream = strm->substream;
+
+ if (rz_ssi_stream_is_play(ssi, substream)) {
+ strm->transfer(ssi, &ssi->playback);
+ } else {
+ strm->transfer(ssi, &ssi->capture);
+ rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0);
+ }
+ }
+
return IRQ_HANDLED;
}
@@ -993,26 +1005,39 @@ static int rz_ssi_probe(struct platform_device *pdev)
if (!rz_ssi_is_dma_enabled(ssi)) {
/* Tx and Rx interrupts (pio only) */
ssi->irq_tx = platform_get_irq_byname(pdev, "dma_tx");
- if (ssi->irq_tx < 0)
- return ssi->irq_tx;
-
- ret = devm_request_irq(&pdev->dev, ssi->irq_tx,
- &rz_ssi_interrupt, 0,
- dev_name(&pdev->dev), ssi);
- if (ret < 0)
- return dev_err_probe(&pdev->dev, ret,
- "irq request error (dma_tx)\n");
-
ssi->irq_rx = platform_get_irq_byname(pdev, "dma_rx");
- if (ssi->irq_rx < 0)
- return ssi->irq_rx;
-
- ret = devm_request_irq(&pdev->dev, ssi->irq_rx,
- &rz_ssi_interrupt, 0,
- dev_name(&pdev->dev), ssi);
- if (ret < 0)
- return dev_err_probe(&pdev->dev, ret,
- "irq request error (dma_rx)\n");
+ if (ssi->irq_tx == -ENXIO && ssi->irq_rx == -ENXIO) {
+ ssi->irq_rt = platform_get_irq_byname(pdev, "dma_rt");
+ if (ssi->irq_rt < 0)
+ return ssi->irq_rt;
+
+ ret = devm_request_irq(&pdev->dev, ssi->irq_rt,
+ &rz_ssi_interrupt, 0,
+ dev_name(&pdev->dev), ssi);
+ if (ret < 0)
+ return dev_err_probe(&pdev->dev, ret,
+ "irq request error (dma_tx)\n");
+ } else {
+ if (ssi->irq_tx < 0)
+ return ssi->irq_tx;
+
+ if (ssi->irq_rx < 0)
+ return ssi->irq_rx;
+
+ ret = devm_request_irq(&pdev->dev, ssi->irq_tx,
+ &rz_ssi_interrupt, 0,
+ dev_name(&pdev->dev), ssi);
+ if (ret < 0)
+ return dev_err_probe(&pdev->dev, ret,
+ "irq request error (dma_tx)\n");
+
+ ret = devm_request_irq(&pdev->dev, ssi->irq_rx,
+ &rz_ssi_interrupt, 0,
+ dev_name(&pdev->dev), ssi);
+ if (ret < 0)
+ return dev_err_probe(&pdev->dev, ret,
+ "irq request error (dma_rx)\n");
+ }
}
ssi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
@@ -1050,7 +1075,7 @@ err_reset:
return ret;
}
-static int rz_ssi_remove(struct platform_device *pdev)
+static void rz_ssi_remove(struct platform_device *pdev)
{
struct rz_ssi_priv *ssi = dev_get_drvdata(&pdev->dev);
@@ -1059,8 +1084,6 @@ static int rz_ssi_remove(struct platform_device *pdev)
pm_runtime_put(ssi->dev);
pm_runtime_disable(ssi->dev);
reset_control_assert(ssi->rstc);
-
- return 0;
}
static const struct of_device_id rz_ssi_of_match[] = {
@@ -1075,7 +1098,7 @@ static struct platform_driver rz_ssi_driver = {
.of_match_table = rz_ssi_of_match,
},
.probe = rz_ssi_probe,
- .remove = rz_ssi_remove,
+ .remove_new = rz_ssi_remove,
};
module_platform_driver(rz_ssi_driver);