[PATCH 46/133] [Jaunty SRU] ARM.imx51 Freescale:ENGR00111746 Sgtl5000: Bug fix

Brad Figg brad.figg at canonical.com
Thu Jul 9 16:48:36 UTC 2009


From: Wallace Wang <r59996 at freescale.com>

1. Remove i2c_unregister_device in sgtl5000
2. sgtl5000_set_bias_level in sgtl5000_remove failed to operate
   as imx_3stack_sgtl5000_remove is called before sgtl5000_remove.
   Add imx_3stack_machine_remove, move power disable from
   imx_3stack_sgtl5000_remove to this function.
3. name in imx_ssi_dai is a pointer to a constant string, can't
   use strcpy, or else the string will be overwritten and memory
   will be corrupted when the copied string length extend the
   original string length.
4. Add imx_ssi_remove to free irq

Signed-off-by: Wallace Wang <r59996 at freescale.com
Signed-off-by: Brad Figg <brad.figg at canonical.com>
---
 sound/soc/codecs/sgtl5000.c         |    2 -
 sound/soc/imx/imx-3stack-sgtl5000.c |   52 +++++++++++++++++++++-------------
 sound/soc/imx/imx-ssi.c             |   13 +++++++++
 3 files changed, 45 insertions(+), 22 deletions(-)

diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index ed39df3..0420868 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -1037,10 +1037,8 @@ static int sgtl5000_remove(struct platform_device *pdev)
 
 	if (codec->control_data)
 		sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
 	snd_soc_free_pcms(socdev);
 	snd_soc_dapm_free(socdev);
-	i2c_unregister_device(codec->control_data);
 	i2c_del_driver(&sgtl5000_i2c_driver);
 	kfree(codec->private_data);
 	kfree(codec);
diff --git a/sound/soc/imx/imx-3stack-sgtl5000.c b/sound/soc/imx/imx-3stack-sgtl5000.c
index 74f5e11..2ba9776 100644
--- a/sound/soc/imx/imx-3stack-sgtl5000.c
+++ b/sound/soc/imx/imx-3stack-sgtl5000.c
@@ -213,7 +213,6 @@ static void headphone_detect_handler(struct work_struct *work)
 	int hp_status;
 
 	sysfs_notify(&pdev->dev.kobj, NULL, "headphone");
-
 	hp_status = plat->hp_status();
 	if (hp_status)
 		set_irq_type(plat->hp_irq, IRQ_TYPE_EDGE_FALLING);
@@ -380,11 +379,37 @@ static struct snd_soc_dai_link imx_3stack_dai = {
 	.ops = &imx_3stack_ops,
 };
 
+static int imx_3stack_machine_remove(struct platform_device *pdev)
+{
+	struct imx_3stack_priv *priv = &machine_priv;
+	struct mxc_audio_platform_data *plat;
+	if (priv->reg_vddio)
+		regulator_disable(priv->reg_vddio);
+	if (priv->reg_vddd)
+		regulator_disable(priv->reg_vddd);
+	if (priv->reg_vdda)
+		regulator_disable(priv->reg_vdda);
+	if (priv->reg_vdda)
+		regulator_put(priv->reg_vdda);
+	if (priv->reg_vddio)
+		regulator_put(priv->reg_vddio);
+	if (priv->reg_vddd)
+		regulator_put(priv->reg_vddd);
+	if (priv->pdev) {
+		plat = priv->pdev->dev.platform_data;
+		if (plat->finit)
+			plat->finit();
+	}
+
+	return 0;
+}
+
 /* imx_3stack audio machine driver */
 static struct snd_soc_machine snd_soc_machine_imx_3stack = {
 	.name = "imx-3stack",
 	.dai_link = &imx_3stack_dai,
 	.num_links = 1,
+	.remove = imx_3stack_machine_remove,
 };
 
 static struct snd_soc_device imx_3stack_snd_devdata = {
@@ -419,9 +444,9 @@ static int __devinit imx_3stack_sgtl5000_probe(struct platform_device *pdev)
 	imx_3stack_init_dam(plat->src_port, plat->ext_port);
 
 	if (plat->src_port == 2)
-		strcpy(imx_ssi_dai.name, "imx-ssi-3");
+		imx_ssi_dai.name = "imx-ssi-3";
 	else
-		strcpy(imx_ssi_dai.name, "imx-ssi-1");
+		imx_ssi_dai.name = "imx-ssi-1";
 
 	ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone);
 	if (ret < 0) {
@@ -516,22 +541,9 @@ static int imx_3stack_sgtl5000_remove(struct platform_device *pdev)
 
 	free_irq(plat->hp_irq, priv);
 
-	if (priv->reg_vddio)
-		regulator_disable(priv->reg_vddio);
-	if (priv->reg_vddd)
-		regulator_disable(priv->reg_vddd);
-	if (priv->reg_vdda)
-		regulator_disable(priv->reg_vdda);
-	if (plat->amp_enable)
-		plat->amp_enable(0);
-	if (plat->finit)
-		plat->finit();
-	if (priv->reg_vdda)
-		regulator_put(priv->reg_vdda);
-	if (priv->reg_vddio)
-		regulator_put(priv->reg_vddio);
-	if (priv->reg_vddd)
-		regulator_put(priv->reg_vddd);
+	driver_remove_file(pdev->dev.driver, &driver_attr_headphone);
+
+	kfree(imx_3stack_snd_devdata.codec_data);
 
 	return 0;
 }
@@ -554,7 +566,7 @@ static int __init imx_3stack_init(void)
 	if (ret)
 		return -ENOMEM;
 
-	imx_3stack_snd_device = platform_device_alloc("soc-audio", -1);
+	imx_3stack_snd_device = platform_device_alloc("soc-audio", 2);
 	if (!imx_3stack_snd_device)
 		return -ENOMEM;
 
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index e16cafe..b0bc51a 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -714,6 +714,18 @@ static int imx_ssi_probe(struct platform_device *pdev, struct snd_soc_dai *dai)
 	return 0;
 }
 
+static void imx_ssi_remove(struct platform_device *pdev,
+			   struct snd_soc_dai *dai)
+{
+	if ((!strcmp(dai->name, "imx-ssi-1")) ||
+	    (!strcmp(dai->name, "imx-ssi-2")))
+		free_irq(MXC_INT_SSI1, dai);
+
+	if ((!strcmp(dai->name, "imx-ssi-3")) ||
+	    (!strcmp(dai->name, "imx-ssi-4")))
+		free_irq(MXC_INT_SSI2, dai);
+}
+
 #define IMX_SSI_RATES \
 	(SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \
 	SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
@@ -731,6 +743,7 @@ struct snd_soc_dai imx_ssi_dai = {
 	.type = SND_SOC_DAI_PCM,
 	.probe = imx_ssi_probe,
 	.suspend = imx_ssi_suspend,
+	.remove = imx_ssi_remove,
 	.resume = imx_ssi_resume,
 	.playback = {
 		     .channels_min = 1,
-- 
1.6.0.4





More information about the kernel-team mailing list