Browse Source

audio-lnx: asoc: codecs: Fix rmmod issues with wcd9335

Remove any child devices associated with this
codec driver so that rmmod and insmod again will
run without issues.

Clear MBHC setting during tasha_remove.

Change-Id: Icad9b2ad21601525c68c5d151cd664aa6060e911
Signed-off-by: Meng Wang <[email protected]>
Meng Wang 7 years ago
parent
commit
3b19449547
1 changed files with 25 additions and 2 deletions
  1. 25 2
      asoc/codecs/wcd9335.c

+ 25 - 2
asoc/codecs/wcd9335.c

@@ -87,6 +87,8 @@
 #define TASHA_NUM_INTERPOLATORS 9
 #define TASHA_NUM_DECIMATORS 9
 
+#define WCD9335_CHILD_DEVICES_MAX	6
+
 #define BYTE_BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE))
 #define TASHA_MAD_AUDIO_FIRMWARE_PATH "wcd9335/wcd9335_mad_audio.bin"
 #define TASHA_CPE_SS_ERR_STATUS_MEM_ACCESS (1 << 0)
@@ -829,6 +831,10 @@ struct tasha_priv {
 	u32 ref_count;
 	/* Lock to protect mclk enablement */
 	struct mutex mclk_lock;
+
+	struct platform_device *pdev_child_devices
+			[WCD9335_CHILD_DEVICES_MAX];
+	int child_count;
 };
 
 static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec,
@@ -13576,11 +13582,14 @@ static int tasha_codec_remove(struct snd_soc_codec *codec)
 	struct wcd9xxx *control;
 
 	control = dev_get_drvdata(codec->dev->parent);
+	control->num_rx_port = 0;
+	control->num_tx_port = 0;
 	control->rx_chs = NULL;
 	control->tx_chs = NULL;
 
 	tasha_cleanup_irqs(tasha);
 	/* Cleanup MBHC */
+	wcd_mbhc_deinit(&tasha->mbhc);
 	/* Cleanup resmgr */
 
 	return 0;
@@ -13920,6 +13929,7 @@ static void tasha_add_child_devices(struct work_struct *work)
 	}
 
 	platdata = &tasha->swr_plat_data;
+	tasha->child_count = 0;
 
 	for_each_child_of_node(wcd9xxx->dev->of_node, node) {
 		if (!strcmp(node->name, "swr_master"))
@@ -13980,6 +13990,11 @@ static void tasha_add_child_devices(struct work_struct *work)
 			tasha->nr = ctrl_num;
 			tasha->swr_ctrl_data = swr_ctrl_data;
 		}
+
+		if (tasha->child_count < WCD9335_CHILD_DEVICES_MAX)
+			tasha->pdev_child_devices[tasha->child_count++] = pdev;
+		else
+			goto err;
 	}
 
 	return;
@@ -14179,17 +14194,25 @@ err_cdc_pwr:
 static int tasha_remove(struct platform_device *pdev)
 {
 	struct tasha_priv *tasha;
+	int count = 0;
 
 	tasha = platform_get_drvdata(pdev);
 
+	if (!tasha)
+		return -EINVAL;
+
+	for (count = 0; count < tasha->child_count &&
+		count < WCD9335_CHILD_DEVICES_MAX; count++)
+		platform_device_unregister(tasha->pdev_child_devices[count]);
+
 	mutex_destroy(&tasha->codec_mutex);
 	clk_put(tasha->wcd_ext_clk);
 	if (tasha->wcd_native_clk)
 		clk_put(tasha->wcd_native_clk);
 	mutex_destroy(&tasha->mclk_lock);
-	devm_kfree(&pdev->dev, tasha);
-	snd_soc_unregister_codec(&pdev->dev);
 	mutex_destroy(&tasha->sb_clk_gear_lock);
+	snd_soc_unregister_codec(&pdev->dev);
+	devm_kfree(&pdev->dev, tasha);
 	return 0;
 }