mirror of https://gitee.com/openkylin/linux.git
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 <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
parent
5514efdfe0
commit
b1226dc59d
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue