Merge tag 'asoc-fix-v5.3-rc3' of https://git.kernel.org/pub/scm/linux/kernel/git...
authorTakashi Iwai <tiwai@suse.de>
Tue, 6 Aug 2019 10:28:08 +0000 (12:28 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 6 Aug 2019 10:28:08 +0000 (12:28 +0200)
ASoC: Fixes for v5.3

A relatively large batch of mostly unremarkable fixes here, a couple of
small core fixes for fairly obscure issues, more comment/email updates
with no code impact than usual and a bunch of small driver fixes.

The support for new sample rates in the max98373 driver is a fix for the
fact that the driver declared support for those rates but would in fact
return an error if these rates were selected.

1  2 
MAINTAINERS
sound/soc/generic/audio-graph-card.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/soc/ti/davinci-mcasp.c

diff --combined MAINTAINERS
index 0b9192c10d47bcefe8d1679ee26560a71f460d20,92829ca37459391a25195ca2acf750b9365e1549..f227f7e04fbda11555beca24a9c3b0bddee4cef9
@@@ -3122,7 -3122,6 +3122,7 @@@ F:      arch/arm/mach-bcm
  BROADCOM BCM2835 ARM ARCHITECTURE
  M:    Eric Anholt <eric@anholt.net>
  M:    Stefan Wahren <wahrenst@gmx.net>
 +L:    bcm-kernel-feedback-list@broadcom.com
  L:    linux-rpi-kernel@lists.infradead.org (moderated for non-subscribers)
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  T:    git git://github.com/anholt/linux
@@@ -3152,7 -3151,6 +3152,7 @@@ F:      arch/arm/boot/dts/bcm953012
  
  BROADCOM BCM53573 ARM ARCHITECTURE
  M:    Rafał Miłecki <rafal@milecki.pl>
 +L:    bcm-kernel-feedback-list@broadcom.com
  L:    linux-arm-kernel@lists.infradead.org
  S:    Maintained
  F:    arch/arm/boot/dts/bcm53573*
@@@ -3947,14 -3945,6 +3947,14 @@@ M:    Miguel Ojeda <miguel.ojeda.sandonis@
  S:    Maintained
  F:    .clang-format
  
 +CLANG/LLVM BUILD SUPPORT
 +L:    clang-built-linux@googlegroups.com
 +W:    https://clangbuiltlinux.github.io/
 +B:    https://github.com/ClangBuiltLinux/linux/issues
 +C:    irc://chat.freenode.net/clangbuiltlinux
 +S:    Supported
 +K:    \b(?i:clang|llvm)\b
 +
  CLEANCACHE API
  M:    Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
  L:    linux-kernel@vger.kernel.org
@@@ -7871,6 -7861,7 +7871,7 @@@ S:      Maintaine
  F:    drivers/video/fbdev/i810/
  
  INTEL ASoC DRIVERS
+ M:    Cezary Rojewski <cezary.rojewski@intel.com>
  M:    Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
  M:    Liam Girdwood <liam.r.girdwood@linux.intel.com>
  M:    Jie Yang <yang.jie@linux.intel.com>
@@@ -15805,7 -15796,7 +15806,7 @@@ S:   Maintaine
  F:    drivers/net/ethernet/ti/netcp*
  
  TI PCM3060 ASoC CODEC DRIVER
- M:    Kirill Marinushkin <kmarinushkin@birdec.tech>
+ M:    Kirill Marinushkin <kmarinushkin@birdec.com>
  L:    alsa-devel@alsa-project.org (moderated for non-subscribers)
  S:    Maintained
  F:    Documentation/devicetree/bindings/sound/pcm3060.txt
index 30a4e8399ec38eef1de4ac8e26118c59f77894d9,ebf2ca3249cb9197bfe0d21e16361430cc6f4c80..288df245b2f07e16d42329a8da6cdb50b0a8fcd5
@@@ -63,6 -63,7 +63,7 @@@ static int graph_get_dai_id(struct devi
        struct device_node *endpoint;
        struct of_endpoint info;
        int i, id;
+       const u32 *reg;
        int ret;
  
        /* use driver specified DAI ID if exist */
@@@ -83,8 -84,9 +84,9 @@@
                        return info.id;
  
                node = of_get_parent(ep);
+               reg = of_get_property(node, "reg", NULL);
                of_node_put(node);
-               if (of_get_property(node, "reg", NULL))
+               if (reg)
                        return info.port;
        }
        node = of_graph_get_port_parent(ep);
@@@ -208,10 -210,6 +210,6 @@@ static int graph_dai_link_of_dpcm(struc
  
        dev_dbg(dev, "link_of DPCM (%pOF)\n", ep);
  
-       of_node_put(ports);
-       of_node_put(port);
-       of_node_put(node);
        if (li->cpu) {
                int is_single_links = 0;
  
  
                ret = asoc_simple_parse_cpu(ep, dai_link, &is_single_links);
                if (ret)
-                       return ret;
+                       goto out_put_node;
  
                ret = asoc_simple_parse_clk_cpu(dev, ep, dai_link, dai);
                if (ret < 0)
-                       return ret;
+                       goto out_put_node;
  
                ret = asoc_simple_set_dailink_name(dev, dai_link,
                                                   "fe.%s",
                                                   cpus->dai_name);
                if (ret < 0)
-                       return ret;
+                       goto out_put_node;
  
                /* card->num_links includes Codec */
                asoc_simple_canonicalize_cpu(dai_link, is_single_links);
  
                ret = asoc_simple_parse_codec(ep, dai_link);
                if (ret < 0)
-                       return ret;
+                       goto out_put_node;
  
                ret = asoc_simple_parse_clk_codec(dev, ep, dai_link, dai);
                if (ret < 0)
-                       return ret;
+                       goto out_put_node;
  
                ret = asoc_simple_set_dailink_name(dev, dai_link,
                                                   "be.%s",
                                                   codecs->dai_name);
                if (ret < 0)
-                       return ret;
+                       goto out_put_node;
  
                /* check "prefix" from top node */
                snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node,
  
        ret = asoc_simple_parse_tdm(ep, dai);
        if (ret)
-               return ret;
+               goto out_put_node;
  
        ret = asoc_simple_parse_daifmt(dev, cpu_ep, codec_ep,
                                       NULL, &dai_link->dai_fmt);
        if (ret < 0)
-               return ret;
+               goto out_put_node;
  
        dai_link->dpcm_playback         = 1;
        dai_link->dpcm_capture          = 1;
        dai_link->ops                   = &graph_ops;
        dai_link->init                  = asoc_simple_dai_init;
  
-       return 0;
+ out_put_node:
+       of_node_put(ports);
+       of_node_put(port);
+       of_node_put(node);
+       return ret;
  }
  
  static int graph_dai_link_of(struct asoc_simple_priv *priv,
@@@ -421,6 -423,9 +423,6 @@@ static int graph_for_each_link(struct a
                        codec_ep = of_graph_get_remote_endpoint(cpu_ep);
                        codec_port = of_get_parent(codec_ep);
  
 -                      of_node_put(codec_ep);
 -                      of_node_put(codec_port);
 -
                        /* get convert-xxx property */
                        memset(&adata, 0, sizeof(adata));
                        graph_parse_convert(dev, codec_ep, &adata);
                        else
                                ret = func_noml(priv, cpu_ep, codec_ep, li);
  
 +                      of_node_put(codec_ep);
 +                      of_node_put(codec_port);
 +
                        if (ret < 0)
                                return ret;
  
diff --combined sound/soc/soc-core.c
index fd6eaae6c0ed37e38da9fd8a66c5a621047cc20d,1486fb2eb9212f622698f69ddc8f9272fa0e2031..44f899b970c2a399bb3cf9b97ce4a93d9264f140
@@@ -165,10 -165,9 +165,10 @@@ static void soc_init_component_debugfs(
                                component->card->debugfs_card_root);
        }
  
 -      if (!component->debugfs_root) {
 +      if (IS_ERR(component->debugfs_root)) {
                dev_warn(component->dev,
 -                      "ASoC: Failed to create component debugfs directory\n");
 +                      "ASoC: Failed to create component debugfs directory: %ld\n",
 +                      PTR_ERR(component->debugfs_root));
                return;
        }
  
@@@ -220,21 -219,18 +220,21 @@@ static void soc_init_card_debugfs(struc
  
        card->debugfs_card_root = debugfs_create_dir(card->name,
                                                     snd_soc_debugfs_root);
 -      if (!card->debugfs_card_root) {
 +      if (IS_ERR(card->debugfs_card_root)) {
                dev_warn(card->dev,
 -                       "ASoC: Failed to create card debugfs directory\n");
 +                       "ASoC: Failed to create card debugfs directory: %ld\n",
 +                       PTR_ERR(card->debugfs_card_root));
 +              card->debugfs_card_root = NULL;
                return;
        }
  
        card->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644,
                                                    card->debugfs_card_root,
                                                    &card->pop_time);
 -      if (!card->debugfs_pop_time)
 +      if (IS_ERR(card->debugfs_pop_time))
                dev_warn(card->dev,
 -                       "ASoC: Failed to create pop time debugfs file\n");
 +                       "ASoC: Failed to create pop time debugfs file: %ld\n",
 +                       PTR_ERR(card->debugfs_pop_time));
  }
  
  static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
@@@ -1515,8 -1511,11 +1515,11 @@@ static int soc_probe_link_dais(struct s
                }
        }
  
-       if (dai_link->dai_fmt)
-               snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt);
+       if (dai_link->dai_fmt) {
+               ret = snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt);
+               if (ret)
+                       return ret;
+       }
  
        ret = soc_post_component_init(rtd, dai_link->name);
        if (ret)
@@@ -2749,12 -2748,14 +2752,12 @@@ static void snd_soc_unbind_card(struct 
                snd_soc_dapm_shutdown(card);
                snd_soc_flush_all_delayed_work(card);
  
 -              mutex_lock(&client_mutex);
                /* remove all components used by DAI links on this card */
                for_each_comp_order(order) {
                        for_each_card_rtds(card, rtd) {
                                soc_remove_link_components(card, rtd, order);
                        }
                }
 -              mutex_unlock(&client_mutex);
  
                soc_cleanup_card_resources(card);
                if (!unregister)
   */
  int snd_soc_unregister_card(struct snd_soc_card *card)
  {
 +      mutex_lock(&client_mutex);
        snd_soc_unbind_card(card, true);
 +      mutex_unlock(&client_mutex);
        dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name);
  
        return 0;
diff --combined sound/soc/soc-dapm.c
index f013b24c050a17376ff7fe8237624adef1c5406e,656cb5cd9cd8ab70d37acf85a98c21bb83f44b8e..2790c00735f3abaa4582fd95854b7134780ae869
@@@ -1157,8 -1157,8 +1157,8 @@@ static __always_inline int is_connected
                list_add_tail(&widget->work_list, list);
  
        if (custom_stop_condition && custom_stop_condition(widget, dir)) {
-               widget->endpoints[dir] = 1;
-               return widget->endpoints[dir];
+               list = NULL;
+               custom_stop_condition = NULL;
        }
  
        if ((widget->is_ep & SND_SOC_DAPM_DIR_TO_EP(dir)) && widget->connected) {
   *
   * Optionally, can be supplied with a function acting as a stopping condition.
   * This function takes the dapm widget currently being examined and the walk
-  * direction as an arguments, it should return true if the walk should be
-  * stopped and false otherwise.
+  * direction as an arguments, it should return true if widgets from that point
+  * in the graph onwards should not be added to the widget list.
   */
  static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
        struct list_head *list,
@@@ -2156,25 -2156,23 +2156,25 @@@ void snd_soc_dapm_debugfs_init(struct s
  {
        struct dentry *d;
  
 -      if (!parent)
 +      if (!parent || IS_ERR(parent))
                return;
  
        dapm->debugfs_dapm = debugfs_create_dir("dapm", parent);
  
 -      if (!dapm->debugfs_dapm) {
 +      if (IS_ERR(dapm->debugfs_dapm)) {
                dev_warn(dapm->dev,
 -                     "ASoC: Failed to create DAPM debugfs directory\n");
 +                       "ASoC: Failed to create DAPM debugfs directory %ld\n",
 +                       PTR_ERR(dapm->debugfs_dapm));
                return;
        }
  
        d = debugfs_create_file("bias_level", 0444,
                                dapm->debugfs_dapm, dapm,
                                &dapm_bias_fops);
 -      if (!d)
 +      if (IS_ERR(d))
                dev_warn(dapm->dev,
 -                       "ASoC: Failed to create bias level debugfs file\n");
 +                       "ASoC: Failed to create bias level debugfs file: %ld\n",
 +                       PTR_ERR(d));
  }
  
  static void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
        d = debugfs_create_file(w->name, 0444,
                                dapm->debugfs_dapm, w,
                                &dapm_widget_power_fops);
 -      if (!d)
 +      if (IS_ERR(d))
                dev_warn(w->dapm->dev,
 -                      "ASoC: Failed to create %s debugfs file\n",
 -                      w->name);
 +                       "ASoC: Failed to create %s debugfs file: %ld\n",
 +                       w->name, PTR_ERR(d));
  }
  
  static void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
@@@ -3706,6 -3704,8 +3706,8 @@@ request_failed
                dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n",
                        w->name, ret);
  
+       kfree_const(w->sname);
+       kfree(w);
        return ERR_PTR(ret);
  }
  
index ac59b509ead51de648b09cf8819131e1d13be9d2,44708c8f90d6f3f5873764d1ad0af6208348cac7..bc7bf15ed7a44544b875dc35a4ce4ca73b406c03
@@@ -195,7 -195,7 +195,7 @@@ static inline void mcasp_set_axr_pdir(s
  {
        u32 bit;
  
-       for_each_set_bit(bit, &mcasp->pdir, PIN_BIT_AFSR) {
+       for_each_set_bit(bit, &mcasp->pdir, PIN_BIT_AMUTE) {
                if (enable)
                        mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit));
                else
@@@ -223,6 -223,7 +223,7 @@@ static void mcasp_start_rx(struct davin
        if (mcasp_is_synchronous(mcasp)) {
                mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST);
                mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST);
+               mcasp_set_clk_pdir(mcasp, true);
        }
  
        /* Activate serializer(s) */
@@@ -1256,6 -1257,28 +1257,28 @@@ static int davinci_mcasp_trigger(struc
        return ret;
  }
  
+ static int davinci_mcasp_hw_rule_slot_width(struct snd_pcm_hw_params *params,
+                                           struct snd_pcm_hw_rule *rule)
+ {
+       struct davinci_mcasp_ruledata *rd = rule->private;
+       struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+       struct snd_mask nfmt;
+       int i, slot_width;
+       snd_mask_none(&nfmt);
+       slot_width = rd->mcasp->slot_width;
+       for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
+               if (snd_mask_test(fmt, i)) {
+                       if (snd_pcm_format_width(i) <= slot_width) {
+                               snd_mask_set(&nfmt, i);
+                       }
+               }
+       }
+       return snd_mask_refine(fmt, &nfmt);
+ }
  static const unsigned int davinci_mcasp_dai_rates[] = {
        8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000,
        88200, 96000, 176400, 192000,
@@@ -1377,7 -1400,7 +1400,7 @@@ static int davinci_mcasp_startup(struc
        struct davinci_mcasp_ruledata *ruledata =
                                        &mcasp->ruledata[substream->stream];
        u32 max_channels = 0;
-       int i, dir;
+       int i, dir, ret;
        int tdm_slots = mcasp->tdm_slots;
  
        /* Do not allow more then one stream per direction */
                        max_channels++;
        }
        ruledata->serializers = max_channels;
+       ruledata->mcasp = mcasp;
        max_channels *= tdm_slots;
        /*
         * If the already active stream has less channels than the calculated
                                   0, SNDRV_PCM_HW_PARAM_CHANNELS,
                                   &mcasp->chconstr[substream->stream]);
  
-       if (mcasp->slot_width)
-               snd_pcm_hw_constraint_minmax(substream->runtime,
-                                            SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
-                                            8, mcasp->slot_width);
+       if (mcasp->slot_width) {
+               /* Only allow formats require <= slot_width bits on the bus */
+               ret = snd_pcm_hw_rule_add(substream->runtime, 0,
+                                         SNDRV_PCM_HW_PARAM_FORMAT,
+                                         davinci_mcasp_hw_rule_slot_width,
+                                         ruledata,
+                                         SNDRV_PCM_HW_PARAM_FORMAT, -1);
+               if (ret)
+                       return ret;
+       }
  
        /*
         * If we rely on implicit BCLK divider setting we should
         * set constraints based on what we can provide.
         */
        if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) {
-               int ret;
-               ruledata->mcasp = mcasp;
                ret = snd_pcm_hw_rule_add(substream->runtime, 0,
                                          SNDRV_PCM_HW_PARAM_RATE,
                                          davinci_mcasp_hw_rule_rate,
@@@ -2271,7 -2297,7 +2297,7 @@@ static int davinci_mcasp_probe(struct p
                ret = edma_pcm_platform_register(&pdev->dev);
                break;
        case PCM_SDMA:
 -              ret = sdma_pcm_platform_register(&pdev->dev, NULL, NULL);
 +              ret = sdma_pcm_platform_register(&pdev->dev, "tx", "rx");
                break;
        default:
                dev_err(&pdev->dev, "No DMA controller found (%d)\n", ret);