aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2014-11-10 16:41:45 -0500
committerMark Brown <broonie@kernel.org>2014-11-18 10:26:05 -0500
commit70f3af3ca15affaef3d026a5aa6e44c4627ea6c7 (patch)
tree214ed9e55bd37bc22922e44a31a28b71ac0d24f3
parent65c72efd1ea370f0311a5d89754996fff9fc0747 (diff)
ASoC: Properly handle AC'97 device lifetime management
The memory that a struct device is contained in must not be freed except from within the device's release callback. The ASoC code currently does not adhere to this rule for the AC'97 device. This patch fixes it by moving the freeing of the AC'97 to the release callback and splitting up the registration and unregistration of the device into separate steps for getting/putting the reference to the device and adding/removing it to the device hierarchy. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/soc-core.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 4c8f8a23a0e9..7084c6f1285a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -504,13 +504,10 @@ EXPORT_SYMBOL_GPL(snd_soc_get_pcm_runtime);
504static int soc_ac97_dev_unregister(struct snd_soc_codec *codec) 504static int soc_ac97_dev_unregister(struct snd_soc_codec *codec)
505{ 505{
506 if (codec->ac97->dev.bus) 506 if (codec->ac97->dev.bus)
507 device_unregister(&codec->ac97->dev); 507 device_del(&codec->ac97->dev);
508 return 0; 508 return 0;
509} 509}
510 510
511/* stop no dev release warning */
512static void soc_ac97_device_release(struct device *dev){}
513
514/* register ac97 codec to bus */ 511/* register ac97 codec to bus */
515static int soc_ac97_dev_register(struct snd_soc_codec *codec) 512static int soc_ac97_dev_register(struct snd_soc_codec *codec)
516{ 513{
@@ -518,12 +515,11 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
518 515
519 codec->ac97->dev.bus = &ac97_bus_type; 516 codec->ac97->dev.bus = &ac97_bus_type;
520 codec->ac97->dev.parent = codec->component.card->dev; 517 codec->ac97->dev.parent = codec->component.card->dev;
521 codec->ac97->dev.release = soc_ac97_device_release;
522 518
523 dev_set_name(&codec->ac97->dev, "%d-%d:%s", 519 dev_set_name(&codec->ac97->dev, "%d-%d:%s",
524 codec->component.card->snd_card->number, 0, 520 codec->component.card->snd_card->number, 0,
525 codec->component.name); 521 codec->component.name);
526 err = device_register(&codec->ac97->dev); 522 err = device_add(&codec->ac97->dev);
527 if (err < 0) { 523 if (err < 0) {
528 dev_err(codec->dev, "ASoC: Can't register ac97 bus\n"); 524 dev_err(codec->dev, "ASoC: Can't register ac97 bus\n");
529 codec->ac97->dev.bus = NULL; 525 codec->ac97->dev.bus = NULL;
@@ -1948,6 +1944,11 @@ static struct platform_driver soc_driver = {
1948 .remove = soc_remove, 1944 .remove = soc_remove,
1949}; 1945};
1950 1946
1947static void soc_ac97_device_release(struct device *dev)
1948{
1949 kfree(to_ac97_t(dev));
1950}
1951
1951/** 1952/**
1952 * snd_soc_new_ac97_codec - initailise AC97 device 1953 * snd_soc_new_ac97_codec - initailise AC97 device
1953 * @codec: audio codec 1954 * @codec: audio codec
@@ -1972,12 +1973,14 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
1972 1973
1973 codec->ac97->bus->ops = ops; 1974 codec->ac97->bus->ops = ops;
1974 codec->ac97->num = num; 1975 codec->ac97->num = num;
1976 codec->ac97->dev.release = soc_ac97_device_release;
1975 1977
1976 /* 1978 /*
1977 * Mark the AC97 device to be created by us. This way we ensure that the 1979 * Mark the AC97 device to be created by us. This way we ensure that the
1978 * device will be registered with the device subsystem later on. 1980 * device will be registered with the device subsystem later on.
1979 */ 1981 */
1980 codec->ac97_created = 1; 1982 codec->ac97_created = 1;
1983 device_initialize(&codec->ac97->dev);
1981 1984
1982 return 0; 1985 return 0;
1983} 1986}
@@ -2152,7 +2155,8 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec)
2152 soc_unregister_ac97_codec(codec); 2155 soc_unregister_ac97_codec(codec);
2153#endif 2156#endif
2154 kfree(codec->ac97->bus); 2157 kfree(codec->ac97->bus);
2155 kfree(codec->ac97); 2158 codec->ac97->bus = NULL;
2159 put_device(&codec->ac97->dev);
2156 codec->ac97 = NULL; 2160 codec->ac97 = NULL;
2157 codec->ac97_created = 0; 2161 codec->ac97_created = 0;
2158} 2162}