summaryrefslogtreecommitdiffstats
path: root/sound/soc/sh
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2017-09-20 06:28:44 +0000
committerMark Brown <broonie@kernel.org>2017-09-21 17:50:48 +0100
commit81cb71240e202a8086bda0755d9d78bd3decd0aa (patch)
tree9003cdead803748256eadac2060f727c25faf9a5 /sound/soc/sh
parentb7165d26bf730567ab081bb9383aff82cd43d9ea (diff)
downloadlinux-81cb71240e202a8086bda0755d9d78bd3decd0aa.tar.bz2
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>
Diffstat (limited to 'sound/soc/sh')
-rw-r--r--sound/soc/sh/rcar/dma.c60
1 files 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)