summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDipesh Gandhi <dipeshg@nvidia.com>2019-12-31 00:21:43 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2020-01-07 06:09:06 -0500
commit699864836d95fc46f8ef68a6288360b3cae4f0e2 (patch)
tree4974cdcc846f802188bcc94bd8d7d7fdb7e518ca
parent728d985a72aa23e0333ac22a9fcbf9d6b445b9c3 (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.c65
-rw-r--r--sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.h4
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 */
97struct tegra210_virt_admaif_client_data { 97struct 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