summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2008-09-30 11:40:37 +0200
committerTakashi Iwai <tiwai@suse.de>2008-09-30 12:47:12 +0200
commite3145dfb7b4262fa55907006b75da799de8c1be3 (patch)
tree5260088839385b751953cb0ad47cef9633f9ad23
parent9778e9a0eafe796c2affcd1fa1fa8a3765e026e6 (diff)
ALSA: ASoC: Fix cs4270 error path
The error path in cs4270_probe/cs4270_remove is pretty broken: * If cs4270_probe fails, codec is leaked. * If snd_soc_register_card fails, cs4270_i2c_driver stays registered. * If I2C support is enabled but no I2C device is found, i2c_del_driver is never called (neither in cs4270_probe nor in cs4270_remove. Fix all 3 problems by implementing a clean error path in cs4270_probe and jumping to its labels as needed. Signed-off-by: Jean Delvare <khali@linux-fr.org> Acked-by: Timur Tabi <timur@freescale.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/soc/codecs/cs4270.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index d68650de39bc..0bbd94501d7e 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -681,7 +681,7 @@ static int cs4270_probe(struct platform_device *pdev)
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
printk(KERN_ERR "cs4270: failed to create PCMs\n");
- return ret;
+ goto error_free_codec;
}
#ifdef USE_I2C
@@ -690,8 +690,7 @@ static int cs4270_probe(struct platform_device *pdev)
ret = i2c_add_driver(&cs4270_i2c_driver);
if (ret) {
printk(KERN_ERR "cs4270: failed to attach driver");
- snd_soc_free_pcms(socdev);
- return ret;
+ goto error_free_pcms;
}
/* Did we find a CS4270 on the I2C bus? */
@@ -713,10 +712,23 @@ static int cs4270_probe(struct platform_device *pdev)
ret = snd_soc_register_card(socdev);
if (ret < 0) {
printk(KERN_ERR "cs4270: failed to register card\n");
- snd_soc_free_pcms(socdev);
- return ret;
+ goto error_del_driver;
}
+ return 0;
+
+error_del_driver:
+#ifdef USE_I2C
+ i2c_del_driver(&cs4270_i2c_driver);
+
+error_free_pcms:
+#endif
+ snd_soc_free_pcms(socdev);
+
+error_free_codec:
+ kfree(socdev->codec);
+ socdev->codec = NULL;
+
return ret;
}
@@ -727,8 +739,7 @@ static int cs4270_remove(struct platform_device *pdev)
snd_soc_free_pcms(socdev);
#ifdef USE_I2C
- if (socdev->codec->control_data)
- i2c_del_driver(&cs4270_i2c_driver);
+ i2c_del_driver(&cs4270_i2c_driver);
#endif
kfree(socdev->codec);