1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/pm_runtime.h>
19#include <sound/hdaudio_ext.h>
20#include <sound/hda_register.h>
21#include <sound/sof.h>
22#include "../ops.h"
23#include "hda.h"
24
25
26
27
28static int hda_setup_bdle(struct snd_sof_dev *sdev,
29 struct snd_dma_buffer *dmab,
30 struct hdac_stream *stream,
31 struct sof_intel_dsp_bdl **bdlp,
32 int offset, int size, int ioc)
33{
34 struct hdac_bus *bus = sof_to_bus(sdev);
35 struct sof_intel_dsp_bdl *bdl = *bdlp;
36
37 while (size > 0) {
38 dma_addr_t addr;
39 int chunk;
40
41 if (stream->frags >= HDA_DSP_MAX_BDL_ENTRIES) {
42 dev_err(sdev->dev, "error: stream frags exceeded\n");
43 return -EINVAL;
44 }
45
46 addr = snd_sgbuf_get_addr(dmab, offset);
47
48 bdl->addr_l = cpu_to_le32(lower_32_bits(addr));
49 bdl->addr_h = cpu_to_le32(upper_32_bits(addr));
50
51 chunk = snd_sgbuf_get_chunk_size(dmab, offset, size);
52
53 if (bus->align_bdle_4k) {
54 u32 remain = 0x1000 - (offset & 0xfff);
55
56 if (chunk > remain)
57 chunk = remain;
58 }
59 bdl->size = cpu_to_le32(chunk);
60
61 size -= chunk;
62 bdl->ioc = (size || !ioc) ? 0 : cpu_to_le32(0x01);
63 bdl++;
64 stream->frags++;
65 offset += chunk;
66
67 dev_vdbg(sdev->dev, "bdl, frags:%d, chunk size:0x%x;\n",
68 stream->frags, chunk);
69 }
70
71 *bdlp = bdl;
72 return offset;
73}
74
75
76
77
78
79int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev,
80 struct snd_dma_buffer *dmab,
81 struct hdac_stream *stream)
82{
83 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
84 struct sof_intel_dsp_bdl *bdl;
85 int i, offset, period_bytes, periods;
86 int remain, ioc;
87
88 period_bytes = stream->period_bytes;
89 dev_dbg(sdev->dev, "period_bytes:0x%x\n", period_bytes);
90 if (!period_bytes)
91 period_bytes = stream->bufsize;
92
93 periods = stream->bufsize / period_bytes;
94
95 dev_dbg(sdev->dev, "periods:%d\n", periods);
96
97 remain = stream->bufsize % period_bytes;
98 if (remain)
99 periods++;
100
101
102 bdl = (struct sof_intel_dsp_bdl *)stream->bdl.area;
103 offset = 0;
104 stream->frags = 0;
105
106
107
108
109
110 ioc = hda->no_ipc_position ?
111 !stream->no_period_wakeup : 0;
112
113 for (i = 0; i < periods; i++) {
114 if (i == (periods - 1) && remain)
115
116 offset = hda_setup_bdle(sdev, dmab,
117 stream, &bdl, offset,
118 remain, 0);
119 else
120 offset = hda_setup_bdle(sdev, dmab,
121 stream, &bdl, offset,
122 period_bytes, ioc);
123 }
124
125 return offset;
126}
127
128int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev,
129 struct hdac_ext_stream *stream,
130 int enable, u32 size)
131{
132 struct hdac_stream *hstream = &stream->hstream;
133 u32 mask;
134
135 if (!sdev->bar[HDA_DSP_SPIB_BAR]) {
136 dev_err(sdev->dev, "error: address of spib capability is NULL\n");
137 return -EINVAL;
138 }
139
140 mask = (1 << hstream->index);
141
142
143 snd_sof_dsp_update_bits(sdev, HDA_DSP_SPIB_BAR,
144 SOF_HDA_ADSP_REG_CL_SPBFIFO_SPBFCCTL, mask,
145 enable << hstream->index);
146
147
148 sof_io_write(sdev, stream->spib_addr, size);
149
150 return 0;
151}
152
153
154struct hdac_ext_stream *
155hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction)
156{
157 struct hdac_bus *bus = sof_to_bus(sdev);
158 struct hdac_ext_stream *stream = NULL;
159 struct hdac_stream *s;
160
161 spin_lock_irq(&bus->reg_lock);
162
163
164 list_for_each_entry(s, &bus->stream_list, list) {
165 if (s->direction == direction && !s->opened) {
166 s->opened = true;
167 stream = stream_to_hdac_ext_stream(s);
168 break;
169 }
170 }
171
172 spin_unlock_irq(&bus->reg_lock);
173
174
175 if (!stream)
176 dev_err(sdev->dev, "error: no free %s streams\n",
177 direction == SNDRV_PCM_STREAM_PLAYBACK ?
178 "playback" : "capture");
179
180 return stream;
181}
182
183
184int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
185{
186 struct hdac_bus *bus = sof_to_bus(sdev);
187 struct hdac_stream *s;
188
189 spin_lock_irq(&bus->reg_lock);
190
191
192 list_for_each_entry(s, &bus->stream_list, list) {
193 if (s->direction == direction &&
194 s->opened && s->stream_tag == stream_tag) {
195 s->opened = false;
196 spin_unlock_irq(&bus->reg_lock);
197 return 0;
198 }
199 }
200
201 spin_unlock_irq(&bus->reg_lock);
202
203 dev_dbg(sdev->dev, "stream_tag %d not opened!\n", stream_tag);
204 return -ENODEV;
205}
206
207int hda_dsp_stream_trigger(struct snd_sof_dev *sdev,
208 struct hdac_ext_stream *stream, int cmd)
209{
210 struct hdac_stream *hstream = &stream->hstream;
211 int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
212
213
214 switch (cmd) {
215 case SNDRV_PCM_TRIGGER_RESUME:
216 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
217 case SNDRV_PCM_TRIGGER_START:
218 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
219 1 << hstream->index,
220 1 << hstream->index);
221
222 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
223 sd_offset,
224 SOF_HDA_SD_CTL_DMA_START |
225 SOF_HDA_CL_DMA_SD_INT_MASK,
226 SOF_HDA_SD_CTL_DMA_START |
227 SOF_HDA_CL_DMA_SD_INT_MASK);
228
229 hstream->running = true;
230 break;
231 case SNDRV_PCM_TRIGGER_SUSPEND:
232 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
233 case SNDRV_PCM_TRIGGER_STOP:
234 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
235 sd_offset,
236 SOF_HDA_SD_CTL_DMA_START |
237 SOF_HDA_CL_DMA_SD_INT_MASK, 0x0);
238
239 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, sd_offset +
240 SOF_HDA_ADSP_REG_CL_SD_STS,
241 SOF_HDA_CL_DMA_SD_INT_MASK);
242
243 hstream->running = false;
244 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
245 1 << hstream->index, 0x0);
246 break;
247 default:
248 dev_err(sdev->dev, "error: unknown command: %d\n", cmd);
249 return -EINVAL;
250 }
251
252 return 0;
253}
254
255
256
257
258
259int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
260 struct hdac_ext_stream *stream,
261 struct snd_dma_buffer *dmab,
262 struct snd_pcm_hw_params *params)
263{
264 struct hdac_bus *bus = sof_to_bus(sdev);
265 struct hdac_stream *hstream = &stream->hstream;
266 int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
267 int ret, timeout = HDA_DSP_STREAM_RESET_TIMEOUT;
268 u32 val, mask;
269
270 if (!stream) {
271 dev_err(sdev->dev, "error: no stream available\n");
272 return -ENODEV;
273 }
274
275
276 mask = 0x1 << hstream->index;
277 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
278 mask, mask);
279
280 if (!dmab) {
281 dev_err(sdev->dev, "error: no dma buffer allocated!\n");
282 return -ENODEV;
283 }
284
285
286 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
287 SOF_HDA_CL_DMA_SD_INT_MASK |
288 SOF_HDA_SD_CTL_DMA_START, 0);
289 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
290 sd_offset + SOF_HDA_ADSP_REG_CL_SD_STS,
291 SOF_HDA_CL_DMA_SD_INT_MASK,
292 SOF_HDA_CL_DMA_SD_INT_MASK);
293
294
295 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, 0x1,
296 0x1);
297 udelay(3);
298 do {
299 val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
300 sd_offset);
301 if (val & 0x1)
302 break;
303 } while (--timeout);
304 if (timeout == 0) {
305 dev_err(sdev->dev, "error: stream reset failed\n");
306 return -ETIMEDOUT;
307 }
308
309 timeout = HDA_DSP_STREAM_RESET_TIMEOUT;
310 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, 0x1,
311 0x0);
312
313
314 udelay(3);
315 do {
316 val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
317 sd_offset);
318 if ((val & 0x1) == 0)
319 break;
320 } while (--timeout);
321 if (timeout == 0) {
322 dev_err(sdev->dev, "error: timeout waiting for stream reset\n");
323 return -ETIMEDOUT;
324 }
325
326 if (hstream->posbuf)
327 *hstream->posbuf = 0;
328
329
330 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
331 sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
332 0x0);
333 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
334 sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
335 0x0);
336
337
338 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
339 SOF_HDA_CL_DMA_SD_INT_MASK |
340 SOF_HDA_SD_CTL_DMA_START, 0);
341 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
342 sd_offset + SOF_HDA_ADSP_REG_CL_SD_STS,
343 SOF_HDA_CL_DMA_SD_INT_MASK,
344 SOF_HDA_CL_DMA_SD_INT_MASK);
345
346 hstream->frags = 0;
347
348 ret = hda_dsp_stream_setup_bdl(sdev, dmab, hstream);
349 if (ret < 0) {
350 dev_err(sdev->dev, "error: set up of BDL failed\n");
351 return ret;
352 }
353
354
355 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
356 SOF_HDA_CL_SD_CTL_STREAM_TAG_MASK,
357 hstream->stream_tag <<
358 SOF_HDA_CL_SD_CTL_STREAM_TAG_SHIFT);
359
360
361 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
362 sd_offset + SOF_HDA_ADSP_REG_CL_SD_CBL,
363 hstream->bufsize);
364
365
366
367
368
369
370
371
372
373
374
375
376
377 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
378 mask, 0);
379
380
381 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
382 sd_offset +
383 SOF_HDA_ADSP_REG_CL_SD_FORMAT,
384 0xffff, hstream->format_val);
385
386
387 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
388 mask, mask);
389
390
391 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
392 sd_offset + SOF_HDA_ADSP_REG_CL_SD_LVI,
393 0xffff, (hstream->frags - 1));
394
395
396 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
397 sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
398 (u32)hstream->bdl.addr);
399 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
400 sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
401 upper_32_bits(hstream->bdl.addr));
402
403
404 if (!(snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPLBASE)
405 & SOF_HDA_ADSP_DPLBASE_ENABLE)) {
406 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPUBASE,
407 upper_32_bits(bus->posbuf.addr));
408 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPLBASE,
409 (u32)bus->posbuf.addr |
410 SOF_HDA_ADSP_DPLBASE_ENABLE);
411 }
412
413
414 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
415 SOF_HDA_CL_DMA_SD_INT_MASK,
416 SOF_HDA_CL_DMA_SD_INT_MASK);
417
418
419 if (hstream->direction == SNDRV_PCM_STREAM_PLAYBACK) {
420 hstream->fifo_size =
421 snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
422 sd_offset +
423 SOF_HDA_ADSP_REG_CL_SD_FIFOSIZE);
424 hstream->fifo_size &= 0xffff;
425 hstream->fifo_size += 1;
426 } else {
427 hstream->fifo_size = 0;
428 }
429
430 return ret;
431}
432
433irqreturn_t hda_dsp_stream_interrupt(int irq, void *context)
434{
435 struct hdac_bus *bus = context;
436 struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
437 u32 stream_mask;
438 u32 status;
439
440 if (!pm_runtime_active(bus->dev))
441 return IRQ_NONE;
442
443 spin_lock(&bus->reg_lock);
444
445 status = snd_hdac_chip_readl(bus, INTSTS);
446 stream_mask = GENMASK(sof_hda->stream_max - 1, 0) | AZX_INT_CTRL_EN;
447
448
449 if (!(status & stream_mask) || status == 0xffffffff) {
450 spin_unlock(&bus->reg_lock);
451 return IRQ_NONE;
452 }
453
454#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
455
456 status = snd_hdac_chip_readb(bus, RIRBSTS);
457 if (status & RIRB_INT_MASK) {
458 if (status & RIRB_INT_RESPONSE)
459 snd_hdac_bus_update_rirb(bus);
460 snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
461 }
462#endif
463
464 spin_unlock(&bus->reg_lock);
465
466 return snd_hdac_chip_readl(bus, INTSTS) ? IRQ_WAKE_THREAD : IRQ_HANDLED;
467}
468
469irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context)
470{
471 struct hdac_bus *bus = context;
472 struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
473 u32 status = snd_hdac_chip_readl(bus, INTSTS);
474 struct hdac_stream *s;
475 u32 sd_status;
476
477
478 list_for_each_entry(s, &bus->stream_list, list) {
479 if (status & (1 << s->index) && s->opened) {
480 sd_status = snd_hdac_stream_readb(s, SD_STS);
481
482 dev_vdbg(bus->dev, "stream %d status 0x%x\n",
483 s->index, sd_status);
484
485 snd_hdac_stream_writeb(s, SD_STS, SD_INT_MASK);
486
487 if (!s->substream ||
488 !s->running ||
489 (sd_status & SOF_HDA_CL_DMA_SD_INT_COMPLETE) == 0)
490 continue;
491
492
493 if (sof_hda->no_ipc_position)
494 snd_sof_pcm_period_elapsed(s->substream);
495
496 }
497 }
498
499 return IRQ_HANDLED;
500}
501
502int hda_dsp_stream_init(struct snd_sof_dev *sdev)
503{
504 struct hdac_bus *bus = sof_to_bus(sdev);
505 struct hdac_ext_stream *stream;
506 struct hdac_stream *hstream;
507 struct pci_dev *pci = to_pci_dev(sdev->dev);
508 struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
509 int sd_offset;
510 int i, num_playback, num_capture, num_total, ret;
511 u32 gcap;
512
513 gcap = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_GCAP);
514 dev_dbg(sdev->dev, "hda global caps = 0x%x\n", gcap);
515
516
517 num_capture = (gcap >> 8) & 0x0f;
518 num_playback = (gcap >> 12) & 0x0f;
519 num_total = num_playback + num_capture;
520
521 dev_dbg(sdev->dev, "detected %d playback and %d capture streams\n",
522 num_playback, num_capture);
523
524 if (num_playback >= SOF_HDA_PLAYBACK_STREAMS) {
525 dev_err(sdev->dev, "error: too many playback streams %d\n",
526 num_playback);
527 return -EINVAL;
528 }
529
530 if (num_capture >= SOF_HDA_CAPTURE_STREAMS) {
531 dev_err(sdev->dev, "error: too many capture streams %d\n",
532 num_playback);
533 return -EINVAL;
534 }
535
536
537
538
539
540 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
541 SOF_HDA_DPIB_ENTRY_SIZE * num_total,
542 &bus->posbuf);
543 if (ret < 0) {
544 dev_err(sdev->dev, "error: posbuffer dma alloc failed\n");
545 return -ENOMEM;
546 }
547
548#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
549
550 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
551 PAGE_SIZE, &bus->rb);
552 if (ret < 0) {
553 dev_err(sdev->dev, "error: RB alloc failed\n");
554 return -ENOMEM;
555 }
556#endif
557
558
559 for (i = 0; i < num_capture; i++) {
560 struct sof_intel_hda_stream *hda_stream;
561
562 hda_stream = devm_kzalloc(sdev->dev, sizeof(*hda_stream),
563 GFP_KERNEL);
564 if (!hda_stream)
565 return -ENOMEM;
566
567 stream = &hda_stream->hda_stream;
568
569 stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
570 SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
571
572 stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
573 SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
574 SOF_HDA_PPLC_INTERVAL * i;
575
576
577 if (sdev->bar[HDA_DSP_SPIB_BAR]) {
578 stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
579 SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
580 SOF_HDA_SPIB_SPIB;
581
582 stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
583 SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
584 SOF_HDA_SPIB_MAXFIFO;
585 }
586
587 hstream = &stream->hstream;
588 hstream->bus = bus;
589 hstream->sd_int_sta_mask = 1 << i;
590 hstream->index = i;
591 sd_offset = SOF_STREAM_SD_OFFSET(hstream);
592 hstream->sd_addr = sdev->bar[HDA_DSP_HDA_BAR] + sd_offset;
593 hstream->stream_tag = i + 1;
594 hstream->opened = false;
595 hstream->running = false;
596 hstream->direction = SNDRV_PCM_STREAM_CAPTURE;
597
598
599 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
600 HDA_DSP_BDL_SIZE, &hstream->bdl);
601 if (ret < 0) {
602 dev_err(sdev->dev, "error: stream bdl dma alloc failed\n");
603 return -ENOMEM;
604 }
605 hstream->posbuf = (__le32 *)(bus->posbuf.area +
606 (hstream->index) * 8);
607
608 list_add_tail(&hstream->list, &bus->stream_list);
609 }
610
611
612 for (i = num_capture; i < num_total; i++) {
613 struct sof_intel_hda_stream *hda_stream;
614
615 hda_stream = devm_kzalloc(sdev->dev, sizeof(*hda_stream),
616 GFP_KERNEL);
617 if (!hda_stream)
618 return -ENOMEM;
619
620 stream = &hda_stream->hda_stream;
621
622
623 stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
624 SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
625
626 stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
627 SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
628 SOF_HDA_PPLC_INTERVAL * i;
629
630
631 if (sdev->bar[HDA_DSP_SPIB_BAR]) {
632 stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
633 SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
634 SOF_HDA_SPIB_SPIB;
635
636 stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
637 SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
638 SOF_HDA_SPIB_MAXFIFO;
639 }
640
641 hstream = &stream->hstream;
642 hstream->bus = bus;
643 hstream->sd_int_sta_mask = 1 << i;
644 hstream->index = i;
645 sd_offset = SOF_STREAM_SD_OFFSET(hstream);
646 hstream->sd_addr = sdev->bar[HDA_DSP_HDA_BAR] + sd_offset;
647 hstream->stream_tag = i - num_capture + 1;
648 hstream->opened = false;
649 hstream->running = false;
650 hstream->direction = SNDRV_PCM_STREAM_PLAYBACK;
651
652
653 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
654 HDA_DSP_BDL_SIZE, &hstream->bdl);
655 if (ret < 0) {
656 dev_err(sdev->dev, "error: stream bdl dma alloc failed\n");
657 return -ENOMEM;
658 }
659
660 hstream->posbuf = (__le32 *)(bus->posbuf.area +
661 (hstream->index) * 8);
662
663 list_add_tail(&hstream->list, &bus->stream_list);
664 }
665
666
667 sof_hda->stream_max = num_total;
668
669 return 0;
670}
671
672void hda_dsp_stream_free(struct snd_sof_dev *sdev)
673{
674 struct hdac_bus *bus = sof_to_bus(sdev);
675 struct hdac_stream *s, *_s;
676 struct hdac_ext_stream *stream;
677 struct sof_intel_hda_stream *hda_stream;
678
679
680 if (bus->posbuf.area)
681 snd_dma_free_pages(&bus->posbuf);
682
683#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
684
685 if (bus->rb.area)
686 snd_dma_free_pages(&bus->rb);
687#endif
688
689 list_for_each_entry_safe(s, _s, &bus->stream_list, list) {
690
691
692
693 if (s->bdl.area)
694 snd_dma_free_pages(&s->bdl);
695 list_del(&s->list);
696 stream = stream_to_hdac_ext_stream(s);
697 hda_stream = container_of(stream, struct sof_intel_hda_stream,
698 hda_stream);
699 devm_kfree(sdev->dev, hda_stream);
700 }
701}
702