diff options
| author | Axel Lin <axel.lin@gmail.com> | 2010-07-23 01:53:53 -0400 |
|---|---|---|
| committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-08-03 02:46:27 -0400 |
| commit | d484366beeab0cded9644083172151c5afacc503 (patch) | |
| tree | a560757325c9c842e12c4f87b25e759b1997a341 | |
| parent | 4eaac50552395f693b8c428872e8b5311c3dab60 (diff) | |
ASoC: wm8978: fix a memory leak if a wm8978_register fail
There is a memory leak found if wm8978_register() fail.
This patch moves the buffer allocate and release
at the same level to prevent the memory leak.
Signed-off-by: Axel Lin <axel.lin@gmail.com>
Reviewed-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
| -rw-r--r-- | sound/soc/codecs/wm8978.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 51d5f433215c..8a1ad778e7e3 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c | |||
| @@ -1076,7 +1076,6 @@ static __devinit int wm8978_register(struct wm8978_priv *wm8978) | |||
| 1076 | err_codec: | 1076 | err_codec: |
| 1077 | snd_soc_unregister_codec(codec); | 1077 | snd_soc_unregister_codec(codec); |
| 1078 | err: | 1078 | err: |
| 1079 | kfree(wm8978); | ||
| 1080 | return ret; | 1079 | return ret; |
| 1081 | } | 1080 | } |
| 1082 | 1081 | ||
| @@ -1085,13 +1084,13 @@ static __devexit void wm8978_unregister(struct wm8978_priv *wm8978) | |||
| 1085 | wm8978_set_bias_level(&wm8978->codec, SND_SOC_BIAS_OFF); | 1084 | wm8978_set_bias_level(&wm8978->codec, SND_SOC_BIAS_OFF); |
| 1086 | snd_soc_unregister_dai(&wm8978_dai); | 1085 | snd_soc_unregister_dai(&wm8978_dai); |
| 1087 | snd_soc_unregister_codec(&wm8978->codec); | 1086 | snd_soc_unregister_codec(&wm8978->codec); |
| 1088 | kfree(wm8978); | ||
| 1089 | wm8978_codec = NULL; | 1087 | wm8978_codec = NULL; |
| 1090 | } | 1088 | } |
| 1091 | 1089 | ||
| 1092 | static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, | 1090 | static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, |
| 1093 | const struct i2c_device_id *id) | 1091 | const struct i2c_device_id *id) |
| 1094 | { | 1092 | { |
| 1093 | int ret; | ||
| 1095 | struct wm8978_priv *wm8978; | 1094 | struct wm8978_priv *wm8978; |
| 1096 | struct snd_soc_codec *codec; | 1095 | struct snd_soc_codec *codec; |
| 1097 | 1096 | ||
| @@ -1107,13 +1106,18 @@ static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, | |||
| 1107 | 1106 | ||
| 1108 | codec->dev = &i2c->dev; | 1107 | codec->dev = &i2c->dev; |
| 1109 | 1108 | ||
| 1110 | return wm8978_register(wm8978); | 1109 | ret = wm8978_register(wm8978); |
| 1110 | if (ret < 0) | ||
| 1111 | kfree(wm8978); | ||
| 1112 | |||
| 1113 | return ret; | ||
| 1111 | } | 1114 | } |
| 1112 | 1115 | ||
| 1113 | static __devexit int wm8978_i2c_remove(struct i2c_client *client) | 1116 | static __devexit int wm8978_i2c_remove(struct i2c_client *client) |
| 1114 | { | 1117 | { |
| 1115 | struct wm8978_priv *wm8978 = i2c_get_clientdata(client); | 1118 | struct wm8978_priv *wm8978 = i2c_get_clientdata(client); |
| 1116 | wm8978_unregister(wm8978); | 1119 | wm8978_unregister(wm8978); |
| 1120 | kfree(wm8978); | ||
| 1117 | return 0; | 1121 | return 0; |
| 1118 | } | 1122 | } |
| 1119 | 1123 | ||
