[alsa-devel] [PATCH] ASoC: si476x: Fix locking of core

Andrey Smirnov andrew.smirnov at gmail.com
Sun Oct 20 20:22:58 CEST 2013


On Sun, Oct 20, 2013 at 10:15 AM, Mark Brown <broonie at kernel.org> wrote:
> From: Mark Brown <broonie at linaro.org>
>
> The conversion of the si476x to regmap removed locking of the core during
> register updates, allowing things like power state changes for the MFD to
> happen during a register update. Avoid this by taking the core lock in the
> DAI operations (which are the only things that do register updates) as we
> used to do in the open coded register I/O functions.
>
> Signed-off-by: Mark Brown <broonie at linaro.org>

Looks good to me, thanks for doing the work!

Acked-by: Andrey Smirnov <andrew.smirnov at gmail.com>




> ---
>  sound/soc/codecs/si476x.c | 18 +++++++++++++++---
>  1 file changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c
> index 03645ce..52e7cb0 100644
> --- a/sound/soc/codecs/si476x.c
> +++ b/sound/soc/codecs/si476x.c
> @@ -73,6 +73,7 @@ static const struct snd_soc_dapm_route si476x_dapm_routes[] = {
>  static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
>                                     unsigned int fmt)
>  {
> +       struct si476x_core *core = i2c_mfd_cell_to_core(codec_dai->dev);
>         int err;
>         u16 format = 0;
>
> @@ -136,9 +137,14 @@ static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
>                 return -EINVAL;
>         }
>
> +       si476x_core_lock(core);
> +
>         err = snd_soc_update_bits(codec_dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
>                                   SI476X_DIGITAL_IO_OUTPUT_FORMAT_MASK,
>                                   format);
> +
> +       si476x_core_unlock(core);
> +
>         if (err < 0) {
>                 dev_err(codec_dai->codec->dev, "Failed to set output format\n");
>                 return err;
> @@ -151,6 +157,7 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
>                                   struct snd_pcm_hw_params *params,
>                                   struct snd_soc_dai *dai)
>  {
> +       struct si476x_core *core = i2c_mfd_cell_to_core(dai->dev);
>         int rate, width, err;
>
>         rate = params_rate(params);
> @@ -176,11 +183,13 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
>                 return -EINVAL;
>         }
>
> +       si476x_core_lock(core);
> +
>         err = snd_soc_write(dai->codec, SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE,
>                             rate);
>         if (err < 0) {
>                 dev_err(dai->codec->dev, "Failed to set sample rate\n");
> -               return err;
> +               goto out;
>         }
>
>         err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
> @@ -189,10 +198,13 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
>                                   (width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT));
>         if (err < 0) {
>                 dev_err(dai->codec->dev, "Failed to set output width\n");
> -               return err;
> +               goto out;
>         }
>
> -       return 0;
> +out:
> +       si476x_core_unlock(core);
> +
> +       return err;
>  }
>
>  static int si476x_codec_probe(struct snd_soc_codec *codec)
> --
> 1.8.4.rc3
>


More information about the Alsa-devel mailing list