|
@@ -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;
|