Merge branch 'for-5.5' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie...
authorMark Brown <broonie@kernel.org>
Wed, 25 Dec 2019 17:51:43 +0000 (17:51 +0000)
committerMark Brown <broonie@kernel.org>
Wed, 25 Dec 2019 17:51:43 +0000 (17:51 +0000)
sound/soc/codecs/wm8962.c
sound/soc/fsl/fsl_audmix.c
sound/soc/soc-core.c
sound/soc/soc-topology.c
sound/soc/sof/imx/imx8.c
sound/soc/sof/intel/hda-dai.c
sound/soc/sof/ipc.c
sound/soc/stm/stm32_spdifrx.c

index 3e5c69f..d9d59f4 100644 (file)
@@ -2788,7 +2788,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
 
        if (target % Fref == 0) {
                fll_div->theta = 0;
-               fll_div->lambda = 0;
+               fll_div->lambda = 1;
        } else {
                gcd_fll = gcd(target, fratio * Fref);
 
@@ -2858,7 +2858,7 @@ static int wm8962_set_fll(struct snd_soc_component *component, int fll_id, int s
                return -EINVAL;
        }
 
-       if (fll_div.theta || fll_div.lambda)
+       if (fll_div.theta)
                fll1 |= WM8962_FLL_FRAC;
 
        /* Stop the FLL while we reconfigure */
index a1db1bc..5faecbe 100644 (file)
@@ -505,15 +505,20 @@ static int fsl_audmix_probe(struct platform_device *pdev)
                                              ARRAY_SIZE(fsl_audmix_dai));
        if (ret) {
                dev_err(dev, "failed to register ASoC DAI\n");
-               return ret;
+               goto err_disable_pm;
        }
 
        priv->pdev = platform_device_register_data(dev, mdrv, 0, NULL, 0);
        if (IS_ERR(priv->pdev)) {
                ret = PTR_ERR(priv->pdev);
                dev_err(dev, "failed to register platform %s: %d\n", mdrv, ret);
+               goto err_disable_pm;
        }
 
+       return 0;
+
+err_disable_pm:
+       pm_runtime_disable(dev);
        return ret;
 }
 
@@ -521,6 +526,8 @@ static int fsl_audmix_remove(struct platform_device *pdev)
 {
        struct fsl_audmix *priv = dev_get_drvdata(&pdev->dev);
 
+       pm_runtime_disable(&pdev->dev);
+
        if (priv->pdev)
                platform_device_unregister(priv->pdev);
 
index 0bd2cb2..55b98e8 100644 (file)
@@ -448,6 +448,12 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
                goto free_rtd;
 
        rtd->dev = dev;
+       INIT_LIST_HEAD(&rtd->list);
+       INIT_LIST_HEAD(&rtd->component_list);
+       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients);
+       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients);
+       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients);
+       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients);
        dev_set_drvdata(dev, rtd);
        INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
 
@@ -463,12 +469,6 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
        /*
         * rtd remaining settings
         */
-       INIT_LIST_HEAD(&rtd->component_list);
-       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients);
-       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients);
-       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients);
-       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients);
-
        rtd->card = card;
        rtd->dai_link = dai_link;
        if (!rtd->dai_link->ops)
@@ -1768,6 +1768,8 @@ match:
 
                        /* convert non BE into BE */
                        dai_link->no_pcm = 1;
+                       dai_link->dpcm_playback = 1;
+                       dai_link->dpcm_capture = 1;
 
                        /* override any BE fixups */
                        dai_link->be_hw_params_fixup =
index 2b3c74a..69d6a52 100644 (file)
@@ -549,7 +549,6 @@ static void remove_link(struct snd_soc_component *comp,
                dobj->ops->link_unload(comp, dobj);
 
        list_del(&dobj->list);
-
        snd_soc_remove_pcm_runtime(comp->card,
                        snd_soc_get_pcm_runtime(comp->card, link));
 
index cfefcfd..aef6ca1 100644 (file)
@@ -209,7 +209,7 @@ static int imx8_probe(struct snd_sof_dev *sdev)
 
        priv->pd_dev = devm_kmalloc_array(&pdev->dev, priv->num_domains,
                                          sizeof(*priv->pd_dev), GFP_KERNEL);
-       if (!priv)
+       if (!priv->pd_dev)
                return -ENOMEM;
 
        priv->link = devm_kmalloc_array(&pdev->dev, priv->num_domains,
@@ -304,6 +304,9 @@ static int imx8_probe(struct snd_sof_dev *sdev)
        }
        sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;
 
+       /* set default mailbox offset for FW ready message */
+       sdev->dsp_box.offset = MBOX_OFFSET;
+
        return 0;
 
 exit_pdev_unregister:
index 638812a..313611d 100644 (file)
@@ -217,6 +217,8 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
                link_dev = hda_link_stream_assign(bus, substream);
                if (!link_dev)
                        return -EBUSY;
+
+               snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
        }
 
        stream_tag = hdac_stream(link_dev)->stream_tag;
@@ -229,8 +231,6 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
        if (ret < 0)
                return ret;
 
-       snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
-
        link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name);
        if (!link)
                return -EINVAL;
@@ -362,6 +362,13 @@ static int hda_link_hw_free(struct snd_pcm_substream *substream,
        bus = hstream->bus;
        rtd = snd_pcm_substream_chip(substream);
        link_dev = snd_soc_dai_get_dma_data(dai, substream);
+
+       if (!link_dev) {
+               dev_dbg(dai->dev,
+                       "%s: link_dev is not assigned\n", __func__);
+               return -EINVAL;
+       }
+
        hda_stream = hstream_to_sof_hda_stream(link_dev);
 
        /* free the link DMA channel in the FW */
index 6186c7f..b63fc52 100644 (file)
@@ -823,6 +823,9 @@ void snd_sof_ipc_free(struct snd_sof_dev *sdev)
 {
        struct snd_sof_ipc *ipc = sdev->ipc;
 
+       if (!ipc)
+               return;
+
        /* disable sending of ipc's */
        mutex_lock(&ipc->tx_mutex);
        ipc->disable_ipc_tx = true;
index 3fd28ee..3769d9c 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/of_platform.h>
-#include <linux/pinctrl/consumer.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
 
  * @slave_config: dma slave channel runtime config pointer
  * @phys_addr: SPDIFRX registers physical base address
  * @lock: synchronization enabling lock
+ * @irq_lock: prevent race condition with IRQ on stream state
  * @cs: channel status buffer
  * @ub: user data buffer
  * @irq: SPDIFRX interrupt line
@@ -240,6 +240,7 @@ struct stm32_spdifrx_data {
        struct dma_slave_config slave_config;
        dma_addr_t phys_addr;
        spinlock_t lock;  /* Sync enabling lock */
+       spinlock_t irq_lock; /* Prevent race condition on stream state */
        unsigned char cs[SPDIFRX_CS_BYTES_NB];
        unsigned char ub[SPDIFRX_UB_BYTES_NB];
        int irq;
@@ -320,6 +321,7 @@ static void stm32_spdifrx_dma_ctrl_stop(struct stm32_spdifrx_data *spdifrx)
 static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
 {
        int cr, cr_mask, imr, ret;
+       unsigned long flags;
 
        /* Enable IRQs */
        imr = SPDIFRX_IMR_IFEIE | SPDIFRX_IMR_SYNCDIE | SPDIFRX_IMR_PERRIE;
@@ -327,7 +329,7 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
        if (ret)
                return ret;
 
-       spin_lock(&spdifrx->lock);
+       spin_lock_irqsave(&spdifrx->lock, flags);
 
        spdifrx->refcount++;
 
@@ -362,7 +364,7 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
                                "Failed to start synchronization\n");
        }
 
-       spin_unlock(&spdifrx->lock);
+       spin_unlock_irqrestore(&spdifrx->lock, flags);
 
        return ret;
 }
@@ -370,11 +372,12 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
 static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx)
 {
        int cr, cr_mask, reg;
+       unsigned long flags;
 
-       spin_lock(&spdifrx->lock);
+       spin_lock_irqsave(&spdifrx->lock, flags);
 
        if (--spdifrx->refcount) {
-               spin_unlock(&spdifrx->lock);
+               spin_unlock_irqrestore(&spdifrx->lock, flags);
                return;
        }
 
@@ -393,7 +396,7 @@ static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx)
        regmap_read(spdifrx->regmap, STM32_SPDIFRX_DR, &reg);
        regmap_read(spdifrx->regmap, STM32_SPDIFRX_CSR, &reg);
 
-       spin_unlock(&spdifrx->lock);
+       spin_unlock_irqrestore(&spdifrx->lock, flags);
 }
 
 static int stm32_spdifrx_dma_ctrl_register(struct device *dev,
@@ -480,8 +483,6 @@ static int stm32_spdifrx_get_ctrl_data(struct stm32_spdifrx_data *spdifrx)
        memset(spdifrx->cs, 0, SPDIFRX_CS_BYTES_NB);
        memset(spdifrx->ub, 0, SPDIFRX_UB_BYTES_NB);
 
-       pinctrl_pm_select_default_state(&spdifrx->pdev->dev);
-
        ret = stm32_spdifrx_dma_ctrl_start(spdifrx);
        if (ret < 0)
                return ret;
@@ -513,7 +514,6 @@ static int stm32_spdifrx_get_ctrl_data(struct stm32_spdifrx_data *spdifrx)
 
 end:
        clk_disable_unprepare(spdifrx->kclk);
-       pinctrl_pm_select_sleep_state(&spdifrx->pdev->dev);
 
        return ret;
 }
@@ -665,7 +665,6 @@ static const struct regmap_config stm32_h7_spdifrx_regmap_conf = {
 static irqreturn_t stm32_spdifrx_isr(int irq, void *devid)
 {
        struct stm32_spdifrx_data *spdifrx = (struct stm32_spdifrx_data *)devid;
-       struct snd_pcm_substream *substream = spdifrx->substream;
        struct platform_device *pdev = spdifrx->pdev;
        unsigned int cr, mask, sr, imr;
        unsigned int flags, sync_state;
@@ -745,14 +744,19 @@ static irqreturn_t stm32_spdifrx_isr(int irq, void *devid)
                        return IRQ_HANDLED;
                }
 
-               if (substream)
-                       snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
+               spin_lock(&spdifrx->irq_lock);
+               if (spdifrx->substream)
+                       snd_pcm_stop(spdifrx->substream,
+                                    SNDRV_PCM_STATE_DISCONNECTED);
+               spin_unlock(&spdifrx->irq_lock);
 
                return IRQ_HANDLED;
        }
 
-       if (err_xrun && substream)
-               snd_pcm_stop_xrun(substream);
+       spin_lock(&spdifrx->irq_lock);
+       if (err_xrun && spdifrx->substream)
+               snd_pcm_stop_xrun(spdifrx->substream);
+       spin_unlock(&spdifrx->irq_lock);
 
        return IRQ_HANDLED;
 }
@@ -761,9 +765,12 @@ static int stm32_spdifrx_startup(struct snd_pcm_substream *substream,
                                 struct snd_soc_dai *cpu_dai)
 {
        struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);
+       unsigned long flags;
        int ret;
 
+       spin_lock_irqsave(&spdifrx->irq_lock, flags);
        spdifrx->substream = substream;
+       spin_unlock_irqrestore(&spdifrx->irq_lock, flags);
 
        ret = clk_prepare_enable(spdifrx->kclk);
        if (ret)
@@ -839,8 +846,12 @@ static void stm32_spdifrx_shutdown(struct snd_pcm_substream *substream,
                                   struct snd_soc_dai *cpu_dai)
 {
        struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);
+       unsigned long flags;
 
+       spin_lock_irqsave(&spdifrx->irq_lock, flags);
        spdifrx->substream = NULL;
+       spin_unlock_irqrestore(&spdifrx->irq_lock, flags);
+
        clk_disable_unprepare(spdifrx->kclk);
 }
 
@@ -944,6 +955,7 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
        spdifrx->pdev = pdev;
        init_completion(&spdifrx->cs_completion);
        spin_lock_init(&spdifrx->lock);
+       spin_lock_init(&spdifrx->irq_lock);
 
        platform_set_drvdata(pdev, spdifrx);