diff options
| author | Dipesh Gandhi <dipeshg@nvidia.com> | 2019-12-31 00:21:43 -0500 |
|---|---|---|
| committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2020-01-07 06:09:06 -0500 |
| commit | 699864836d95fc46f8ef68a6288360b3cae4f0e2 (patch) | |
| tree | 4974cdcc846f802188bcc94bd8d7d7fdb7e518ca | |
| parent | 728d985a72aa23e0333ac22a9fcbf9d6b445b9c3 (diff) | |
tegra-virt: incorrect cif setting for admaif
Change takes care of bug in admaif driver. hw_params
function runs in non-atomic context and we have reference
to static data that is unprotected. Change remove the
dependency on static data and keep the info on stack.
Bug 2796179
Change-Id: Iaffe460144fb47c82e2a40cb494dad212b9a5d24
Signed-off-by: Dipesh Gandhi <dipeshg@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2271089
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Uday Gupta <udayg@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Phoenix Jung <pjung@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
| -rw-r--r-- | sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.c | 65 | ||||
| -rw-r--r-- | sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.h | 4 |
2 files changed, 31 insertions, 38 deletions
diff --git a/sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.c b/sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.c index ccd83c5e4..3ff3de2a3 100644 --- a/sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.c +++ b/sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * tegra210_virt_alt_admaif.c - Tegra ADMAIF component driver | 2 | * tegra210_virt_alt_admaif.c - Tegra ADMAIF component driver |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2014-2019 NVIDIA CORPORATION. All rights reserved. | 4 | * Copyright (c) 2014-2020 NVIDIA CORPORATION. All rights reserved. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
| 7 | * under the terms and conditions of the GNU General Public License, | 7 | * under the terms and conditions of the GNU General Public License, |
| @@ -49,64 +49,63 @@ static int tegra210_admaif_hw_params(struct snd_pcm_substream *substream, | |||
| 49 | struct device *dev = dai->dev; | 49 | struct device *dev = dai->dev; |
| 50 | struct tegra210_virt_admaif_client_data *data = | 50 | struct tegra210_virt_admaif_client_data *data = |
| 51 | &admaif->client_data; | 51 | &admaif->client_data; |
| 52 | struct tegra210_virt_audio_cif *cif_conf = &data->cif; | 52 | struct tegra210_virt_audio_cif cif_conf; |
| 53 | struct nvaudio_ivc_msg msg; | 53 | struct nvaudio_ivc_msg msg; |
| 54 | unsigned int value; | 54 | unsigned int value; |
| 55 | int err; | 55 | int err; |
| 56 | 56 | ||
| 57 | data->admaif_id = dai->id; | 57 | memset(&cif_conf, 0, sizeof(struct tegra210_virt_audio_cif)); |
| 58 | memset(cif_conf, 0, sizeof(struct tegra210_virt_audio_cif)); | 58 | cif_conf.audio_channels = params_channels(params); |
| 59 | cif_conf->audio_channels = params_channels(params); | 59 | cif_conf.client_channels = params_channels(params); |
| 60 | cif_conf->client_channels = params_channels(params); | ||
| 61 | 60 | ||
| 62 | switch (params_format(params)) { | 61 | switch (params_format(params)) { |
| 63 | case SNDRV_PCM_FORMAT_S8: | 62 | case SNDRV_PCM_FORMAT_S8: |
| 64 | cif_conf->client_bits = TEGRA210_AUDIOCIF_BITS_8; | 63 | cif_conf.client_bits = TEGRA210_AUDIOCIF_BITS_8; |
| 65 | cif_conf->audio_bits = TEGRA210_AUDIOCIF_BITS_8; | 64 | cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_8; |
| 66 | break; | 65 | break; |
| 67 | case SNDRV_PCM_FORMAT_S16_LE: | 66 | case SNDRV_PCM_FORMAT_S16_LE: |
| 68 | cif_conf->client_bits = TEGRA210_AUDIOCIF_BITS_16; | 67 | cif_conf.client_bits = TEGRA210_AUDIOCIF_BITS_16; |
| 69 | cif_conf->audio_bits = TEGRA210_AUDIOCIF_BITS_16; | 68 | cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_16; |
| 70 | break; | 69 | break; |
| 71 | case SNDRV_PCM_FORMAT_S24_LE: | 70 | case SNDRV_PCM_FORMAT_S24_LE: |
| 72 | cif_conf->client_bits = TEGRA210_AUDIOCIF_BITS_24; | 71 | cif_conf.client_bits = TEGRA210_AUDIOCIF_BITS_24; |
| 73 | cif_conf->audio_bits = TEGRA210_AUDIOCIF_BITS_24; | 72 | cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_24; |
| 74 | break; | 73 | break; |
| 75 | case SNDRV_PCM_FORMAT_S32_LE: | 74 | case SNDRV_PCM_FORMAT_S32_LE: |
| 76 | cif_conf->client_bits = TEGRA210_AUDIOCIF_BITS_32; | 75 | cif_conf.client_bits = TEGRA210_AUDIOCIF_BITS_32; |
| 77 | cif_conf->audio_bits = TEGRA210_AUDIOCIF_BITS_32; | 76 | cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_32; |
| 78 | break; | 77 | break; |
| 79 | default: | 78 | default: |
| 80 | dev_err(dev, "Wrong format!\n"); | 79 | dev_err(dev, "Wrong format!\n"); |
| 81 | return -EINVAL; | 80 | return -EINVAL; |
| 82 | } | 81 | } |
| 83 | cif_conf->direction = substream->stream; | 82 | cif_conf.direction = substream->stream; |
| 84 | 83 | ||
| 85 | value = (cif_conf->threshold << | 84 | value = (cif_conf.threshold << |
| 86 | TEGRA210_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | | 85 | TEGRA210_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | |
| 87 | ((cif_conf->audio_channels - 1) << | 86 | ((cif_conf.audio_channels - 1) << |
| 88 | TEGRA210_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) | | 87 | TEGRA210_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) | |
| 89 | ((cif_conf->client_channels - 1) << | 88 | ((cif_conf.client_channels - 1) << |
| 90 | TEGRA210_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) | | 89 | TEGRA210_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) | |
| 91 | (cif_conf->audio_bits << | 90 | (cif_conf.audio_bits << |
| 92 | TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) | | 91 | TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) | |
| 93 | (cif_conf->client_bits << | 92 | (cif_conf.client_bits << |
| 94 | TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT) | | 93 | TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT) | |
| 95 | (cif_conf->expand << | 94 | (cif_conf.expand << |
| 96 | TEGRA210_AUDIOCIF_CTRL_EXPAND_SHIFT) | | 95 | TEGRA210_AUDIOCIF_CTRL_EXPAND_SHIFT) | |
| 97 | (cif_conf->stereo_conv << | 96 | (cif_conf.stereo_conv << |
| 98 | TEGRA210_AUDIOCIF_CTRL_STEREO_CONV_SHIFT) | | 97 | TEGRA210_AUDIOCIF_CTRL_STEREO_CONV_SHIFT) | |
| 99 | (cif_conf->replicate << | 98 | (cif_conf.replicate << |
| 100 | TEGRA210_AUDIOCIF_CTRL_REPLICATE_SHIFT) | | 99 | TEGRA210_AUDIOCIF_CTRL_REPLICATE_SHIFT) | |
| 101 | (cif_conf->truncate << | 100 | (cif_conf.truncate << |
| 102 | TEGRA210_AUDIOCIF_CTRL_TRUNCATE_SHIFT) | | 101 | TEGRA210_AUDIOCIF_CTRL_TRUNCATE_SHIFT) | |
| 103 | (cif_conf->mono_conv << | 102 | (cif_conf.mono_conv << |
| 104 | TEGRA210_AUDIOCIF_CTRL_MONO_CONV_SHIFT); | 103 | TEGRA210_AUDIOCIF_CTRL_MONO_CONV_SHIFT); |
| 105 | 104 | ||
| 106 | memset(&msg, 0, sizeof(struct nvaudio_ivc_msg)); | 105 | memset(&msg, 0, sizeof(struct nvaudio_ivc_msg)); |
| 107 | msg.params.dmaif_info.id = data->admaif_id; | 106 | msg.params.dmaif_info.id = dai->id; |
| 108 | msg.params.dmaif_info.value = value; | 107 | msg.params.dmaif_info.value = value; |
| 109 | if (!cif_conf->direction) | 108 | if (!cif_conf.direction) |
| 110 | msg.cmd = NVAUDIO_DMAIF_SET_TXCIF; | 109 | msg.cmd = NVAUDIO_DMAIF_SET_TXCIF; |
| 111 | else | 110 | else |
| 112 | msg.cmd = NVAUDIO_DMAIF_SET_RXCIF; | 111 | msg.cmd = NVAUDIO_DMAIF_SET_RXCIF; |
| @@ -128,10 +127,9 @@ static void tegra210_admaif_start_playback(struct snd_soc_dai *dai) | |||
| 128 | int err; | 127 | int err; |
| 129 | struct nvaudio_ivc_msg msg; | 128 | struct nvaudio_ivc_msg msg; |
| 130 | 129 | ||
| 131 | data->admaif_id = dai->id; | ||
| 132 | memset(&msg, 0, sizeof(struct nvaudio_ivc_msg)); | 130 | memset(&msg, 0, sizeof(struct nvaudio_ivc_msg)); |
| 133 | msg.cmd = NVAUDIO_START_PLAYBACK; | 131 | msg.cmd = NVAUDIO_START_PLAYBACK; |
| 134 | msg.params.dmaif_info.id = data->admaif_id; | 132 | msg.params.dmaif_info.id = dai->id; |
| 135 | msg.ack_required = true; | 133 | msg.ack_required = true; |
| 136 | err = nvaudio_ivc_send_receive(data->hivc_client, | 134 | err = nvaudio_ivc_send_receive(data->hivc_client, |
| 137 | &msg, sizeof(struct nvaudio_ivc_msg)); | 135 | &msg, sizeof(struct nvaudio_ivc_msg)); |
| @@ -147,10 +145,9 @@ static void tegra210_admaif_stop_playback(struct snd_soc_dai *dai) | |||
| 147 | int err; | 145 | int err; |
| 148 | struct nvaudio_ivc_msg msg; | 146 | struct nvaudio_ivc_msg msg; |
| 149 | 147 | ||
| 150 | data->admaif_id = dai->id; | ||
| 151 | memset(&msg, 0, sizeof(struct nvaudio_ivc_msg)); | 148 | memset(&msg, 0, sizeof(struct nvaudio_ivc_msg)); |
| 152 | msg.cmd = NVAUDIO_STOP_PLAYBACK; | 149 | msg.cmd = NVAUDIO_STOP_PLAYBACK; |
| 153 | msg.params.dmaif_info.id = data->admaif_id; | 150 | msg.params.dmaif_info.id = dai->id; |
| 154 | 151 | ||
| 155 | msg.ack_required = true; | 152 | msg.ack_required = true; |
| 156 | err = nvaudio_ivc_send_receive(data->hivc_client, | 153 | err = nvaudio_ivc_send_receive(data->hivc_client, |
| @@ -167,10 +164,9 @@ static void tegra210_admaif_start_capture(struct snd_soc_dai *dai) | |||
| 167 | int err; | 164 | int err; |
| 168 | struct nvaudio_ivc_msg msg; | 165 | struct nvaudio_ivc_msg msg; |
| 169 | 166 | ||
| 170 | data->admaif_id = dai->id; | ||
| 171 | memset(&msg, 0, sizeof(struct nvaudio_ivc_msg)); | 167 | memset(&msg, 0, sizeof(struct nvaudio_ivc_msg)); |
| 172 | msg.cmd = NVAUDIO_START_CAPTURE; | 168 | msg.cmd = NVAUDIO_START_CAPTURE; |
| 173 | msg.params.dmaif_info.id = data->admaif_id; | 169 | msg.params.dmaif_info.id = dai->id; |
| 174 | 170 | ||
| 175 | msg.ack_required = true; | 171 | msg.ack_required = true; |
| 176 | err = nvaudio_ivc_send_receive(data->hivc_client, | 172 | err = nvaudio_ivc_send_receive(data->hivc_client, |
| @@ -187,10 +183,9 @@ static void tegra210_admaif_stop_capture(struct snd_soc_dai *dai) | |||
| 187 | int err; | 183 | int err; |
| 188 | struct nvaudio_ivc_msg msg; | 184 | struct nvaudio_ivc_msg msg; |
| 189 | 185 | ||
| 190 | data->admaif_id = dai->id; | ||
| 191 | memset(&msg, 0, sizeof(struct nvaudio_ivc_msg)); | 186 | memset(&msg, 0, sizeof(struct nvaudio_ivc_msg)); |
| 192 | msg.cmd = NVAUDIO_STOP_CAPTURE; | 187 | msg.cmd = NVAUDIO_STOP_CAPTURE; |
| 193 | msg.params.dmaif_info.id = data->admaif_id; | 188 | msg.params.dmaif_info.id = dai->id; |
| 194 | 189 | ||
| 195 | msg.ack_required = true; | 190 | msg.ack_required = true; |
| 196 | err = nvaudio_ivc_send_receive(data->hivc_client, | 191 | err = nvaudio_ivc_send_receive(data->hivc_client, |
diff --git a/sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.h b/sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.h index 6e8c8cae0..56c871da7 100644 --- a/sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.h +++ b/sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * tegra210_virt_alt_admaif.h - Tegra210 ADMAIF registers | 2 | * tegra210_virt_alt_admaif.h - Tegra210 ADMAIF registers |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2014-2019 NVIDIA CORPORATION. All rights reserved. | 4 | * Copyright (c) 2014-2020 NVIDIA CORPORATION. All rights reserved. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
| 7 | * under the terms and conditions of the GNU General Public License, | 7 | * under the terms and conditions of the GNU General Public License, |
| @@ -95,8 +95,6 @@ struct tegra210_virt_audio_cif { | |||
| 95 | 95 | ||
| 96 | /* apbif data */ | 96 | /* apbif data */ |
| 97 | struct tegra210_virt_admaif_client_data { | 97 | struct tegra210_virt_admaif_client_data { |
| 98 | unsigned int admaif_id; | ||
| 99 | struct tegra210_virt_audio_cif cif; | ||
| 100 | struct nvaudio_ivc_ctxt *hivc_client; | 98 | struct nvaudio_ivc_ctxt *hivc_client; |
| 101 | }; | 99 | }; |
| 102 | 100 | ||
