From 42adadc24fb2a370d0ceee2208630a3c51d231e5 Mon Sep 17 00:00:00 2001 From: Harshal Ahire Date: Fri, 15 Nov 2019 15:52:50 +0530 Subject: [PATCH] asoc: codecs: avoid crash after diconnecting DP cable Fix the null pointer access of DP callback functions. Change-Id: If4cc48a2471c2cbd1c46ea49cffaa01315673bde Signed-off-by: Harshal Ahire --- asoc/codecs/msm_hdmi_codec_rx.c | 37 ++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/asoc/codecs/msm_hdmi_codec_rx.c b/asoc/codecs/msm_hdmi_codec_rx.c index 5144b923b0..1588c56767 100644 --- a/asoc/codecs/msm_hdmi_codec_rx.c +++ b/asoc/codecs/msm_hdmi_codec_rx.c @@ -29,8 +29,6 @@ codec_info.type = EXT_DISPLAY_TYPE_DP; \ codec_info.ctrl_id = codec_data->ctl[dai_id]; \ codec_info.stream_id = codec_data->stream[dai_id]; \ - msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, \ - &codec_info) enum { DP_CONTROLLER0 = 0, @@ -94,7 +92,9 @@ static int msm_ext_disp_edid_ctl_info(struct snd_kcontrol *kcontrol, mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai_id); - if (!codec_data->ext_disp_ops.get_audio_edid_blk) { + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); + if (!codec_data->ext_disp_ops.get_audio_edid_blk || rc) { dev_dbg(component->dev, "%s: get_audio_edid_blk() is NULL\n", __func__); uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; @@ -139,7 +139,9 @@ static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol, mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai_id); - if (!codec_data->ext_disp_ops.get_audio_edid_blk) { + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); + if (!codec_data->ext_disp_ops.get_audio_edid_blk || rc) { dev_err(component->dev, "%s: codec_data or get_audio_edid_blk() is NULL\n", __func__); mutex_unlock(&codec_data->dp_ops_lock); @@ -199,9 +201,11 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai_id); + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); if (!codec_data->ext_disp_ops.get_audio_edid_blk || - !codec_data->ext_disp_ops.get_intf_id) { + !codec_data->ext_disp_ops.get_intf_id || rc) { dev_err(component->dev, "%s: get_audio_edid_blk() or get_intf_id is NULL\n", __func__); rc = -EINVAL; @@ -284,8 +288,10 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai_id); + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); - if (!codec_data->ext_disp_ops.acknowledge) { + if (!codec_data->ext_disp_ops.acknowledge || rc) { dev_err(component->dev, "%s: codec_data ops acknowledge() is NULL\n", __func__); @@ -460,7 +466,7 @@ static int msm_ext_disp_audio_codec_rx_dai_startup( struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - int ret = 0; + int ret = 0, rc = 0; struct msm_ext_disp_codec_id codec_info; struct msm_ext_disp_audio_codec_rx_data *codec_data = dev_get_drvdata(dai->component->dev); @@ -477,8 +483,10 @@ static int msm_ext_disp_audio_codec_rx_dai_startup( mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai->id); + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); - if (!codec_data->ext_disp_ops.cable_status) { + if (!codec_data->ext_disp_ops.cable_status || rc) { dev_err(dai->dev, "%s() cable_status is null\n", __func__); mutex_unlock(&codec_data->dp_ops_lock); @@ -532,8 +540,10 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params( mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai->id); + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); - if (!codec_data->ext_disp_ops.audio_info_setup) { + if (!codec_data->ext_disp_ops.audio_info_setup || rc) { dev_err(dai->dev, "%s: audio_info_setup is null\n", __func__); mutex_unlock(&codec_data->dp_ops_lock); @@ -600,8 +610,13 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params( mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai->id); + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); + if (rc) + goto end; rc = codec_data->ext_disp_ops.audio_info_setup( codec_data->ext_disp_core_pdev, &audio_setup_params); +end: mutex_unlock(&codec_data->dp_ops_lock); if (rc < 0) { dev_err_ratelimited(dai->dev, @@ -634,9 +649,11 @@ static void msm_ext_disp_audio_codec_rx_dai_shutdown( mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai->id); + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); if (!codec_data->ext_disp_ops.teardown_done || - !codec_data->ext_disp_ops.cable_status) { + !codec_data->ext_disp_ops.cable_status || rc) { dev_err(dai->dev, "%s: teardown_done or cable_status is null\n", __func__); mutex_unlock(&codec_data->dp_ops_lock);