History

ALSA: compress_offload: Add 64-bit safe timestamp infrastructure

The copied_total field in struct snd_compr_tstamp is a 32-bit value that can overflow on long-running high-bitrate streams, leading to incorrect calculations for buffer availablility. This patch adds a 64-bit safe timestamping mechanism. A new UAPI struct, snd_compr_tstamp64, is added which uses 64-bit types for byte counters. The relevant ops structures across the ASoC and core compress code are updated to use this new struct. ASoC drivers are updated to use u64 counters. Internal timestamps being u64 now, a compatibility function is added to convert the 64-bit timestamp back to the 32-bit format for legacy ioctl callers.

Joris Verhaegen committed 1 year ago

Commit 2c92e2f1 parent cbd676824 files · +125 −72Browse files

Unified · Split

24 files
  1. include/sound/compress_driver.h +1 −1
  2. include/sound/soc-component.h +2 −2
  3. include/sound/soc-dai.h +4 −3
  4. include/uapi/sound/compress_offload.h +19 −0
  5. sound/core/compress_offload.c +35 −17
  6. sound/soc/codecs/wm_adsp.c +2 −2
  7. sound/soc/codecs/wm_adsp.h +1 −1
  8. sound/soc/intel/atom/sst-mfld-platform-compress.c +7 −5
  9. sound/soc/intel/atom/sst-mfld-platform.h +1 −1
  10. sound/soc/intel/atom/sst/sst_drv_interface.c +5 −4
  11. sound/soc/intel/avs/probes.c +1 −1
  12. sound/soc/qcom/qdsp6/q6apm-dai.c +16 −10
  13. sound/soc/qcom/qdsp6/q6asm-dai.c +16 −10
  14. sound/soc/soc-component.c +1 −1
  15. sound/soc/soc-compress.c +1 −1
  16. sound/soc/soc-dai.c +1 −1
  17. sound/soc/sof/amd/acp-probes.c +1 −1
  18. sound/soc/sof/compress.c +1 −1
  19. sound/soc/sof/intel/hda-probes.c +1 −1
  20. sound/soc/sof/sof-client-probes.c +1 −1
  21. sound/soc/sof/sof-client-probes.h +2 −2
  22. sound/soc/sprd/sprd-pcm-compress.c +3 −3
  23. sound/soc/sprd/sprd-pcm-dma.h +2 −2
  24. sound/soc/uniphier/aio-compress.c +1 −1
include/sound/compress_driver.h+1−1
@@ -161,7 +161,7 @@ struct snd_compr_ops { · 160 unmodified lines
161 struct snd_compr_metadata *metadata);161 struct snd_compr_metadata *metadata);
162 int (*trigger)(struct snd_compr_stream *stream, int cmd);162 int (*trigger)(struct snd_compr_stream *stream, int cmd);
163 int (*pointer)(struct snd_compr_stream *stream,163 int (*pointer)(struct snd_compr_stream *stream,
164 struct snd_compr_tstamp *tstamp);164 struct snd_compr_tstamp64 *tstamp);
165 int (*copy)(struct snd_compr_stream *stream, char __user *buf,165 int (*copy)(struct snd_compr_stream *stream, char __user *buf,
166 size_t count);166 size_t count);
167 int (*mmap)(struct snd_compr_stream *stream,167 int (*mmap)(struct snd_compr_stream *stream,
include/sound/soc-component.h+2−2
@@ -47,7 +47,7 @@ struct snd_compress_ops { · 46 unmodified lines
47 struct snd_compr_stream *stream, int cmd);47 struct snd_compr_stream *stream, int cmd);
48 int (*pointer)(struct snd_soc_component *component,48 int (*pointer)(struct snd_soc_component *component,
49 struct snd_compr_stream *stream,49 struct snd_compr_stream *stream,
50 struct snd_compr_tstamp *tstamp);50 struct snd_compr_tstamp64 *tstamp);
51 int (*copy)(struct snd_soc_component *component,51 int (*copy)(struct snd_soc_component *component,
52 struct snd_compr_stream *stream, char __user *buf,52 struct snd_compr_stream *stream, char __user *buf,
53 size_t count);53 size_t count);
@@ -498,7 +498,7 @@ int snd_soc_component_compr_get_codec_caps(struct snd_compr_stream *cstream, · 444 unmodified lines
498 struct snd_compr_codec_caps *codec);498 struct snd_compr_codec_caps *codec);
499int snd_soc_component_compr_ack(struct snd_compr_stream *cstream, size_t bytes);499int snd_soc_component_compr_ack(struct snd_compr_stream *cstream, size_t bytes);
500int snd_soc_component_compr_pointer(struct snd_compr_stream *cstream,500int snd_soc_component_compr_pointer(struct snd_compr_stream *cstream,
501 struct snd_compr_tstamp *tstamp);501 struct snd_compr_tstamp64 *tstamp);
502int snd_soc_component_compr_copy(struct snd_compr_stream *cstream,502int snd_soc_component_compr_copy(struct snd_compr_stream *cstream,
503 char __user *buf, size_t count);503 char __user *buf, size_t count);
504int snd_soc_component_compr_set_metadata(struct snd_compr_stream *cstream,504int snd_soc_component_compr_set_metadata(struct snd_compr_stream *cstream,
include/sound/soc-dai.h+4−3
@@ -256,7 +256,7 @@ int snd_soc_dai_compr_ack(struct snd_soc_dai *dai, · 255 unmodified lines
256 size_t bytes);256 size_t bytes);
257int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai,257int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai,
258 struct snd_compr_stream *cstream,258 struct snd_compr_stream *cstream,
259 struct snd_compr_tstamp *tstamp);259 struct snd_compr_tstamp64 *tstamp);
260int snd_soc_dai_compr_set_metadata(struct snd_soc_dai *dai,260int snd_soc_dai_compr_set_metadata(struct snd_soc_dai *dai,
261 struct snd_compr_stream *cstream,261 struct snd_compr_stream *cstream,
262 struct snd_compr_metadata *metadata);262 struct snd_compr_metadata *metadata);
@@ -383,8 +383,9 @@ struct snd_soc_cdai_ops { · 120 unmodified lines
383 struct snd_compr_metadata *, struct snd_soc_dai *);383 struct snd_compr_metadata *, struct snd_soc_dai *);
384 int (*trigger)(struct snd_compr_stream *, int,384 int (*trigger)(struct snd_compr_stream *, int,
385 struct snd_soc_dai *);385 struct snd_soc_dai *);
386 int (*pointer)(struct snd_compr_stream *,386 int (*pointer)(struct snd_compr_stream *stream,
387 struct snd_compr_tstamp *, struct snd_soc_dai *);387 struct snd_compr_tstamp64 *tstamp,
388 struct snd_soc_dai *dai);
388 int (*ack)(struct snd_compr_stream *, size_t,389 int (*ack)(struct snd_compr_stream *, size_t,
389 struct snd_soc_dai *);390 struct snd_soc_dai *);
390};391};
include/uapi/sound/compress_offload.h+19−0
@@ -56,6 +56,25 @@ struct snd_compr_tstamp { · 55 unmodified lines
56 __u32 sampling_rate;56 __u32 sampling_rate;
57} __attribute__((packed, aligned(4)));57} __attribute__((packed, aligned(4)));
58 58
59/**
60 * struct snd_compr_tstamp64 - timestamp descriptor with fields in 64 bit
61 * @byte_offset: Byte offset in ring buffer to DSP
62 * @copied_total: Total number of bytes copied from/to ring buffer to/by DSP
63 * @pcm_frames: Frames decoded or encoded by DSP. This field will evolve by
64 * large steps and should only be used to monitor encoding/decoding
65 * progress. It shall not be used for timing estimates.
66 * @pcm_io_frames: Frames rendered or received by DSP into a mixer or an audio
67 * output/input. This field should be used for A/V sync or time estimates.
68 * @sampling_rate: sampling rate of audio
69 */
70struct snd_compr_tstamp64 {
71 __u32 byte_offset;
72 __u64 copied_total;
73 __u64 pcm_frames;
74 __u64 pcm_io_frames;
75 __u32 sampling_rate;
76} __attribute__((packed, aligned(4)));
77
59/**78/**
60 * struct snd_compr_avail - avail descriptor79 * struct snd_compr_avail - avail descriptor
61 * @avail: Number of bytes available in ring buffer for writing/reading80 * @avail: Number of bytes available in ring buffer for writing/reading
sound/core/compress_offload.c+35−17
@@ -176,14 +176,25 @@ static int snd_compr_free(struct inode *inode, struct file *f) · 175 unmodified lines
176 return 0;176 return 0;
177}177}
178 178
179static void
180snd_compr_tstamp32_from_64(struct snd_compr_tstamp *tstamp32,
181 const struct snd_compr_tstamp64 *tstamp64)
182{
183 tstamp32->byte_offset = tstamp64->byte_offset;
184 tstamp32->copied_total = (u32)tstamp64->copied_total;
185 tstamp32->pcm_frames = (u32)tstamp64->pcm_frames;
186 tstamp32->pcm_io_frames = (u32)tstamp64->pcm_io_frames;
187 tstamp32->sampling_rate = tstamp64->sampling_rate;
188}
189
179static int snd_compr_update_tstamp(struct snd_compr_stream *stream,190static int snd_compr_update_tstamp(struct snd_compr_stream *stream,
180 struct snd_compr_tstamp *tstamp)191 struct snd_compr_tstamp64 *tstamp)
181{192{
182 if (!stream->ops->pointer)193 if (!stream->ops->pointer)
183 return -ENOTSUPP;194 return -ENOTSUPP;
184 stream->ops->pointer(stream, tstamp);195 stream->ops->pointer(stream, tstamp);
185 pr_debug("dsp consumed till %d total %d bytes\n",196 pr_debug("dsp consumed till %u total %llu bytes\n", tstamp->byte_offset,
186 tstamp->byte_offset, tstamp->copied_total);197 tstamp->copied_total);
187 if (stream->direction == SND_COMPRESS_PLAYBACK)198 if (stream->direction == SND_COMPRESS_PLAYBACK)
188 stream->runtime->total_bytes_transferred = tstamp->copied_total;199 stream->runtime->total_bytes_transferred = tstamp->copied_total;
189 else200 else
@@ -194,8 +205,11 @@ static int snd_compr_update_tstamp(struct snd_compr_stream *stream, · 4 unmodified lines
194static size_t snd_compr_calc_avail(struct snd_compr_stream *stream,205static size_t snd_compr_calc_avail(struct snd_compr_stream *stream,
195 struct snd_compr_avail *avail)206 struct snd_compr_avail *avail)
196{207{
208 struct snd_compr_tstamp64 tstamp64 = { 0 };
209
197 memset(avail, 0, sizeof(*avail));210 memset(avail, 0, sizeof(*avail));
198 snd_compr_update_tstamp(stream, &avail->tstamp);211 snd_compr_update_tstamp(stream, &tstamp64);
212 snd_compr_tstamp32_from_64(&avail->tstamp, &tstamp64);
199 /* Still need to return avail even if tstamp can't be filled in */213 /* Still need to return avail even if tstamp can't be filled in */
200 214
201 if (stream->runtime->total_bytes_available == 0 &&215 if (stream->runtime->total_bytes_available == 0 &&
@@ -204,9 +218,9 @@ static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, · 2 unmodified lines
204 pr_debug("detected init and someone forgot to do a write\n");218 pr_debug("detected init and someone forgot to do a write\n");
205 return stream->runtime->buffer_size;219 return stream->runtime->buffer_size;
206 }220 }
207 pr_debug("app wrote %lld, DSP consumed %lld\n",221 pr_debug("app wrote %llu, DSP consumed %llu\n",
208 stream->runtime->total_bytes_available,222 stream->runtime->total_bytes_available,
209 stream->runtime->total_bytes_transferred);223 stream->runtime->total_bytes_transferred);
210 if (stream->runtime->total_bytes_available ==224 if (stream->runtime->total_bytes_available ==
211 stream->runtime->total_bytes_transferred) {225 stream->runtime->total_bytes_transferred) {
212 if (stream->direction == SND_COMPRESS_PLAYBACK) {226 if (stream->direction == SND_COMPRESS_PLAYBACK) {
@@ -223,7 +237,7 @@ static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, · 10 unmodified lines
223 if (stream->direction == SND_COMPRESS_PLAYBACK)237 if (stream->direction == SND_COMPRESS_PLAYBACK)
224 avail->avail = stream->runtime->buffer_size - avail->avail;238 avail->avail = stream->runtime->buffer_size - avail->avail;
225 239
226 pr_debug("ret avail as %lld\n", avail->avail);240 pr_debug("ret avail as %llu\n", avail->avail);
227 return avail->avail;241 return avail->avail;
228}242}
229 243
@@ -274,8 +288,7 @@ static int snd_compr_write_data(struct snd_compr_stream *stream, · 44 unmodified lines
274 (app_pointer * runtime->buffer_size);288 (app_pointer * runtime->buffer_size);
275 289
276 dstn = runtime->buffer + app_pointer;290 dstn = runtime->buffer + app_pointer;
277 pr_debug("copying %ld at %lld\n",291 pr_debug("copying %lu at %llu\n", (unsigned long)count, app_pointer);
278 (unsigned long)count, app_pointer);
279 if (count < runtime->buffer_size - app_pointer) {292 if (count < runtime->buffer_size - app_pointer) {
280 if (copy_from_user(dstn, buf, count))293 if (copy_from_user(dstn, buf, count))
281 return -EFAULT;294 return -EFAULT;
@@ -318,7 +331,7 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf, · 36 unmodified lines
318 }331 }
319 332
320 avail = snd_compr_get_avail(stream);333 avail = snd_compr_get_avail(stream);
321 pr_debug("avail returned %ld\n", (unsigned long)avail);334 pr_debug("avail returned %lu\n", (unsigned long)avail);
322 /* calculate how much we can write to buffer */335 /* calculate how much we can write to buffer */
323 if (avail > count)336 if (avail > count)
324 avail = count;337 avail = count;
@@ -374,7 +387,7 @@ static ssize_t snd_compr_read(struct file *f, char __user *buf, · 49 unmodified lines
374 }387 }
375 388
376 avail = snd_compr_get_avail(stream);389 avail = snd_compr_get_avail(stream);
377 pr_debug("avail returned %ld\n", (unsigned long)avail);390 pr_debug("avail returned %lu\n", (unsigned long)avail);
378 /* calculate how much we can read from buffer */391 /* calculate how much we can read from buffer */
379 if (avail > count)392 if (avail > count)
380 avail = count;393 avail = count;
@@ -443,7 +456,7 @@ static __poll_t snd_compr_poll(struct file *f, poll_table *wait) · 62 unmodified lines
443#endif456#endif
444 457
445 avail = snd_compr_get_avail(stream);458 avail = snd_compr_get_avail(stream);
446 pr_debug("avail is %ld\n", (unsigned long)avail);459 pr_debug("avail is %lu\n", (unsigned long)avail);
447 /* check if we have at least one fragment to fill */460 /* check if we have at least one fragment to fill */
448 switch (runtime->state) {461 switch (runtime->state) {
449 case SNDRV_PCM_STATE_DRAINING:462 case SNDRV_PCM_STATE_DRAINING:
@@ -726,13 +739,18 @@ snd_compr_set_metadata(struct snd_compr_stream *stream, unsigned long arg) · 276 unmodified lines
726static inline int739static inline int
727snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg)740snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg)
728{741{
729 struct snd_compr_tstamp tstamp = {0};742 struct snd_compr_tstamp64 tstamp64 = { 0 };
743 struct snd_compr_tstamp tstamp32 = { 0 };
730 int ret;744 int ret;
731 745
732 ret = snd_compr_update_tstamp(stream, &tstamp);746 ret = snd_compr_update_tstamp(stream, &tstamp64);
733 if (ret == 0)747 if (ret == 0) {
748 snd_compr_tstamp32_from_64(&tstamp32, &tstamp64);
734 ret = copy_to_user((struct snd_compr_tstamp __user *)arg,749 ret = copy_to_user((struct snd_compr_tstamp __user *)arg,
735 &tstamp, sizeof(tstamp)) ? -EFAULT : 0;750 &tstamp32, sizeof(tstamp32)) ?
751 -EFAULT :
752 0;
753 }
736 return ret;754 return ret;
737}755}
738 756
sound/soc/codecs/wm_adsp.c+2−2
@@ -173,7 +173,7 @@ struct wm_adsp_compr { · 172 unmodified lines
173 struct snd_compressed_buffer size;173 struct snd_compressed_buffer size;
174 174
175 u32 *raw_buf;175 u32 *raw_buf;
176 unsigned int copied_total;176 u64 copied_total;
177 177
178 unsigned int sample_rate;178 unsigned int sample_rate;
179 179
@@ -1860,7 +1860,7 @@ static int wm_adsp_buffer_reenable_irq(struct wm_adsp_compr_buf *buf) · 1680 unmodified lines
1860 1860
1861int wm_adsp_compr_pointer(struct snd_soc_component *component,1861int wm_adsp_compr_pointer(struct snd_soc_component *component,
1862 struct snd_compr_stream *stream,1862 struct snd_compr_stream *stream,
1863 struct snd_compr_tstamp *tstamp)1863 struct snd_compr_tstamp64 *tstamp)
1864{1864{
1865 struct wm_adsp_compr *compr = stream->runtime->private_data;1865 struct wm_adsp_compr *compr = stream->runtime->private_data;
1866 struct wm_adsp *dsp = compr->dsp;1866 struct wm_adsp *dsp = compr->dsp;
sound/soc/codecs/wm_adsp.h+1−1
@@ -131,7 +131,7 @@ int wm_adsp_compr_trigger(struct snd_soc_component *component, · 130 unmodified lines
131int wm_adsp_compr_handle_irq(struct wm_adsp *dsp);131int wm_adsp_compr_handle_irq(struct wm_adsp *dsp);
132int wm_adsp_compr_pointer(struct snd_soc_component *component,132int wm_adsp_compr_pointer(struct snd_soc_component *component,
133 struct snd_compr_stream *stream,133 struct snd_compr_stream *stream,
134 struct snd_compr_tstamp *tstamp);134 struct snd_compr_tstamp64 *tstamp);
135int wm_adsp_compr_copy(struct snd_soc_component *component,135int wm_adsp_compr_copy(struct snd_soc_component *component,
136 struct snd_compr_stream *stream,136 struct snd_compr_stream *stream,
137 char __user *buf, size_t count);137 char __user *buf, size_t count);
sound/soc/intel/atom/sst-mfld-platform-compress.c+7−5
@@ -18,6 +18,7 @@ · 17 unmodified lines
18#include <sound/pcm_params.h>18#include <sound/pcm_params.h>
19#include <sound/soc.h>19#include <sound/soc.h>
20#include <sound/compress_driver.h>20#include <sound/compress_driver.h>
21#include <asm/div64.h>
21#include "sst-mfld-platform.h"22#include "sst-mfld-platform.h"
22 23
23/* compress stream operations */24/* compress stream operations */
@@ -202,15 +203,16 @@ static int sst_platform_compr_trigger(struct snd_soc_component *component, · 178 unmodified lines
202 203
203static int sst_platform_compr_pointer(struct snd_soc_component *component,204static int sst_platform_compr_pointer(struct snd_soc_component *component,
204 struct snd_compr_stream *cstream,205 struct snd_compr_stream *cstream,
205 struct snd_compr_tstamp *tstamp)206 struct snd_compr_tstamp64 *tstamp)
206{207{
207 struct sst_runtime_stream *stream;208 struct sst_runtime_stream *stream;
209 u64 temp_copied_total = tstamp->copied_total;
208 210
209 stream = cstream->runtime->private_data;211 stream = cstream->runtime->private_data;
210 stream->compr_ops->tstamp(sst->dev, stream->id, tstamp);212 stream->compr_ops->tstamp(sst->dev, stream->id, tstamp);
211 tstamp->byte_offset = tstamp->copied_total %213 tstamp->byte_offset =
212 (u32)cstream->runtime->buffer_size;214 do_div(temp_copied_total, cstream->runtime->buffer_size);
213 pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset);215 pr_debug("calc bytes offset/copied bytes as %u\n", tstamp->byte_offset);
214 return 0;216 return 0;
215}217}
216 218
sound/soc/intel/atom/sst-mfld-platform.h+1−1
@@ -105,7 +105,7 @@ struct compress_sst_ops { · 104 unmodified lines
105 int (*stream_pause_release)(struct device *dev, unsigned int str_id);105 int (*stream_pause_release)(struct device *dev, unsigned int str_id);
106 106
107 int (*tstamp)(struct device *dev, unsigned int str_id,107 int (*tstamp)(struct device *dev, unsigned int str_id,
108 struct snd_compr_tstamp *tstamp);108 struct snd_compr_tstamp64 *tstamp);
109 int (*ack)(struct device *dev, unsigned int str_id,109 int (*ack)(struct device *dev, unsigned int str_id,
110 unsigned long bytes);110 unsigned long bytes);
111 int (*close)(struct device *dev, unsigned int str_id);111 int (*close)(struct device *dev, unsigned int str_id);
sound/soc/intel/atom/sst/sst_drv_interface.c+5−4
@@ -326,7 +326,7 @@ static int sst_cdev_stream_partial_drain(struct device *dev, · 325 unmodified lines
326}326}
327 327
328static int sst_cdev_tstamp(struct device *dev, unsigned int str_id,328static int sst_cdev_tstamp(struct device *dev, unsigned int str_id,
329 struct snd_compr_tstamp *tstamp)329 struct snd_compr_tstamp64 *tstamp)
330{330{
331 struct snd_sst_tstamp fw_tstamp = {0,};331 struct snd_sst_tstamp fw_tstamp = {0,};
332 struct stream_info *stream;332 struct stream_info *stream;
@@ -349,10 +349,11 @@ static int sst_cdev_tstamp(struct device *dev, unsigned int str_id, · 16 unmodified lines
349 (u64)stream->num_ch * SST_GET_BYTES_PER_SAMPLE(24));349 (u64)stream->num_ch * SST_GET_BYTES_PER_SAMPLE(24));
350 tstamp->sampling_rate = fw_tstamp.sampling_frequency;350 tstamp->sampling_rate = fw_tstamp.sampling_frequency;
351 351
352 dev_dbg(dev, "PCM = %u\n", tstamp->pcm_io_frames);352 dev_dbg(dev, "PCM = %llu\n", tstamp->pcm_io_frames);
353 dev_dbg(dev, "Ptr Query on strid = %d copied_total %d, decodec %d\n",353 dev_dbg(dev,
354 "Ptr Query on strid = %d copied_total %llu, decodec %llu\n",
354 str_id, tstamp->copied_total, tstamp->pcm_frames);355 str_id, tstamp->copied_total, tstamp->pcm_frames);
355 dev_dbg(dev, "rendered %d\n", tstamp->pcm_io_frames);356 dev_dbg(dev, "rendered %llu\n", tstamp->pcm_io_frames);
356 357
357 return 0;358 return 0;
358}359}
sound/soc/intel/avs/probes.c+1−1
@@ -213,7 +213,7 @@ static int avs_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd, · 212 unmodified lines
213}213}
214 214
215static int avs_probe_compr_pointer(struct snd_compr_stream *cstream,215static int avs_probe_compr_pointer(struct snd_compr_stream *cstream,
216 struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai)216 struct snd_compr_tstamp64 *tstamp, struct snd_soc_dai *dai)
217{217{
218 struct hdac_ext_stream *host_stream = avs_compr_get_host_stream(cstream);218 struct hdac_ext_stream *host_stream = avs_compr_get_host_stream(cstream);
219 struct snd_soc_pcm_stream *pstream;219 struct snd_soc_pcm_stream *pstream;
sound/soc/qcom/qdsp6/q6apm-dai.c+16−10
@@ -11,6 +11,7 @@ · 10 unmodified lines
11#include <sound/soc-dapm.h>11#include <sound/soc-dapm.h>
12#include <linux/spinlock.h>12#include <linux/spinlock.h>
13#include <sound/pcm.h>13#include <sound/pcm.h>
14#include <asm/div64.h>
14#include <asm/dma.h>15#include <asm/dma.h>
15#include <linux/dma-mapping.h>16#include <linux/dma-mapping.h>
16#include <sound/pcm_params.h>17#include <sound/pcm_params.h>
@@ -65,9 +66,9 @@ struct q6apm_dai_rtd { · 48 unmodified lines
65 unsigned int pcm_size;66 unsigned int pcm_size;
66 unsigned int pcm_count;67 unsigned int pcm_count;
67 unsigned int periods;68 unsigned int periods;
68 unsigned int bytes_sent;69 uint64_t bytes_sent;
69 unsigned int bytes_received;70 uint64_t bytes_received;
70 unsigned int copied_total;71 uint64_t copied_total;
71 uint16_t bits_per_sample;72 uint16_t bits_per_sample;
72 snd_pcm_uframes_t queue_ptr;73 snd_pcm_uframes_t queue_ptr;
73 bool next_track;74 bool next_track;
@@ -575,15 +576,17 @@ static int q6apm_dai_compr_get_codec_caps(struct snd_soc_component *component, · 501 unmodified lines
575 576
576static int q6apm_dai_compr_pointer(struct snd_soc_component *component,577static int q6apm_dai_compr_pointer(struct snd_soc_component *component,
577 struct snd_compr_stream *stream,578 struct snd_compr_stream *stream,
578 struct snd_compr_tstamp *tstamp)579 struct snd_compr_tstamp64 *tstamp)
579{580{
580 struct snd_compr_runtime *runtime = stream->runtime;581 struct snd_compr_runtime *runtime = stream->runtime;
581 struct q6apm_dai_rtd *prtd = runtime->private_data;582 struct q6apm_dai_rtd *prtd = runtime->private_data;
582 unsigned long flags;583 unsigned long flags;
584 uint64_t temp_copied_total;
583 585
584 spin_lock_irqsave(&prtd->lock, flags);586 spin_lock_irqsave(&prtd->lock, flags);
585 tstamp->copied_total = prtd->copied_total;587 tstamp->copied_total = prtd->copied_total;
586 tstamp->byte_offset = prtd->copied_total % prtd->pcm_size;588 temp_copied_total = tstamp->copied_total;
589 tstamp->byte_offset = do_div(temp_copied_total, prtd->pcm_size);
587 spin_unlock_irqrestore(&prtd->lock, flags);590 spin_unlock_irqrestore(&prtd->lock, flags);
588 591
589 return 0;592 return 0;
@@ -760,21 +763,24 @@ static int q6apm_compr_copy(struct snd_soc_component *component, · 170 unmodified lines
760 size_t copy;763 size_t copy;
761 u32 wflags = 0;764 u32 wflags = 0;
762 u32 app_pointer;765 u32 app_pointer;
763 u32 bytes_received;766 uint64_t bytes_received;
767 uint64_t temp_bytes_received;
764 uint32_t bytes_to_write;768 uint32_t bytes_to_write;
765 int avail, bytes_in_flight = 0;769 uint64_t avail, bytes_in_flight = 0;
766 770
767 bytes_received = prtd->bytes_received;771 bytes_received = prtd->bytes_received;
772 temp_bytes_received = bytes_received;
768 773
769 /**774 /**
770 * Make sure that next track data pointer is aligned at 32 bit boundary775 * Make sure that next track data pointer is aligned at 32 bit boundary
771 * This is a Mandatory requirement from DSP data buffers alignment776 * This is a Mandatory requirement from DSP data buffers alignment
772 */777 */
773 if (prtd->next_track)778 if (prtd->next_track) {
774 bytes_received = ALIGN(prtd->bytes_received, prtd->pcm_count);779 bytes_received = ALIGN(prtd->bytes_received, prtd->pcm_count);
780 temp_bytes_received = bytes_received;
781 }
775 782
776 app_pointer = bytes_received/prtd->pcm_size;783 app_pointer = do_div(temp_bytes_received, prtd->pcm_size);
777 app_pointer = bytes_received - (app_pointer * prtd->pcm_size);
778 dstn = prtd->dma_buffer.area + app_pointer;784 dstn = prtd->dma_buffer.area + app_pointer;
779 785
780 if (count < prtd->pcm_size - app_pointer) {786 if (count < prtd->pcm_size - app_pointer) {
sound/soc/qcom/qdsp6/q6asm-dai.c+16−10
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#include <sound/pcm.h>14#include <sound/pcm.h>
15#include <linux/spinlock.h>15#include <linux/spinlock.h>
16#include <sound/compress_driver.h>16#include <sound/compress_driver.h>
17#include <asm/div64.h>
17#include <asm/dma.h>18#include <asm/dma.h>
18#include <linux/dma-mapping.h>19#include <linux/dma-mapping.h>
19#include <sound/pcm_params.h>20#include <sound/pcm_params.h>
@@ -59,9 +60,9 @@ struct q6asm_dai_rtd { · 39 unmodified lines
59 unsigned int pcm_count;60 unsigned int pcm_count;
60 unsigned int pcm_irq_pos; /* IRQ position */61 unsigned int pcm_irq_pos; /* IRQ position */
61 unsigned int periods;62 unsigned int periods;
62 unsigned int bytes_sent;63 uint64_t bytes_sent;
63 unsigned int bytes_received;64 uint64_t bytes_received;
64 unsigned int copied_total;65 uint64_t copied_total;
65 uint16_t bits_per_sample;66 uint16_t bits_per_sample;
66 uint16_t source; /* Encoding source bit mask */67 uint16_t source; /* Encoding source bit mask */
67 struct audio_client *audio_client;68 struct audio_client *audio_client;
@@ -1026,16 +1027,18 @@ static int q6asm_dai_compr_trigger(struct snd_soc_component *component, · 958 unmodified lines
1026 1027
1027static int q6asm_dai_compr_pointer(struct snd_soc_component *component,1028static int q6asm_dai_compr_pointer(struct snd_soc_component *component,
1028 struct snd_compr_stream *stream,1029 struct snd_compr_stream *stream,
1029 struct snd_compr_tstamp *tstamp)1030 struct snd_compr_tstamp64 *tstamp)
1030{1031{
1031 struct snd_compr_runtime *runtime = stream->runtime;1032 struct snd_compr_runtime *runtime = stream->runtime;
1032 struct q6asm_dai_rtd *prtd = runtime->private_data;1033 struct q6asm_dai_rtd *prtd = runtime->private_data;
1033 unsigned long flags;1034 unsigned long flags;
1035 uint64_t temp_copied_total;
1034 1036
1035 spin_lock_irqsave(&prtd->lock, flags);1037 spin_lock_irqsave(&prtd->lock, flags);
1036 1038
1037 tstamp->copied_total = prtd->copied_total;1039 tstamp->copied_total = prtd->copied_total;
1038 tstamp->byte_offset = prtd->copied_total % prtd->pcm_size;1040 temp_copied_total = tstamp->copied_total;
1041 tstamp->byte_offset = do_div(temp_copied_total, prtd->pcm_size);
1039 1042
1040 spin_unlock_irqrestore(&prtd->lock, flags);1043 spin_unlock_irqrestore(&prtd->lock, flags);
1041 1044
@@ -1050,23 +1053,26 @@ static int q6asm_compr_copy(struct snd_soc_component *component, · 8 unmodified lines
1050 struct q6asm_dai_rtd *prtd = runtime->private_data;1053 struct q6asm_dai_rtd *prtd = runtime->private_data;
1051 unsigned long flags;1054 unsigned long flags;
1052 u32 wflags = 0;1055 u32 wflags = 0;
1053 int avail, bytes_in_flight = 0;1056 uint64_t avail, bytes_in_flight = 0;
1054 void *dstn;1057 void *dstn;
1055 size_t copy;1058 size_t copy;
1056 u32 app_pointer;1059 u32 app_pointer;
1057 u32 bytes_received;1060 uint64_t bytes_received;
1061 uint64_t temp_bytes_received;
1058 1062
1059 bytes_received = prtd->bytes_received;1063 bytes_received = prtd->bytes_received;
1064 temp_bytes_received = bytes_received;
1060 1065
1061 /**1066 /**
1062 * Make sure that next track data pointer is aligned at 32 bit boundary1067 * Make sure that next track data pointer is aligned at 32 bit boundary
1063 * This is a Mandatory requirement from DSP data buffers alignment1068 * This is a Mandatory requirement from DSP data buffers alignment
1064 */1069 */
1065 if (prtd->next_track)1070 if (prtd->next_track) {
1066 bytes_received = ALIGN(prtd->bytes_received, prtd->pcm_count);1071 bytes_received = ALIGN(prtd->bytes_received, prtd->pcm_count);
1072 temp_bytes_received = bytes_received;
1073 }
1067 1074
1068 app_pointer = bytes_received/prtd->pcm_size;1075 app_pointer = do_div(temp_bytes_received, prtd->pcm_size);
1069 app_pointer = bytes_received - (app_pointer * prtd->pcm_size);
1070 dstn = prtd->dma_buffer.area + app_pointer;1076 dstn = prtd->dma_buffer.area + app_pointer;
1071 1077
1072 if (count < prtd->pcm_size - app_pointer) {1078 if (count < prtd->pcm_size - app_pointer) {
sound/soc/soc-component.c+1−1
@@ -637,7 +637,7 @@ int snd_soc_component_compr_ack(struct snd_compr_stream *cstream, size_t bytes) · 636 unmodified lines
637EXPORT_SYMBOL_GPL(snd_soc_component_compr_ack);637EXPORT_SYMBOL_GPL(snd_soc_component_compr_ack);
638 638
639int snd_soc_component_compr_pointer(struct snd_compr_stream *cstream,639int snd_soc_component_compr_pointer(struct snd_compr_stream *cstream,
640 struct snd_compr_tstamp *tstamp)640 struct snd_compr_tstamp64 *tstamp)
641{641{
642 struct snd_soc_pcm_runtime *rtd = cstream->private_data;642 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
643 struct snd_soc_component *component;643 struct snd_soc_component *component;
sound/soc/soc-compress.c+1−1
@@ -457,7 +457,7 @@ err: · 456 unmodified lines
457}457}
458 458
459static int soc_compr_pointer(struct snd_compr_stream *cstream,459static int soc_compr_pointer(struct snd_compr_stream *cstream,
460 struct snd_compr_tstamp *tstamp)460 struct snd_compr_tstamp64 *tstamp)
461{461{
462 struct snd_soc_pcm_runtime *rtd = cstream->private_data;462 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
463 int ret;463 int ret;
sound/soc/soc-dai.c+1−1
@@ -774,7 +774,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_compr_ack); · 773 unmodified lines
774 774
775int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai,775int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai,
776 struct snd_compr_stream *cstream,776 struct snd_compr_stream *cstream,
777 struct snd_compr_tstamp *tstamp)777 struct snd_compr_tstamp64 *tstamp)
778{778{
779 int ret = 0;779 int ret = 0;
780 780
sound/soc/sof/amd/acp-probes.c+1−1
@@ -108,7 +108,7 @@ static int acp_probes_compr_trigger(struct sof_client_dev *cdev, · 107 unmodified lines
108 108
109static int acp_probes_compr_pointer(struct sof_client_dev *cdev,109static int acp_probes_compr_pointer(struct sof_client_dev *cdev,
110 struct snd_compr_stream *cstream,110 struct snd_compr_stream *cstream,
111 struct snd_compr_tstamp *tstamp,111 struct snd_compr_tstamp64 *tstamp,
112 struct snd_soc_dai *dai)112 struct snd_soc_dai *dai)
113{113{
114 struct acp_dsp_stream *stream = cstream->runtime->private_data;114 struct acp_dsp_stream *stream = cstream->runtime->private_data;
sound/soc/sof/compress.c+1−1
@@ -361,7 +361,7 @@ static int sof_compr_copy(struct snd_soc_component *component, · 360 unmodified lines
361 361
362static int sof_compr_pointer(struct snd_soc_component *component,362static int sof_compr_pointer(struct snd_soc_component *component,
363 struct snd_compr_stream *cstream,363 struct snd_compr_stream *cstream,
364 struct snd_compr_tstamp *tstamp)364 struct snd_compr_tstamp64 *tstamp)
365{365{
366 struct snd_sof_pcm *spcm;366 struct snd_sof_pcm *spcm;
367 struct snd_soc_pcm_runtime *rtd = cstream->private_data;367 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
sound/soc/sof/intel/hda-probes.c+1−1
@@ -112,7 +112,7 @@ static int hda_probes_compr_trigger(struct sof_client_dev *cdev, · 111 unmodified lines
112 112
113static int hda_probes_compr_pointer(struct sof_client_dev *cdev,113static int hda_probes_compr_pointer(struct sof_client_dev *cdev,
114 struct snd_compr_stream *cstream,114 struct snd_compr_stream *cstream,
115 struct snd_compr_tstamp *tstamp,115 struct snd_compr_tstamp64 *tstamp,
116 struct snd_soc_dai *dai)116 struct snd_soc_dai *dai)
117{117{
118 struct hdac_ext_stream *hext_stream = hda_compr_get_stream(cstream);118 struct hdac_ext_stream *hext_stream = hda_compr_get_stream(cstream);
sound/soc/sof/sof-client-probes.c+1−1
@@ -137,7 +137,7 @@ static int sof_probes_compr_trigger(struct snd_compr_stream *cstream, int cmd, · 136 unmodified lines
137}137}
138 138
139static int sof_probes_compr_pointer(struct snd_compr_stream *cstream,139static int sof_probes_compr_pointer(struct snd_compr_stream *cstream,
140 struct snd_compr_tstamp *tstamp,140 struct snd_compr_tstamp64 *tstamp,
141 struct snd_soc_dai *dai)141 struct snd_soc_dai *dai)
142{142{
143 struct snd_soc_card *card = snd_soc_component_get_drvdata(dai->component);143 struct snd_soc_card *card = snd_soc_component_get_drvdata(dai->component);
sound/soc/sof/sof-client-probes.h+2−2
@@ -4,7 +4,7 @@ · 3 unmodified lines
4#define __SOF_CLIENT_PROBES_H4#define __SOF_CLIENT_PROBES_H
5 5
6struct snd_compr_stream;6struct snd_compr_stream;
7struct snd_compr_tstamp;7struct snd_compr_tstamp64;
8struct snd_compr_params;8struct snd_compr_params;
9struct sof_client_dev;9struct sof_client_dev;
10struct snd_soc_dai;10struct snd_soc_dai;
@@ -24,7 +24,7 @@ struct sof_probes_host_ops { · 13 unmodified lines
24 int (*trigger)(struct sof_client_dev *cdev, struct snd_compr_stream *cstream,24 int (*trigger)(struct sof_client_dev *cdev, struct snd_compr_stream *cstream,
25 int cmd, struct snd_soc_dai *dai);25 int cmd, struct snd_soc_dai *dai);
26 int (*pointer)(struct sof_client_dev *cdev, struct snd_compr_stream *cstream,26 int (*pointer)(struct sof_client_dev *cdev, struct snd_compr_stream *cstream,
27 struct snd_compr_tstamp *tstamp,27 struct snd_compr_tstamp64 *tstamp,
28 struct snd_soc_dai *dai);28 struct snd_soc_dai *dai);
29};29};
30 30
sound/soc/sprd/sprd-pcm-compress.c+3−3
@@ -85,9 +85,9 @@ struct sprd_compr_stream { · 84 unmodified lines
85 int info_size;85 int info_size;
86 86
87 /* Data size copied to IRAM buffer */87 /* Data size copied to IRAM buffer */
88 int copied_total;88 u64 copied_total;
89 /* Total received data size from userspace */89 /* Total received data size from userspace */
90 int received_total;90 u64 received_total;
91 /* Stage 0 IRAM buffer received data size */91 /* Stage 0 IRAM buffer received data size */
92 int received_stage0;92 int received_stage0;
93 /* Stage 1 DDR buffer received data size */93 /* Stage 1 DDR buffer received data size */
@@ -513,7 +513,7 @@ static int sprd_platform_compr_trigger(struct snd_soc_component *component, · 419 unmodified lines
513 513
514static int sprd_platform_compr_pointer(struct snd_soc_component *component,514static int sprd_platform_compr_pointer(struct snd_soc_component *component,
515 struct snd_compr_stream *cstream,515 struct snd_compr_stream *cstream,
516 struct snd_compr_tstamp *tstamp)516 struct snd_compr_tstamp64 *tstamp)
517{517{
518 struct snd_compr_runtime *runtime = cstream->runtime;518 struct snd_compr_runtime *runtime = cstream->runtime;
519 struct sprd_compr_stream *stream = runtime->private_data;519 struct sprd_compr_stream *stream = runtime->private_data;
sound/soc/sprd/sprd-pcm-dma.h+2−2
@@ -19,7 +19,7 @@ struct sprd_compr_playinfo { · 18 unmodified lines
19 int total_time;19 int total_time;
20 int current_time;20 int current_time;
21 int total_data_length;21 int total_data_length;
22 int current_data_offset;22 u64 current_data_offset;
23};23};
24 24
25struct sprd_compr_params {25struct sprd_compr_params {
@@ -46,7 +46,7 @@ struct sprd_compr_ops { · 20 unmodified lines
46 int (*stop)(int str_id);46 int (*stop)(int str_id);
47 int (*pause)(int str_id);47 int (*pause)(int str_id);
48 int (*pause_release)(int str_id);48 int (*pause_release)(int str_id);
49 int (*drain)(int received_total);49 int (*drain)(u64 received_total);
50 int (*set_params)(int str_id, struct sprd_compr_params *params);50 int (*set_params)(int str_id, struct sprd_compr_params *params);
51};51};
52 52
sound/soc/uniphier/aio-compress.c+1−1
@@ -249,7 +249,7 @@ static int uniphier_aio_compr_trigger(struct snd_soc_component *component, · 248 unmodified lines
249 249
250static int uniphier_aio_compr_pointer(struct snd_soc_component *component,250static int uniphier_aio_compr_pointer(struct snd_soc_component *component,
251 struct snd_compr_stream *cstream,251 struct snd_compr_stream *cstream,
252 struct snd_compr_tstamp *tstamp)252 struct snd_compr_tstamp64 *tstamp)
253{253{
254 struct snd_soc_pcm_runtime *rtd = cstream->private_data;254 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
255 struct snd_compr_runtime *runtime = cstream->runtime;255 struct snd_compr_runtime *runtime = cstream->runtime;