[alsa-devel] [PATCH] ASoC: fsi: use PIO handler if DMA handler was invalid

Kuninori Morimoto kuninori.morimoto.gx at renesas.com
Fri May 25 08:56:19 CEST 2012


PIO handler is not good performance, but works on all platform.
So, switch to PIO handler if DMA handler was invalid case.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
---
 sound/soc/sh/fsi.c |   29 ++++++++++++++++++++---------
 1 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 05582c1..0da021a 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -247,7 +247,7 @@ struct fsi_priv {
 struct fsi_stream_handler {
 	int (*init)(struct fsi_priv *fsi, struct fsi_stream *io);
 	int (*quit)(struct fsi_priv *fsi, struct fsi_stream *io);
-	int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io);
+	int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev);
 	int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io);
 	int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io);
 	void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io,
@@ -571,16 +571,16 @@ static int fsi_stream_transfer(struct fsi_stream *io)
 #define fsi_stream_stop(fsi, io)\
 	fsi_stream_handler_call(io, start_stop, fsi, io, 0)
 
-static int fsi_stream_probe(struct fsi_priv *fsi)
+static int fsi_stream_probe(struct fsi_priv *fsi, struct device *dev)
 {
 	struct fsi_stream *io;
 	int ret1, ret2;
 
 	io = &fsi->playback;
-	ret1 = fsi_stream_handler_call(io, probe, fsi, io);
+	ret1 = fsi_stream_handler_call(io, probe, fsi, io, dev);
 
 	io = &fsi->capture;
-	ret2 = fsi_stream_handler_call(io, probe, fsi, io);
+	ret2 = fsi_stream_handler_call(io, probe, fsi, io, dev);
 
 	if (ret1 < 0)
 		return ret1;
@@ -1182,7 +1182,7 @@ static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
 		fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
 }
 
-static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io)
+static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev)
 {
 	dma_cap_mask_t mask;
 
@@ -1190,8 +1190,19 @@ static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io)
 	dma_cap_set(DMA_SLAVE, mask);
 
 	io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave);
-	if (!io->chan)
-		return -EIO;
+	if (!io->chan) {
+
+		/* switch to PIO handler */
+		if (fsi_stream_is_play(fsi, io))
+			fsi->playback.handler	= &fsi_pio_push_handler;
+		else
+			fsi->capture.handler	= &fsi_pio_pop_handler;
+
+		dev_info(dev, "switch handler (dma => pio)\n");
+
+		/* probe again */
+		return fsi_stream_probe(fsi, dev);
+	}
 
 	tasklet_init(&io->tasklet, fsi_dma_do_tasklet, (unsigned long)io);
 
@@ -1681,7 +1692,7 @@ static int fsi_probe(struct platform_device *pdev)
 	master->fsia.master	= master;
 	master->fsia.info	= &info->port_a;
 	fsi_handler_init(&master->fsia);
-	ret = fsi_stream_probe(&master->fsia);
+	ret = fsi_stream_probe(&master->fsia, &pdev->dev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "FSIA stream probe failed\n");
 		goto exit_iounmap;
@@ -1692,7 +1703,7 @@ static int fsi_probe(struct platform_device *pdev)
 	master->fsib.master	= master;
 	master->fsib.info	= &info->port_b;
 	fsi_handler_init(&master->fsib);
-	ret = fsi_stream_probe(&master->fsib);
+	ret = fsi_stream_probe(&master->fsib, &pdev->dev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "FSIB stream probe failed\n");
 		goto exit_fsia;
-- 
1.7.5.4



More information about the Alsa-devel mailing list