aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-core.c
diff options
context:
space:
mode:
authorDimitris Papastamos <dp@opensource.wolfsonmicro.com>2010-12-02 11:11:05 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-12-03 11:37:06 -0500
commit3335ddca9367675f4ee0bd50cc70402c4919a10d (patch)
tree4391baddac89dc25cd242e44168a0bbf3e1442bc /sound/soc/soc-core.c
parentff819b8357df0ca9903ff7c9ad518b949c410123 (diff)
ASoC: soc-cache: Use reg_def_copy instead of reg_cache_default
Make sure to use codec->reg_def_copy instead of codec_drv->reg_cache_default wherever necessary. This change is necessary because in the next patch we move the cache initialization code outside snd_soc_register_codec() and by that time any data marked as __devinitconst such as the original reg_cache_default array might have already been freed by the kernel. Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r--sound/soc/soc-core.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 4649db6163b..a95d111a653 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3434,6 +3434,7 @@ int snd_soc_register_codec(struct device *dev,
3434 struct snd_soc_codec_driver *codec_drv, 3434 struct snd_soc_codec_driver *codec_drv,
3435 struct snd_soc_dai_driver *dai_drv, int num_dai) 3435 struct snd_soc_dai_driver *dai_drv, int num_dai)
3436{ 3436{
3437 size_t reg_size;
3437 struct snd_soc_codec *codec; 3438 struct snd_soc_codec *codec;
3438 int ret, i; 3439 int ret, i;
3439 3440
@@ -3469,6 +3470,19 @@ int snd_soc_register_codec(struct device *dev,
3469 3470
3470 /* allocate CODEC register cache */ 3471 /* allocate CODEC register cache */
3471 if (codec_drv->reg_cache_size && codec_drv->reg_word_size) { 3472 if (codec_drv->reg_cache_size && codec_drv->reg_word_size) {
3473 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
3474 /* it is necessary to make a copy of the default register cache
3475 * because in the case of using a compression type that requires
3476 * the default register cache to be marked as __devinitconst the
3477 * kernel might have freed the array by the time we initialize
3478 * the cache.
3479 */
3480 codec->reg_def_copy = kmemdup(codec_drv->reg_cache_default,
3481 reg_size, GFP_KERNEL);
3482 if (!codec->reg_def_copy) {
3483 ret = -ENOMEM;
3484 goto error_cache;
3485 }
3472 ret = snd_soc_cache_init(codec); 3486 ret = snd_soc_cache_init(codec);
3473 if (ret < 0) { 3487 if (ret < 0) {
3474 dev_err(codec->dev, "Failed to set cache compression type: %d\n", 3488 dev_err(codec->dev, "Failed to set cache compression type: %d\n",
@@ -3500,6 +3514,8 @@ int snd_soc_register_codec(struct device *dev,
3500error_dais: 3514error_dais:
3501 snd_soc_cache_exit(codec); 3515 snd_soc_cache_exit(codec);
3502error_cache: 3516error_cache:
3517 kfree(codec->reg_def_copy);
3518 codec->reg_def_copy = NULL;
3503 kfree(codec->name); 3519 kfree(codec->name);
3504 kfree(codec); 3520 kfree(codec);
3505 return ret; 3521 return ret;
@@ -3534,6 +3550,7 @@ found:
3534 pr_debug("Unregistered codec '%s'\n", codec->name); 3550 pr_debug("Unregistered codec '%s'\n", codec->name);
3535 3551
3536 snd_soc_cache_exit(codec); 3552 snd_soc_cache_exit(codec);
3553 kfree(codec->reg_def_copy);
3537 kfree(codec->name); 3554 kfree(codec->name);
3538 kfree(codec); 3555 kfree(codec);
3539} 3556}