Commit 91432e97 authored by Ian Molton's avatar Ian Molton Committed by Mark Brown

ASoC: fixes to caching implementations

This patch takes fixes a number of bugs in the caching code used by
several ASoC codec drivers. Mostly off-by-one fixes.
Signed-off-by: default avatarIan Molton <ian@mnementh.co.uk>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 28796eaf
...@@ -123,7 +123,6 @@ static int ac97_soc_probe(struct platform_device *pdev) ...@@ -123,7 +123,6 @@ static int ac97_soc_probe(struct platform_device *pdev)
snd_soc_free_pcms(socdev); snd_soc_free_pcms(socdev);
err: err:
kfree(socdev->codec->reg_cache);
kfree(socdev->codec); kfree(socdev->codec);
socdev->codec = NULL; socdev->codec = NULL;
return ret; return ret;
...@@ -138,7 +137,6 @@ static int ac97_soc_remove(struct platform_device *pdev) ...@@ -138,7 +137,6 @@ static int ac97_soc_remove(struct platform_device *pdev)
return 0; return 0;
snd_soc_free_pcms(socdev); snd_soc_free_pcms(socdev);
kfree(socdev->codec->reg_cache);
kfree(socdev->codec); kfree(socdev->codec);
return 0; return 0;
......
...@@ -109,7 +109,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, ...@@ -109,7 +109,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
default: default:
reg = reg >> 1; reg = reg >> 1;
if (reg >= (ARRAY_SIZE(ad1980_reg))) if (reg >= ARRAY_SIZE(ad1980_reg))
return -EINVAL; return -EINVAL;
return cache[reg]; return cache[reg];
...@@ -123,7 +123,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, ...@@ -123,7 +123,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
soc_ac97_ops.write(codec->ac97, reg, val); soc_ac97_ops.write(codec->ac97, reg, val);
reg = reg >> 1; reg = reg >> 1;
if (reg < (ARRAY_SIZE(ad1980_reg))) if (reg < ARRAY_SIZE(ad1980_reg))
cache[reg] = val; cache[reg] = val;
return 0; return 0;
......
...@@ -125,6 +125,9 @@ static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec, ...@@ -125,6 +125,9 @@ static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec,
{ {
u8 *cache = codec->reg_cache; u8 *cache = codec->reg_cache;
if (reg >= TWL4030_CACHEREGNUM)
return -EIO;
return cache[reg]; return cache[reg];
} }
......
...@@ -200,7 +200,7 @@ static inline unsigned int wm8580_read_reg_cache(struct snd_soc_codec *codec, ...@@ -200,7 +200,7 @@ static inline unsigned int wm8580_read_reg_cache(struct snd_soc_codec *codec,
unsigned int reg) unsigned int reg)
{ {
u16 *cache = codec->reg_cache; u16 *cache = codec->reg_cache;
BUG_ON(reg > ARRAY_SIZE(wm8580_reg)); BUG_ON(reg >= ARRAY_SIZE(wm8580_reg));
return cache[reg]; return cache[reg];
} }
...@@ -223,7 +223,7 @@ static int wm8580_write(struct snd_soc_codec *codec, unsigned int reg, ...@@ -223,7 +223,7 @@ static int wm8580_write(struct snd_soc_codec *codec, unsigned int reg,
{ {
u8 data[2]; u8 data[2];
BUG_ON(reg > ARRAY_SIZE(wm8580_reg)); BUG_ON(reg >= ARRAY_SIZE(wm8580_reg));
/* Registers are 9 bits wide */ /* Registers are 9 bits wide */
value &= 0x1ff; value &= 0x1ff;
......
...@@ -47,7 +47,7 @@ static inline unsigned int wm8728_read_reg_cache(struct snd_soc_codec *codec, ...@@ -47,7 +47,7 @@ static inline unsigned int wm8728_read_reg_cache(struct snd_soc_codec *codec,
unsigned int reg) unsigned int reg)
{ {
u16 *cache = codec->reg_cache; u16 *cache = codec->reg_cache;
BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults)); BUG_ON(reg >= ARRAY_SIZE(wm8728_reg_defaults));
return cache[reg]; return cache[reg];
} }
...@@ -55,7 +55,7 @@ static inline void wm8728_write_reg_cache(struct snd_soc_codec *codec, ...@@ -55,7 +55,7 @@ static inline void wm8728_write_reg_cache(struct snd_soc_codec *codec,
u16 reg, unsigned int value) u16 reg, unsigned int value)
{ {
u16 *cache = codec->reg_cache; u16 *cache = codec->reg_cache;
BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults)); BUG_ON(reg >= ARRAY_SIZE(wm8728_reg_defaults));
cache[reg] = value; cache[reg] = value;
} }
......
...@@ -97,7 +97,7 @@ static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec, ...@@ -97,7 +97,7 @@ static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec,
unsigned int reg) unsigned int reg)
{ {
u16 *cache = codec->reg_cache; u16 *cache = codec->reg_cache;
if (reg < 1 || reg > (ARRAY_SIZE(wm8753_reg) + 1)) if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
return -1; return -1;
return cache[reg - 1]; return cache[reg - 1];
} }
...@@ -109,7 +109,7 @@ static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec, ...@@ -109,7 +109,7 @@ static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec,
unsigned int reg, unsigned int value) unsigned int reg, unsigned int value)
{ {
u16 *cache = codec->reg_cache; u16 *cache = codec->reg_cache;
if (reg < 1 || reg > 0x3f) if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
return; return;
cache[reg - 1] = value; cache[reg - 1] = value;
} }
......
...@@ -116,7 +116,7 @@ static inline unsigned int wm8990_read_reg_cache(struct snd_soc_codec *codec, ...@@ -116,7 +116,7 @@ static inline unsigned int wm8990_read_reg_cache(struct snd_soc_codec *codec,
unsigned int reg) unsigned int reg)
{ {
u16 *cache = codec->reg_cache; u16 *cache = codec->reg_cache;
BUG_ON(reg > (ARRAY_SIZE(wm8990_reg)) - 1); BUG_ON(reg >= ARRAY_SIZE(wm8990_reg));
return cache[reg]; return cache[reg];
} }
...@@ -129,7 +129,7 @@ static inline void wm8990_write_reg_cache(struct snd_soc_codec *codec, ...@@ -129,7 +129,7 @@ static inline void wm8990_write_reg_cache(struct snd_soc_codec *codec,
u16 *cache = codec->reg_cache; u16 *cache = codec->reg_cache;
/* Reset register and reserved registers are uncached */ /* Reset register and reserved registers are uncached */
if (reg == 0 || reg > ARRAY_SIZE(wm8990_reg) - 1) if (reg == 0 || reg >= ARRAY_SIZE(wm8990_reg))
return; return;
cache[reg] = value; cache[reg] = value;
......
...@@ -452,7 +452,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, ...@@ -452,7 +452,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
else { else {
reg = reg >> 1; reg = reg >> 1;
if (reg > (ARRAY_SIZE(wm9712_reg))) if (reg >= (ARRAY_SIZE(wm9712_reg)))
return -EIO; return -EIO;
return cache[reg]; return cache[reg];
...@@ -466,7 +466,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, ...@@ -466,7 +466,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
soc_ac97_ops.write(codec->ac97, reg, val); soc_ac97_ops.write(codec->ac97, reg, val);
reg = reg >> 1; reg = reg >> 1;
if (reg <= (ARRAY_SIZE(wm9712_reg))) if (reg < (ARRAY_SIZE(wm9712_reg)))
cache[reg] = val; cache[reg] = val;
return 0; return 0;
......
...@@ -620,7 +620,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, ...@@ -620,7 +620,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
else { else {
reg = reg >> 1; reg = reg >> 1;
if (reg > (ARRAY_SIZE(wm9713_reg))) if (reg >= (ARRAY_SIZE(wm9713_reg)))
return -EIO; return -EIO;
return cache[reg]; return cache[reg];
...@@ -634,7 +634,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, ...@@ -634,7 +634,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
if (reg < 0x7c) if (reg < 0x7c)
soc_ac97_ops.write(codec->ac97, reg, val); soc_ac97_ops.write(codec->ac97, reg, val);
reg = reg >> 1; reg = reg >> 1;
if (reg <= (ARRAY_SIZE(wm9713_reg))) if (reg < (ARRAY_SIZE(wm9713_reg)))
cache[reg] = val; cache[reg] = val;
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment