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
161161 struct snd_compr_metadata *metadata);
162162 int (*trigger)(struct snd_compr_stream *stream, int cmd);
163163 int (*pointer)(struct snd_compr_stream *stream,
164− struct snd_compr_tstamp *tstamp);
164+ struct snd_compr_tstamp64 *tstamp);
165165 int (*copy)(struct snd_compr_stream *stream, char __user *buf,
166166 size_t count);
167167 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
4747 struct snd_compr_stream *stream, int cmd);
4848 int (*pointer)(struct snd_soc_component *component,
4949 struct snd_compr_stream *stream,
50− struct snd_compr_tstamp *tstamp);
50+ struct snd_compr_tstamp64 *tstamp);
5151 int (*copy)(struct snd_soc_component *component,
5252 struct snd_compr_stream *stream, char __user *buf,
5353 size_t count);
@@ -498,7 +498,7 @@ int snd_soc_component_compr_get_codec_caps(struct snd_compr_stream *cstream, · 444 unmodified lines
498498 struct snd_compr_codec_caps *codec);
499499 int snd_soc_component_compr_ack(struct snd_compr_stream *cstream, size_t bytes);
500500 int snd_soc_component_compr_pointer(struct snd_compr_stream *cstream,
501− struct snd_compr_tstamp *tstamp);
501+ struct snd_compr_tstamp64 *tstamp);
502502 int snd_soc_component_compr_copy(struct snd_compr_stream *cstream,
503503 char __user *buf, size_t count);
504504 int 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
256256 size_t bytes);
257257 int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai,
258258 struct snd_compr_stream *cstream,
259− struct snd_compr_tstamp *tstamp);
259+ struct snd_compr_tstamp64 *tstamp);
260260 int snd_soc_dai_compr_set_metadata(struct snd_soc_dai *dai,
261261 struct snd_compr_stream *cstream,
262262 struct snd_compr_metadata *metadata);
@@ -383,8 +383,9 @@ struct snd_soc_cdai_ops { · 120 unmodified lines
383383 struct snd_compr_metadata *, struct snd_soc_dai *);
384384 int (*trigger)(struct snd_compr_stream *, int,
385385 struct snd_soc_dai *);
386− int (*pointer)(struct snd_compr_stream *,
387− struct snd_compr_tstamp *, struct snd_soc_dai *);
386+ int (*pointer)(struct snd_compr_stream *stream,
387+ struct snd_compr_tstamp64 *tstamp,
388+ struct snd_soc_dai *dai);
388389 int (*ack)(struct snd_compr_stream *, size_t,
389390 struct snd_soc_dai *);
390391 };
include/uapi/sound/compress_offload.h+19−0
@@ -56,6 +56,25 @@ struct snd_compr_tstamp { · 55 unmodified lines
5656 __u32 sampling_rate;
5757 } __attribute__((packed, aligned(4)));
5858
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+ */
70+struct 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+
5978 /**
6079 * struct snd_compr_avail - avail descriptor
6180 * @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
176176 return 0;
177177 }
178178
179+static void
180+snd_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+
179190 static int snd_compr_update_tstamp(struct snd_compr_stream *stream,
180− struct snd_compr_tstamp *tstamp)
191+ struct snd_compr_tstamp64 *tstamp)
181192 {
182193 if (!stream->ops->pointer)
183194 return -ENOTSUPP;
184195 stream->ops->pointer(stream, tstamp);
185− pr_debug("dsp consumed till %d total %d bytes\n",
186− tstamp->byte_offset, tstamp->copied_total);
196+ pr_debug("dsp consumed till %u total %llu bytes\n", tstamp->byte_offset,
197+ tstamp->copied_total);
187198 if (stream->direction == SND_COMPRESS_PLAYBACK)
188199 stream->runtime->total_bytes_transferred = tstamp->copied_total;
189200 else
@@ -194,8 +205,11 @@ static int snd_compr_update_tstamp(struct snd_compr_stream *stream, · 4 unmodified lines
194205 static size_t snd_compr_calc_avail(struct snd_compr_stream *stream,
195206 struct snd_compr_avail *avail)
196207 {
208+ struct snd_compr_tstamp64 tstamp64 = { 0 };
209+
197210 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);
199213 /* Still need to return avail even if tstamp can't be filled in */
200214
201215 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
204218 pr_debug("detected init and someone forgot to do a write\n");
205219 return stream->runtime->buffer_size;
206220 }
207− pr_debug("app wrote %lld, DSP consumed %lld\n",
208− stream->runtime->total_bytes_available,
209− stream->runtime->total_bytes_transferred);
221+ pr_debug("app wrote %llu, DSP consumed %llu\n",
222+ stream->runtime->total_bytes_available,
223+ stream->runtime->total_bytes_transferred);
210224 if (stream->runtime->total_bytes_available ==
211225 stream->runtime->total_bytes_transferred) {
212226 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
223237 if (stream->direction == SND_COMPRESS_PLAYBACK)
224238 avail->avail = stream->runtime->buffer_size - avail->avail;
225239
226− pr_debug("ret avail as %lld\n", avail->avail);
240+ pr_debug("ret avail as %llu\n", avail->avail);
227241 return avail->avail;
228242 }
229243
@@ -274,8 +288,7 @@ static int snd_compr_write_data(struct snd_compr_stream *stream, · 44 unmodified lines
274288 (app_pointer * runtime->buffer_size);
275289
276290 dstn = runtime->buffer + app_pointer;
277− pr_debug("copying %ld at %lld\n",
278− (unsigned long)count, app_pointer);
291+ pr_debug("copying %lu at %llu\n", (unsigned long)count, app_pointer);
279292 if (count < runtime->buffer_size - app_pointer) {
280293 if (copy_from_user(dstn, buf, count))
281294 return -EFAULT;
@@ -318,7 +331,7 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf, · 36 unmodified lines
318331 }
319332
320333 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);
322335 /* calculate how much we can write to buffer */
323336 if (avail > count)
324337 avail = count;
@@ -374,7 +387,7 @@ static ssize_t snd_compr_read(struct file *f, char __user *buf, · 49 unmodified lines
374387 }
375388
376389 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);
378391 /* calculate how much we can read from buffer */
379392 if (avail > count)
380393 avail = count;
@@ -443,7 +456,7 @@ static __poll_t snd_compr_poll(struct file *f, poll_table *wait) · 62 unmodified lines
443456 #endif
444457
445458 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);
447460 /* check if we have at least one fragment to fill */
448461 switch (runtime->state) {
449462 case SNDRV_PCM_STATE_DRAINING:
@@ -726,13 +739,18 @@ snd_compr_set_metadata(struct snd_compr_stream *stream, unsigned long arg) · 276 unmodified lines
726739 static inline int
727740 snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg)
728741 {
729− struct snd_compr_tstamp tstamp = {0};
742+ struct snd_compr_tstamp64 tstamp64 = { 0 };
743+ struct snd_compr_tstamp tstamp32 = { 0 };
730744 int ret;
731745
732− ret = snd_compr_update_tstamp(stream, &tstamp);
733− if (ret == 0)
746+ ret = snd_compr_update_tstamp(stream, &tstamp64);
747+ if (ret == 0) {
748+ snd_compr_tstamp32_from_64(&tstamp32, &tstamp64);
734749 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+ }
736754 return ret;
737755 }
738756
sound/soc/codecs/wm_adsp.c+2−2
@@ -173,7 +173,7 @@ struct wm_adsp_compr { · 172 unmodified lines
173173 struct snd_compressed_buffer size;
174174
175175 u32 *raw_buf;
176− unsigned int copied_total;
176+ u64 copied_total;
177177
178178 unsigned int sample_rate;
179179
@@ -1860,7 +1860,7 @@ static int wm_adsp_buffer_reenable_irq(struct wm_adsp_compr_buf *buf) · 1680 unmodified lines
18601860
18611861 int wm_adsp_compr_pointer(struct snd_soc_component *component,
18621862 struct snd_compr_stream *stream,
1863− struct snd_compr_tstamp *tstamp)
1863+ struct snd_compr_tstamp64 *tstamp)
18641864 {
18651865 struct wm_adsp_compr *compr = stream->runtime->private_data;
18661866 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
131131 int wm_adsp_compr_handle_irq(struct wm_adsp *dsp);
132132 int wm_adsp_compr_pointer(struct snd_soc_component *component,
133133 struct snd_compr_stream *stream,
134− struct snd_compr_tstamp *tstamp);
134+ struct snd_compr_tstamp64 *tstamp);
135135 int wm_adsp_compr_copy(struct snd_soc_component *component,
136136 struct snd_compr_stream *stream,
137137 char __user *buf, size_t count);
sound/soc/intel/atom/sst-mfld-platform-compress.c+7−5
@@ -18,6 +18,7 @@ · 17 unmodified lines
1818 #include <sound/pcm_params.h>
1919 #include <sound/soc.h>
2020 #include <sound/compress_driver.h>
21+#include <asm/div64.h>
2122 #include "sst-mfld-platform.h"
2223
2324 /* compress stream operations */
@@ -202,15 +203,16 @@ static int sst_platform_compr_trigger(struct snd_soc_component *component, · 178 unmodified lines
202203
203204 static int sst_platform_compr_pointer(struct snd_soc_component *component,
204205 struct snd_compr_stream *cstream,
205− struct snd_compr_tstamp *tstamp)
206+ struct snd_compr_tstamp64 *tstamp)
206207 {
207208 struct sst_runtime_stream *stream;
209+ u64 temp_copied_total = tstamp->copied_total;
208210
209− stream = cstream->runtime->private_data;
211+ stream = cstream->runtime->private_data;
210212 stream->compr_ops->tstamp(sst->dev, stream->id, tstamp);
211− tstamp->byte_offset = tstamp->copied_total %
212− (u32)cstream->runtime->buffer_size;
213− pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset);
213+ tstamp->byte_offset =
214+ do_div(temp_copied_total, cstream->runtime->buffer_size);
215+ pr_debug("calc bytes offset/copied bytes as %u\n", tstamp->byte_offset);
214216 return 0;
215217 }
216218
sound/soc/intel/atom/sst-mfld-platform.h+1−1
@@ -105,7 +105,7 @@ struct compress_sst_ops { · 104 unmodified lines
105105 int (*stream_pause_release)(struct device *dev, unsigned int str_id);
106106
107107 int (*tstamp)(struct device *dev, unsigned int str_id,
108− struct snd_compr_tstamp *tstamp);
108+ struct snd_compr_tstamp64 *tstamp);
109109 int (*ack)(struct device *dev, unsigned int str_id,
110110 unsigned long bytes);
111111 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
326326 }
327327
328328 static int sst_cdev_tstamp(struct device *dev, unsigned int str_id,
329− struct snd_compr_tstamp *tstamp)
329+ struct snd_compr_tstamp64 *tstamp)
330330 {
331331 struct snd_sst_tstamp fw_tstamp = {0,};
332332 struct stream_info *stream;
@@ -349,10 +349,11 @@ static int sst_cdev_tstamp(struct device *dev, unsigned int str_id, · 16 unmodified lines
349349 (u64)stream->num_ch * SST_GET_BYTES_PER_SAMPLE(24));
350350 tstamp->sampling_rate = fw_tstamp.sampling_frequency;
351351
352− dev_dbg(dev, "PCM = %u\n", tstamp->pcm_io_frames);
353− dev_dbg(dev, "Ptr Query on strid = %d copied_total %d, decodec %d\n",
352+ dev_dbg(dev, "PCM = %llu\n", tstamp->pcm_io_frames);
353+ dev_dbg(dev,
354+ "Ptr Query on strid = %d copied_total %llu, decodec %llu\n",
354355 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);
356357
357358 return 0;
358359 }
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
213213 }
214214
215215 static 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)
217217 {
218218 struct hdac_ext_stream *host_stream = avs_compr_get_host_stream(cstream);
219219 struct snd_soc_pcm_stream *pstream;
sound/soc/qcom/qdsp6/q6apm-dai.c+16−10
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 #include <sound/soc-dapm.h>
1212 #include <linux/spinlock.h>
1313 #include <sound/pcm.h>
14+#include <asm/div64.h>
1415 #include <asm/dma.h>
1516 #include <linux/dma-mapping.h>
1617 #include <sound/pcm_params.h>
@@ -65,9 +66,9 @@ struct q6apm_dai_rtd { · 48 unmodified lines
6566 unsigned int pcm_size;
6667 unsigned int pcm_count;
6768 unsigned int periods;
68− unsigned int bytes_sent;
69− unsigned int bytes_received;
70− unsigned int copied_total;
69+ uint64_t bytes_sent;
70+ uint64_t bytes_received;
71+ uint64_t copied_total;
7172 uint16_t bits_per_sample;
7273 snd_pcm_uframes_t queue_ptr;
7374 bool next_track;
@@ -575,15 +576,17 @@ static int q6apm_dai_compr_get_codec_caps(struct snd_soc_component *component, · 501 unmodified lines
575576
576577 static int q6apm_dai_compr_pointer(struct snd_soc_component *component,
577578 struct snd_compr_stream *stream,
578− struct snd_compr_tstamp *tstamp)
579+ struct snd_compr_tstamp64 *tstamp)
579580 {
580581 struct snd_compr_runtime *runtime = stream->runtime;
581582 struct q6apm_dai_rtd *prtd = runtime->private_data;
582583 unsigned long flags;
584+ uint64_t temp_copied_total;
583585
584586 spin_lock_irqsave(&prtd->lock, flags);
585587 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);
587590 spin_unlock_irqrestore(&prtd->lock, flags);
588591
589592 return 0;
@@ -760,21 +763,24 @@ static int q6apm_compr_copy(struct snd_soc_component *component, · 170 unmodified lines
760763 size_t copy;
761764 u32 wflags = 0;
762765 u32 app_pointer;
763− u32 bytes_received;
766+ uint64_t bytes_received;
767+ uint64_t temp_bytes_received;
764768 uint32_t bytes_to_write;
765− int avail, bytes_in_flight = 0;
769+ uint64_t avail, bytes_in_flight = 0;
766770
767771 bytes_received = prtd->bytes_received;
772+ temp_bytes_received = bytes_received;
768773
769774 /**
770775 * Make sure that next track data pointer is aligned at 32 bit boundary
771776 * This is a Mandatory requirement from DSP data buffers alignment
772777 */
773− if (prtd->next_track)
778+ if (prtd->next_track) {
774779 bytes_received = ALIGN(prtd->bytes_received, prtd->pcm_count);
780+ temp_bytes_received = bytes_received;
781+ }
775782
776− app_pointer = bytes_received/prtd->pcm_size;
777− app_pointer = bytes_received - (app_pointer * prtd->pcm_size);
783+ app_pointer = do_div(temp_bytes_received, prtd->pcm_size);
778784 dstn = prtd->dma_buffer.area + app_pointer;
779785
780786 if (count < prtd->pcm_size - app_pointer) {
sound/soc/qcom/qdsp6/q6asm-dai.c+16−10
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414 #include <sound/pcm.h>
1515 #include <linux/spinlock.h>
1616 #include <sound/compress_driver.h>
17+#include <asm/div64.h>
1718 #include <asm/dma.h>
1819 #include <linux/dma-mapping.h>
1920 #include <sound/pcm_params.h>
@@ -59,9 +60,9 @@ struct q6asm_dai_rtd { · 39 unmodified lines
5960 unsigned int pcm_count;
6061 unsigned int pcm_irq_pos; /* IRQ position */
6162 unsigned int periods;
62− unsigned int bytes_sent;
63− unsigned int bytes_received;
64− unsigned int copied_total;
63+ uint64_t bytes_sent;
64+ uint64_t bytes_received;
65+ uint64_t copied_total;
6566 uint16_t bits_per_sample;
6667 uint16_t source; /* Encoding source bit mask */
6768 struct audio_client *audio_client;
@@ -1026,16 +1027,18 @@ static int q6asm_dai_compr_trigger(struct snd_soc_component *component, · 958 unmodified lines
10261027
10271028 static int q6asm_dai_compr_pointer(struct snd_soc_component *component,
10281029 struct snd_compr_stream *stream,
1029− struct snd_compr_tstamp *tstamp)
1030+ struct snd_compr_tstamp64 *tstamp)
10301031 {
10311032 struct snd_compr_runtime *runtime = stream->runtime;
10321033 struct q6asm_dai_rtd *prtd = runtime->private_data;
10331034 unsigned long flags;
1035+ uint64_t temp_copied_total;
10341036
10351037 spin_lock_irqsave(&prtd->lock, flags);
10361038
10371039 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);
10391042
10401043 spin_unlock_irqrestore(&prtd->lock, flags);
10411044
@@ -1050,23 +1053,26 @@ static int q6asm_compr_copy(struct snd_soc_component *component, · 8 unmodified lines
10501053 struct q6asm_dai_rtd *prtd = runtime->private_data;
10511054 unsigned long flags;
10521055 u32 wflags = 0;
1053− int avail, bytes_in_flight = 0;
1056+ uint64_t avail, bytes_in_flight = 0;
10541057 void *dstn;
10551058 size_t copy;
10561059 u32 app_pointer;
1057− u32 bytes_received;
1060+ uint64_t bytes_received;
1061+ uint64_t temp_bytes_received;
10581062
10591063 bytes_received = prtd->bytes_received;
1064+ temp_bytes_received = bytes_received;
10601065
10611066 /**
10621067 * Make sure that next track data pointer is aligned at 32 bit boundary
10631068 * This is a Mandatory requirement from DSP data buffers alignment
10641069 */
1065− if (prtd->next_track)
1070+ if (prtd->next_track) {
10661071 bytes_received = ALIGN(prtd->bytes_received, prtd->pcm_count);
1072+ temp_bytes_received = bytes_received;
1073+ }
10671074
1068− app_pointer = bytes_received/prtd->pcm_size;
1069− app_pointer = bytes_received - (app_pointer * prtd->pcm_size);
1075+ app_pointer = do_div(temp_bytes_received, prtd->pcm_size);
10701076 dstn = prtd->dma_buffer.area + app_pointer;
10711077
10721078 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
637637 EXPORT_SYMBOL_GPL(snd_soc_component_compr_ack);
638638
639639 int snd_soc_component_compr_pointer(struct snd_compr_stream *cstream,
640− struct snd_compr_tstamp *tstamp)
640+ struct snd_compr_tstamp64 *tstamp)
641641 {
642642 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
643643 struct snd_soc_component *component;
sound/soc/soc-compress.c+1−1
@@ -457,7 +457,7 @@ err: · 456 unmodified lines
457457 }
458458
459459 static int soc_compr_pointer(struct snd_compr_stream *cstream,
460− struct snd_compr_tstamp *tstamp)
460+ struct snd_compr_tstamp64 *tstamp)
461461 {
462462 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
463463 int ret;
sound/soc/soc-dai.c+1−1
@@ -774,7 +774,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_compr_ack); · 773 unmodified lines
774774
775775 int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai,
776776 struct snd_compr_stream *cstream,
777− struct snd_compr_tstamp *tstamp)
777+ struct snd_compr_tstamp64 *tstamp)
778778 {
779779 int ret = 0;
780780
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
108108
109109 static int acp_probes_compr_pointer(struct sof_client_dev *cdev,
110110 struct snd_compr_stream *cstream,
111− struct snd_compr_tstamp *tstamp,
111+ struct snd_compr_tstamp64 *tstamp,
112112 struct snd_soc_dai *dai)
113113 {
114114 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
361361
362362 static int sof_compr_pointer(struct snd_soc_component *component,
363363 struct snd_compr_stream *cstream,
364− struct snd_compr_tstamp *tstamp)
364+ struct snd_compr_tstamp64 *tstamp)
365365 {
366366 struct snd_sof_pcm *spcm;
367367 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
112112
113113 static int hda_probes_compr_pointer(struct sof_client_dev *cdev,
114114 struct snd_compr_stream *cstream,
115− struct snd_compr_tstamp *tstamp,
115+ struct snd_compr_tstamp64 *tstamp,
116116 struct snd_soc_dai *dai)
117117 {
118118 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
137137 }
138138
139139 static int sof_probes_compr_pointer(struct snd_compr_stream *cstream,
140− struct snd_compr_tstamp *tstamp,
140+ struct snd_compr_tstamp64 *tstamp,
141141 struct snd_soc_dai *dai)
142142 {
143143 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
44 #define __SOF_CLIENT_PROBES_H
55
66 struct snd_compr_stream;
7−struct snd_compr_tstamp;
7+struct snd_compr_tstamp64;
88 struct snd_compr_params;
99 struct sof_client_dev;
1010 struct snd_soc_dai;
@@ -24,7 +24,7 @@ struct sof_probes_host_ops { · 13 unmodified lines
2424 int (*trigger)(struct sof_client_dev *cdev, struct snd_compr_stream *cstream,
2525 int cmd, struct snd_soc_dai *dai);
2626 int (*pointer)(struct sof_client_dev *cdev, struct snd_compr_stream *cstream,
27− struct snd_compr_tstamp *tstamp,
27+ struct snd_compr_tstamp64 *tstamp,
2828 struct snd_soc_dai *dai);
2929 };
3030
sound/soc/sprd/sprd-pcm-compress.c+3−3
@@ -85,9 +85,9 @@ struct sprd_compr_stream { · 84 unmodified lines
8585 int info_size;
8686
8787 /* Data size copied to IRAM buffer */
88− int copied_total;
88+ u64 copied_total;
8989 /* Total received data size from userspace */
90− int received_total;
90+ u64 received_total;
9191 /* Stage 0 IRAM buffer received data size */
9292 int received_stage0;
9393 /* 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
513513
514514 static int sprd_platform_compr_pointer(struct snd_soc_component *component,
515515 struct snd_compr_stream *cstream,
516− struct snd_compr_tstamp *tstamp)
516+ struct snd_compr_tstamp64 *tstamp)
517517 {
518518 struct snd_compr_runtime *runtime = cstream->runtime;
519519 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
1919 int total_time;
2020 int current_time;
2121 int total_data_length;
22− int current_data_offset;
22+ u64 current_data_offset;
2323 };
2424
2525 struct sprd_compr_params {
@@ -46,7 +46,7 @@ struct sprd_compr_ops { · 20 unmodified lines
4646 int (*stop)(int str_id);
4747 int (*pause)(int str_id);
4848 int (*pause_release)(int str_id);
49− int (*drain)(int received_total);
49+ int (*drain)(u64 received_total);
5050 int (*set_params)(int str_id, struct sprd_compr_params *params);
5151 };
5252
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
249249
250250 static int uniphier_aio_compr_pointer(struct snd_soc_component *component,
251251 struct snd_compr_stream *cstream,
252− struct snd_compr_tstamp *tstamp)
252+ struct snd_compr_tstamp64 *tstamp)
253253 {
254254 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
255255 struct snd_compr_runtime *runtime = cstream->runtime;