[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