Merge branch 'fix/pcm' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound...
authorMark Brown <broonie@kernel.org>
Wed, 27 Sep 2017 17:11:06 +0000 (10:11 -0700)
committerMark Brown <broonie@kernel.org>
Wed, 27 Sep 2017 17:11:06 +0000 (10:11 -0700)
1  2 
sound/soc/soc-pcm.c

diff --combined sound/soc/soc-pcm.c
index 23c251a6c5875cfd884b4f57b4e2afb1da0ed0cc,c0f0b09cb433543e32bb38b7d1a17552a2f49381..09fed7014ed84e8955256aa4a0241ce5d2919ef6
@@@ -474,7 -474,7 +474,7 @@@ static int soc_pcm_open(struct snd_pcm_
        mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
  
        /* startup the audio subsystem */
 -      if (cpu_dai->driver->ops && cpu_dai->driver->ops->startup) {
 +      if (cpu_dai->driver->ops->startup) {
                ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
                if (ret < 0) {
                        dev_err(cpu_dai->dev, "ASoC: can't open interface"
  
        for (i = 0; i < rtd->num_codecs; i++) {
                codec_dai = rtd->codec_dais[i];
 -              if (codec_dai->driver->ops && codec_dai->driver->ops->startup) {
 +              if (codec_dai->driver->ops->startup) {
                        ret = codec_dai->driver->ops->startup(substream,
                                                              codec_dai);
                        if (ret < 0) {
                        codec_dai->rx_mask = 0;
        }
  
 -      if (rtd->dai_link->ops && rtd->dai_link->ops->startup) {
 +      if (rtd->dai_link->ops->startup) {
                ret = rtd->dai_link->ops->startup(substream);
                if (ret < 0) {
                        pr_err("ASoC: %s startup failed: %d\n",
@@@ -585,7 -585,7 +585,7 @@@ dynamic
        return 0;
  
  config_err:
 -      if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
 +      if (rtd->dai_link->ops->shutdown)
                rtd->dai_link->ops->shutdown(substream);
  
  machine_err:
@@@ -692,7 -692,7 +692,7 @@@ static int soc_pcm_close(struct snd_pcm
                        codec_dai->driver->ops->shutdown(substream, codec_dai);
        }
  
 -      if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
 +      if (rtd->dai_link->ops->shutdown)
                rtd->dai_link->ops->shutdown(substream);
  
        if (platform->driver->ops && platform->driver->ops->close)
@@@ -751,7 -751,7 +751,7 @@@ static int soc_pcm_prepare(struct snd_p
  
        mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
  
 -      if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) {
 +      if (rtd->dai_link->ops->prepare) {
                ret = rtd->dai_link->ops->prepare(substream);
                if (ret < 0) {
                        dev_err(rtd->card->dev, "ASoC: machine prepare error:"
  
        for (i = 0; i < rtd->num_codecs; i++) {
                codec_dai = rtd->codec_dais[i];
 -              if (codec_dai->driver->ops && codec_dai->driver->ops->prepare) {
 +              if (codec_dai->driver->ops->prepare) {
                        ret = codec_dai->driver->ops->prepare(substream,
                                                              codec_dai);
                        if (ret < 0) {
                }
        }
  
 -      if (cpu_dai->driver->ops && cpu_dai->driver->ops->prepare) {
 +      if (cpu_dai->driver->ops->prepare) {
                ret = cpu_dai->driver->ops->prepare(substream, cpu_dai);
                if (ret < 0) {
                        dev_err(cpu_dai->dev,
@@@ -829,7 -829,7 +829,7 @@@ int soc_dai_hw_params(struct snd_pcm_su
  {
        int ret;
  
 -      if (dai->driver->ops && dai->driver->ops->hw_params) {
 +      if (dai->driver->ops->hw_params) {
                ret = dai->driver->ops->hw_params(substream, params, dai);
                if (ret < 0) {
                        dev_err(dai->dev, "ASoC: can't set %s hw params: %d\n",
@@@ -855,7 -855,12 +855,7 @@@ static int soc_pcm_hw_params(struct snd
        int i, ret = 0;
  
        mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
 -
 -      ret = soc_pcm_params_symmetry(substream, params);
 -      if (ret)
 -              goto out;
 -
 -      if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) {
 +      if (rtd->dai_link->ops->hw_params) {
                ret = rtd->dai_link->ops->hw_params(substream, params);
                if (ret < 0) {
                        dev_err(rtd->card->dev, "ASoC: machine hw_params"
        cpu_dai->sample_bits =
                snd_pcm_format_physical_width(params_format(params));
  
 +
 +      ret = soc_pcm_params_symmetry(substream, params);
 +        if (ret)
 +                goto platform_err;
  out:
        mutex_unlock(&rtd->pcm_mutex);
        return ret;
  
  platform_err:
 -      if (cpu_dai->driver->ops && cpu_dai->driver->ops->hw_free)
 +      if (cpu_dai->driver->ops->hw_free)
                cpu_dai->driver->ops->hw_free(substream, cpu_dai);
  
  interface_err:
  codec_err:
        while (--i >= 0) {
                struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
 -              if (codec_dai->driver->ops && codec_dai->driver->ops->hw_free)
 +              if (codec_dai->driver->ops->hw_free)
                        codec_dai->driver->ops->hw_free(substream, codec_dai);
                codec_dai->rate = 0;
        }
  
 -      if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
 +      if (rtd->dai_link->ops->hw_free)
                rtd->dai_link->ops->hw_free(substream);
  
        mutex_unlock(&rtd->pcm_mutex);
@@@ -994,7 -995,7 +994,7 @@@ static int soc_pcm_hw_free(struct snd_p
        }
  
        /* free any machine hw params */
 -      if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
 +      if (rtd->dai_link->ops->hw_free)
                rtd->dai_link->ops->hw_free(substream);
  
        /* free any DMA resources */
        /* now free hw params for the DAIs  */
        for (i = 0; i < rtd->num_codecs; i++) {
                codec_dai = rtd->codec_dais[i];
 -              if (codec_dai->driver->ops && codec_dai->driver->ops->hw_free)
 +              if (codec_dai->driver->ops->hw_free)
                        codec_dai->driver->ops->hw_free(substream, codec_dai);
        }
  
 -      if (cpu_dai->driver->ops && cpu_dai->driver->ops->hw_free)
 +      if (cpu_dai->driver->ops->hw_free)
                cpu_dai->driver->ops->hw_free(substream, cpu_dai);
  
        mutex_unlock(&rtd->pcm_mutex);
@@@ -1025,7 -1026,7 +1025,7 @@@ static int soc_pcm_trigger(struct snd_p
  
        for (i = 0; i < rtd->num_codecs; i++) {
                codec_dai = rtd->codec_dais[i];
 -              if (codec_dai->driver->ops && codec_dai->driver->ops->trigger) {
 +              if (codec_dai->driver->ops->trigger) {
                        ret = codec_dai->driver->ops->trigger(substream,
                                                              cmd, codec_dai);
                        if (ret < 0)
                        return ret;
        }
  
 -      if (cpu_dai->driver->ops && cpu_dai->driver->ops->trigger) {
 +      if (cpu_dai->driver->ops->trigger) {
                ret = cpu_dai->driver->ops->trigger(substream, cmd, cpu_dai);
                if (ret < 0)
                        return ret;
        }
  
 -      if (rtd->dai_link->ops && rtd->dai_link->ops->trigger) {
 +      if (rtd->dai_link->ops->trigger) {
                ret = rtd->dai_link->ops->trigger(substream, cmd);
                if (ret < 0)
                        return ret;
@@@ -1064,7 -1065,8 +1064,7 @@@ static int soc_pcm_bespoke_trigger(stru
  
        for (i = 0; i < rtd->num_codecs; i++) {
                codec_dai = rtd->codec_dais[i];
 -              if (codec_dai->driver->ops &&
 -                  codec_dai->driver->ops->bespoke_trigger) {
 +              if (codec_dai->driver->ops->bespoke_trigger) {
                        ret = codec_dai->driver->ops->bespoke_trigger(substream,
                                                                cmd, codec_dai);
                        if (ret < 0)
                }
        }
  
 -      if (cpu_dai->driver->ops && cpu_dai->driver->ops->bespoke_trigger) {
 +      if (cpu_dai->driver->ops->bespoke_trigger) {
                ret = cpu_dai->driver->ops->bespoke_trigger(substream, cmd, cpu_dai);
                if (ret < 0)
                        return ret;
@@@ -1099,12 -1101,12 +1099,12 @@@ static snd_pcm_uframes_t soc_pcm_pointe
        if (platform->driver->ops && platform->driver->ops->pointer)
                offset = platform->driver->ops->pointer(substream);
  
 -      if (cpu_dai->driver->ops && cpu_dai->driver->ops->delay)
 +      if (cpu_dai->driver->ops->delay)
                delay += cpu_dai->driver->ops->delay(substream, cpu_dai);
  
        for (i = 0; i < rtd->num_codecs; i++) {
                codec_dai = rtd->codec_dais[i];
 -              if (codec_dai->driver->ops && codec_dai->driver->ops->delay)
 +              if (codec_dai->driver->ops->delay)
                        codec_delay = max(codec_delay,
                                        codec_dai->driver->ops->delay(substream,
                                                                    codec_dai));
@@@ -2630,6 -2632,17 +2630,17 @@@ static int dpcm_fe_dai_close(struct snd
        return ret;
  }
  
+ static void soc_pcm_private_free(struct snd_pcm *pcm)
+ {
+       struct snd_soc_pcm_runtime *rtd = pcm->private_data;
+       struct snd_soc_platform *platform = rtd->platform;
+       /* need to sync the delayed work before releasing resources */
+       flush_delayed_work(&rtd->delayed_work);
+       if (platform->driver->pcm_free)
+               platform->driver->pcm_free(pcm);
+ }
  /* create a new pcm */
  int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
  {
                }
        }
  
-       pcm->private_free = platform->driver->pcm_free;
+       pcm->private_free = soc_pcm_private_free;
  out:
        dev_info(rtd->card->dev, "%s <-> %s mapping ok\n",
                 (rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name,