OSDN Git Service

ASoC: rsnd: add rsnd_dma_alloc()
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Wed, 20 Sep 2017 06:28:44 +0000 (06:28 +0000)
committerMark Brown <broonie@kernel.org>
Thu, 21 Sep 2017 16:50:48 +0000 (17:50 +0100)
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>
sound/soc/sh/rcar/dma.c

index 041ec10..17220c9 100644 (file)
@@ -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)