Skip to content

Commit

Permalink
ASoC: fsi: use PIO handler if DMA handler was invalid
Browse files Browse the repository at this point in the history
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@renesas.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Kuninori Morimoto authored and Mark Brown committed Jun 3, 2012
1 parent 5514efd commit b1226dc
Showing 1 changed file with 20 additions and 9 deletions.
29 changes: 20 additions & 9 deletions sound/soc/sh/fsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1173,16 +1173,27 @@ 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;

dma_cap_zero(mask);
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);

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit b1226dc

Please sign in to comment.