From b1226dc59d55ecde7fc9a338d8cb2a313821fac0 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 24 May 2012 23:56:19 -0700 Subject: [PATCH] ASoC: fsi: use PIO handler if DMA handler was invalid 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 Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index fcaa6b8..53486ff 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; @@ -1173,7 +1173,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; @@ -1181,8 +1181,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); @@ -1672,7 +1683,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; @@ -1683,7 +1694,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; -- 2.7.4