Skip to content

Commit fc976f5

Browse files
ujfalusibroonie
authored andcommitted
ASoC: Intel: Skylake: Correct the handling of fmt_config flexible array
The struct nhlt_format's fmt_config is a flexible array, it must not be used as normal array. When moving to the next nhlt_fmt_cfg we need to take into account the data behind the ->config.caps (indicated by ->config.size). The logic of the code also changed: it is no longer saves the _last_ fmt_cfg for all found rates. Fixes: bc2bd45 ("ASoC: Intel: Skylake: Parse nhlt and register clock device") Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com> Link: https://lore.kernel.org/r/20220630065638.11183-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 219af25 commit fc976f5

File tree

1 file changed

+25
-12
lines changed

1 file changed

+25
-12
lines changed

sound/soc/intel/skylake/skl-nhlt.c

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,12 @@ static void skl_get_ssp_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks,
111111
if (fmt->fmt_count == 0)
112112
return;
113113

114+
fmt_cfg = (struct nhlt_fmt_cfg *)fmt->fmt_config;
114115
for (i = 0; i < fmt->fmt_count; i++) {
116+
struct nhlt_fmt_cfg *saved_fmt_cfg = fmt_cfg;
115117
bool present = false;
116118

117-
fmt_cfg = &fmt->fmt_config[i];
118-
wav_fmt = &fmt_cfg->fmt_ext;
119+
wav_fmt = &saved_fmt_cfg->fmt_ext;
119120

120121
channels = wav_fmt->fmt.channels;
121122
bps = wav_fmt->fmt.bits_per_sample;
@@ -133,12 +134,18 @@ static void skl_get_ssp_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks,
133134
* derive the rate.
134135
*/
135136
for (j = i; j < fmt->fmt_count; j++) {
136-
fmt_cfg = &fmt->fmt_config[j];
137-
wav_fmt = &fmt_cfg->fmt_ext;
137+
struct nhlt_fmt_cfg *tmp_fmt_cfg = fmt_cfg;
138+
139+
wav_fmt = &tmp_fmt_cfg->fmt_ext;
138140
if ((fs == wav_fmt->fmt.samples_per_sec) &&
139-
(bps == wav_fmt->fmt.bits_per_sample))
141+
(bps == wav_fmt->fmt.bits_per_sample)) {
140142
channels = max_t(u16, channels,
141143
wav_fmt->fmt.channels);
144+
saved_fmt_cfg = tmp_fmt_cfg;
145+
}
146+
/* Move to the next nhlt_fmt_cfg */
147+
tmp_fmt_cfg = (struct nhlt_fmt_cfg *)(tmp_fmt_cfg->config.caps +
148+
tmp_fmt_cfg->config.size);
142149
}
143150

144151
rate = channels * bps * fs;
@@ -154,8 +161,11 @@ static void skl_get_ssp_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks,
154161

155162
/* Fill rate and parent for sclk/sclkfs */
156163
if (!present) {
164+
struct nhlt_fmt_cfg *first_fmt_cfg;
165+
166+
first_fmt_cfg = (struct nhlt_fmt_cfg *)fmt->fmt_config;
157167
i2s_config_ext = (struct skl_i2s_config_blob_ext *)
158-
fmt->fmt_config[0].config.caps;
168+
first_fmt_cfg->config.caps;
159169

160170
/* MCLK Divider Source Select */
161171
if (is_legacy_blob(i2s_config_ext->hdr.sig)) {
@@ -169,6 +179,9 @@ static void skl_get_ssp_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks,
169179

170180
parent = skl_get_parent_clk(clk_src);
171181

182+
/* Move to the next nhlt_fmt_cfg */
183+
fmt_cfg = (struct nhlt_fmt_cfg *)(fmt_cfg->config.caps +
184+
fmt_cfg->config.size);
172185
/*
173186
* Do not copy the config data if there is no parent
174187
* clock available for this clock source select
@@ -177,9 +190,9 @@ static void skl_get_ssp_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks,
177190
continue;
178191

179192
sclk[id].rate_cfg[rate_index].rate = rate;
180-
sclk[id].rate_cfg[rate_index].config = fmt_cfg;
193+
sclk[id].rate_cfg[rate_index].config = saved_fmt_cfg;
181194
sclkfs[id].rate_cfg[rate_index].rate = rate;
182-
sclkfs[id].rate_cfg[rate_index].config = fmt_cfg;
195+
sclkfs[id].rate_cfg[rate_index].config = saved_fmt_cfg;
183196
sclk[id].parent_name = parent->name;
184197
sclkfs[id].parent_name = parent->name;
185198

@@ -193,13 +206,13 @@ static void skl_get_mclk(struct skl_dev *skl, struct skl_ssp_clk *mclk,
193206
{
194207
struct skl_i2s_config_blob_ext *i2s_config_ext;
195208
struct skl_i2s_config_blob_legacy *i2s_config;
196-
struct nhlt_specific_cfg *fmt_cfg;
209+
struct nhlt_fmt_cfg *fmt_cfg;
197210
struct skl_clk_parent_src *parent;
198211
u32 clkdiv, div_ratio;
199212
u8 clk_src;
200213

201-
fmt_cfg = &fmt->fmt_config[0].config;
202-
i2s_config_ext = (struct skl_i2s_config_blob_ext *)fmt_cfg->caps;
214+
fmt_cfg = (struct nhlt_fmt_cfg *)fmt->fmt_config;
215+
i2s_config_ext = (struct skl_i2s_config_blob_ext *)fmt_cfg->config.caps;
203216

204217
/* MCLK Divider Source Select and divider */
205218
if (is_legacy_blob(i2s_config_ext->hdr.sig)) {
@@ -228,7 +241,7 @@ static void skl_get_mclk(struct skl_dev *skl, struct skl_ssp_clk *mclk,
228241
return;
229242

230243
mclk[id].rate_cfg[0].rate = parent->rate/div_ratio;
231-
mclk[id].rate_cfg[0].config = &fmt->fmt_config[0];
244+
mclk[id].rate_cfg[0].config = fmt_cfg;
232245
mclk[id].parent_name = parent->name;
233246
}
234247

0 commit comments

Comments
 (0)