ASoC: rsnd: add rsnd_dma_alloc()
R-Car sound DMA will be used from SSI/SRC. dma.c doesn't alloc DMA handler in .probe timing, because we don't know what kind of DMA transfer will be used then. Thus, SSI/SRC have *rsnd_mod for DMA. rsnd_dma_attach() will allocate it and attach it to system. It will be PIO mode if it can't alloc DMA handler. In case of MIX is used, rsnd_dma_attach() will be called twice from SSI. To avoid duplicate allocation, current rsnd_dma_attach() is checking allocated DMA handler. This DMA related operation is a little bit difficult to understand. This patch adds new rsnd_dma_alloc() and separates allocation and attach for readable code. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
b7165d26bf
commit
81cb71240e
|
@ -753,14 +753,15 @@ static void rsnd_dma_of_path(struct rsnd_mod *this,
|
|||
}
|
||||
}
|
||||
|
||||
int rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
|
||||
struct rsnd_mod **dma_mod)
|
||||
static int rsnd_dma_alloc(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
|
||||
struct rsnd_mod **dma_mod)
|
||||
{
|
||||
struct rsnd_mod *mod_from = NULL;
|
||||
struct rsnd_mod *mod_to = NULL;
|
||||
struct rsnd_priv *priv = rsnd_io_to_priv(io);
|
||||
struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
struct rsnd_dma *dma;
|
||||
struct rsnd_mod_ops *ops;
|
||||
enum rsnd_mod_type type;
|
||||
int (*attach)(struct rsnd_dai_stream *io, struct rsnd_dma *dma,
|
||||
|
@ -800,42 +801,47 @@ int rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
|
|||
type = RSND_MOD_AUDMA;
|
||||
}
|
||||
|
||||
if (!(*dma_mod)) {
|
||||
struct rsnd_dma *dma;
|
||||
dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
|
||||
if (!dma)
|
||||
return -ENOMEM;
|
||||
|
||||
dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
|
||||
if (!dma)
|
||||
return -ENOMEM;
|
||||
*dma_mod = rsnd_mod_get(dma);
|
||||
|
||||
*dma_mod = rsnd_mod_get(dma);
|
||||
|
||||
ret = rsnd_mod_init(priv, *dma_mod, ops, NULL,
|
||||
rsnd_mod_get_status, type, dma_id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev_dbg(dev, "%s[%d] %s[%d] -> %s[%d]\n",
|
||||
rsnd_mod_name(*dma_mod), rsnd_mod_id(*dma_mod),
|
||||
rsnd_mod_name(mod_from), rsnd_mod_id(mod_from),
|
||||
rsnd_mod_name(mod_to), rsnd_mod_id(mod_to));
|
||||
|
||||
ret = attach(io, dma, mod_from, mod_to);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1);
|
||||
dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0);
|
||||
dma->mod_from = mod_from;
|
||||
dma->mod_to = mod_to;
|
||||
}
|
||||
|
||||
ret = rsnd_dai_connect(*dma_mod, io, type);
|
||||
ret = rsnd_mod_init(priv, *dma_mod, ops, NULL,
|
||||
rsnd_mod_get_status, type, dma_id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev_dbg(dev, "%s[%d] %s[%d] -> %s[%d]\n",
|
||||
rsnd_mod_name(*dma_mod), rsnd_mod_id(*dma_mod),
|
||||
rsnd_mod_name(mod_from), rsnd_mod_id(mod_from),
|
||||
rsnd_mod_name(mod_to), rsnd_mod_id(mod_to));
|
||||
|
||||
ret = attach(io, dma, mod_from, mod_to);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1);
|
||||
dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0);
|
||||
dma->mod_from = mod_from;
|
||||
dma->mod_to = mod_to;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
|
||||
struct rsnd_mod **dma_mod)
|
||||
{
|
||||
if (!(*dma_mod)) {
|
||||
int ret = rsnd_dma_alloc(io, mod, dma_mod);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return rsnd_dai_connect(*dma_mod, io, (*dma_mod)->type);
|
||||
}
|
||||
|
||||
int rsnd_dma_probe(struct rsnd_priv *priv)
|
||||
{
|
||||
struct platform_device *pdev = rsnd_priv_to_pdev(priv);
|
||||
|
|
Loading…
Reference in New Issue