From 3b19449547a5010304c8f01a0e7d949f2c981d47 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 27 Sep 2017 12:20:22 +0800 Subject: [PATCH] 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 --- asoc/codecs/wcd9335.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 19877b96b0..8ade82b7bb 100644 --- a/asoc/codecs/wcd9335.c +++ b/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; }