aboutsummaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap/linus/0018-ASoC-codecs-max98088-Fix-register-cache-incoherency.patch
diff options
context:
space:
mode:
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.patch72
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
+