diff options
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap/linus/0018-ASoC-codecs-max98088-Fix-register-cache-incoherency.patch')
-rw-r--r-- | extras/recipes-kernel/linux/linux-omap/linus/0018-ASoC-codecs-max98088-Fix-register-cache-incoherency.patch | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap/linus/0018-ASoC-codecs-max98088-Fix-register-cache-incoherency.patch b/extras/recipes-kernel/linux/linux-omap/linus/0018-ASoC-codecs-max98088-Fix-register-cache-incoherency.patch new file mode 100644 index 00000000..5c139ab5 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/linus/0018-ASoC-codecs-max98088-Fix-register-cache-incoherency.patch @@ -0,0 +1,72 @@ +From 0ff8217bd7272d8aef1e58250d84cf5680b16b2d Mon Sep 17 00:00:00 2001 +From: Lars-Peter Clausen <lars@metafoo.de> +Date: Tue, 28 Dec 2010 21:37:56 +0100 +Subject: [PATCH 18/65] ASoC: codecs: max98088: Fix register cache incoherency + +The multi-component patch(commit f0fba2ad1) moved the allocation of the +register cache from the driver to the ASoC core. Most drivers where adjusted to +this, but the max98088 driver still uses its own register cache for its +private functions, while functions from the ASoC core use the generic cache. +Thus we end up with two from each other incoherent caches, which can lead to +undefined behaviour. +This patch fixes the issue by changing the max98088 driver to use the +generic register cache in its private functions. + +Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> +Cc: Peter Hsiang <Peter.Hsiang@maxim-ic.com> +Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> +Cc: stable@kernel.org (for 2.6.37 only) +--- + sound/soc/codecs/max98088.c | 10 ++++------ + 1 files changed, 4 insertions(+), 6 deletions(-) + +diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c +index d63e287..6447dbb 100644 +--- a/sound/soc/codecs/max98088.c ++++ b/sound/soc/codecs/max98088.c +@@ -40,7 +40,6 @@ struct max98088_cdata { + }; + + struct max98088_priv { +- u8 reg_cache[M98088_REG_CNT]; + enum max98088_type devtype; + void *control_data; + struct max98088_pdata *pdata; +@@ -1588,7 +1587,7 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai, + + static void max98088_sync_cache(struct snd_soc_codec *codec) + { +- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); ++ u16 *reg_cache = codec->reg_cache; + int i; + + if (!codec->cache_sync) +@@ -1599,14 +1598,14 @@ static void max98088_sync_cache(struct snd_soc_codec *codec) + /* write back cached values if they're writeable and + * different from the hardware default. + */ +- for (i = 1; i < ARRAY_SIZE(max98088->reg_cache); i++) { ++ for (i = 1; i < codec->driver->reg_cache_size; i++) { + if (!max98088_access[i].writable) + continue; + +- if (max98088->reg_cache[i] == max98088_reg[i]) ++ if (reg_cache[i] == max98088_reg[i]) + continue; + +- snd_soc_write(codec, i, max98088->reg_cache[i]); ++ snd_soc_write(codec, i, reg_cache[i]); + } + + codec->cache_sync = 0; +@@ -1951,7 +1950,6 @@ static int max98088_probe(struct snd_soc_codec *codec) + int ret = 0; + + codec->cache_sync = 1; +- memcpy(codec->reg_cache, max98088_reg, sizeof(max98088_reg)); + + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); + if (ret != 0) { +-- +1.6.6.1 + |