diff options
author | Dimitris Papastamos <dp@opensource.wolfsonmicro.com> | 2010-12-02 11:11:05 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-12-03 11:37:06 -0500 |
commit | 3335ddca9367675f4ee0bd50cc70402c4919a10d (patch) | |
tree | 4391baddac89dc25cd242e44168a0bbf3e1442bc /sound/soc/soc-core.c | |
parent | ff819b8357df0ca9903ff7c9ad518b949c410123 (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.c | 17 |
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, | |||
3500 | error_dais: | 3514 | error_dais: |
3501 | snd_soc_cache_exit(codec); | 3515 | snd_soc_cache_exit(codec); |
3502 | error_cache: | 3516 | error_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 | } |