From: Davide Bonfanti <davide.bonfa...@bticino.it>

    If soc_pcm_ops is statically allocated, more than one call to soc_new_pcm
    cause operations overwrite. The problem is overcome usyng dynamic
    allocation.

    Signed-off-by: Davide Bonfanti <davide.bonfa...@bticino.it>
    Signed-off-by: Raffaele Recalcati <raffaele.recalc...@bticino.it>
---
 sound/soc/soc-core.c |   38 +++++++++++++++++---------------------
 1 files changed, 17 insertions(+), 21 deletions(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index ad7f952..6500686 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -801,17 +801,6 @@ static int soc_pcm_trigger(struct snd_pcm_substream 
*substream, int cmd)
        }
        return 0;
 }
-
-/* ASoC PCM operations */
-static struct snd_pcm_ops soc_pcm_ops = {
-       .open           = soc_pcm_open,
-       .close          = soc_codec_close,
-       .hw_params      = soc_pcm_hw_params,
-       .hw_free        = soc_pcm_hw_free,
-       .prepare        = soc_pcm_prepare,
-       .trigger        = soc_pcm_trigger,
-};
-
 #ifdef CONFIG_PM
 /* powers down audio subsystem for suspend */
 static int soc_suspend(struct device *dev)
@@ -1306,6 +1295,7 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
        struct snd_pcm *pcm;
        char new_name[64];
        int ret = 0, playback = 0, capture = 0;
+       struct snd_pcm_ops *soc_pcm_ops;
 
        rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime), GFP_KERNEL);
        if (rtd == NULL)
@@ -1335,19 +1325,25 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
 
        dai_link->pcm = pcm;
        pcm->private_data = rtd;
-       soc_pcm_ops.mmap = platform->pcm_ops->mmap;
-       soc_pcm_ops.pointer = platform->pcm_ops->pointer;
-       soc_pcm_ops.ioctl = platform->pcm_ops->ioctl;
-       soc_pcm_ops.copy = platform->pcm_ops->copy;
-       soc_pcm_ops.silence = platform->pcm_ops->silence;
-       soc_pcm_ops.ack = platform->pcm_ops->ack;
-       soc_pcm_ops.page = platform->pcm_ops->page;
+       soc_pcm_ops = kmalloc(sizeof(struct snd_pcm_ops), GFP_KERNEL);
+       soc_pcm_ops->open               = soc_pcm_open;
+       soc_pcm_ops->close              = soc_codec_close;
+       soc_pcm_ops->hw_params  = soc_pcm_hw_params;
+       soc_pcm_ops->hw_free    = soc_pcm_hw_free;
+       soc_pcm_ops->prepare    = soc_pcm_prepare;
+       soc_pcm_ops->trigger    = soc_pcm_trigger;
+       soc_pcm_ops->mmap = platform->pcm_ops->mmap;
+       soc_pcm_ops->pointer = platform->pcm_ops->pointer;
+       soc_pcm_ops->ioctl = platform->pcm_ops->ioctl;
+       soc_pcm_ops->copy = platform->pcm_ops->copy;
+       soc_pcm_ops->silence = platform->pcm_ops->silence;
+       soc_pcm_ops->ack = platform->pcm_ops->ack;
+       soc_pcm_ops->page = platform->pcm_ops->page;
 
        if (playback)
-               snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops);
-
+               snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, soc_pcm_ops);
        if (capture)
-               snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops);
+               snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, soc_pcm_ops);
 
        ret = platform->pcm_new(codec->card, codec_dai, pcm);
        if (ret < 0) {
-- 
1.7.0.4

_______________________________________________
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to