| From 08111dfc9f889edfd792570969ec80b6aef9b225 Mon Sep 17 00:00:00 2001 |
| From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| Date: Wed, 20 Sep 2017 06:28:44 +0000 |
| Subject: [PATCH 0135/1795] 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> |
| (cherry picked from commit 81cb71240e202a8086bda0755d9d78bd3decd0aa) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> |
| --- |
| sound/soc/sh/rcar/dma.c | 60 ++++++++++++++++++++++------------------- |
| 1 file changed, 33 insertions(+), 27 deletions(-) |
| |
| diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c |
| index 041ec1080d52..17220c946ff0 100644 |
| --- a/sound/soc/sh/rcar/dma.c |
| +++ b/sound/soc/sh/rcar/dma.c |
| @@ -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,40 +801,45 @@ 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; |
| |
| - 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; |
| |
| - 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)); |
| + 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); |
| |
| - 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); |
| - if (ret < 0) |
| - return ret; |
| - |
| - return 0; |
| + return rsnd_dai_connect(*dma_mod, io, (*dma_mod)->type); |
| } |
| |
| int rsnd_dma_probe(struct rsnd_priv *priv) |
| -- |
| 2.19.0 |
| |