hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/sound/hda/hdac_controller.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * HD-audio controller helpers
34 */
....@@ -8,6 +9,7 @@
89 #include <sound/core.h>
910 #include <sound/hdaudio.h>
1011 #include <sound/hda_register.h>
12
+#include "local.h"
1113
1214 /* clear CORB read pointer properly */
1315 static void azx_clear_corbrp(struct hdac_bus *bus)
....@@ -78,6 +80,8 @@
7880 snd_hdac_chip_writew(bus, RINTCNT, 1);
7981 /* enable rirb dma and response irq */
8082 snd_hdac_chip_writeb(bus, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN);
83
+ /* Accept unsolicited responses */
84
+ snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, AZX_GCTL_UNSOL);
8185 spin_unlock_irq(&bus->reg_lock);
8286 }
8387 EXPORT_SYMBOL_GPL(snd_hdac_bus_init_cmd_io);
....@@ -178,6 +182,7 @@
178182 * @bus: HD-audio core bus
179183 *
180184 * Usually called from interrupt handler.
185
+ * The caller needs bus->reg_lock spinlock before calling this.
181186 */
182187 void snd_hdac_bus_update_rirb(struct hdac_bus *bus)
183188 {
....@@ -213,6 +218,9 @@
213218 else if (bus->rirb.cmds[addr]) {
214219 bus->rirb.res[addr] = res;
215220 bus->rirb.cmds[addr]--;
221
+ if (!bus->rirb.cmds[addr] &&
222
+ waitqueue_active(&bus->rirb_wq))
223
+ wake_up(&bus->rirb_wq);
216224 } else {
217225 dev_err_ratelimited(bus->dev,
218226 "spurious response %#x:%#x, last cmd=%#08x\n",
....@@ -235,27 +243,50 @@
235243 {
236244 unsigned long timeout;
237245 unsigned long loopcounter;
246
+ wait_queue_entry_t wait;
247
+ bool warned = false;
238248
249
+ init_wait_entry(&wait, 0);
239250 timeout = jiffies + msecs_to_jiffies(1000);
240251
241252 for (loopcounter = 0;; loopcounter++) {
242253 spin_lock_irq(&bus->reg_lock);
254
+ if (!bus->polling_mode)
255
+ prepare_to_wait(&bus->rirb_wq, &wait,
256
+ TASK_UNINTERRUPTIBLE);
257
+ if (bus->polling_mode)
258
+ snd_hdac_bus_update_rirb(bus);
243259 if (!bus->rirb.cmds[addr]) {
244260 if (res)
245261 *res = bus->rirb.res[addr]; /* the last value */
262
+ if (!bus->polling_mode)
263
+ finish_wait(&bus->rirb_wq, &wait);
246264 spin_unlock_irq(&bus->reg_lock);
247265 return 0;
248266 }
249267 spin_unlock_irq(&bus->reg_lock);
250268 if (time_after(jiffies, timeout))
251269 break;
252
- if (loopcounter > 3000)
270
+#define LOOP_COUNT_MAX 3000
271
+ if (!bus->polling_mode) {
272
+ schedule_timeout(msecs_to_jiffies(2));
273
+ } else if (bus->needs_damn_long_delay ||
274
+ loopcounter > LOOP_COUNT_MAX) {
275
+ if (loopcounter > LOOP_COUNT_MAX && !warned) {
276
+ dev_dbg_ratelimited(bus->dev,
277
+ "too slow response, last cmd=%#08x\n",
278
+ bus->last_cmd[addr]);
279
+ warned = true;
280
+ }
253281 msleep(2); /* temporary workaround */
254
- else {
282
+ } else {
255283 udelay(10);
256284 cond_resched();
257285 }
258286 }
287
+
288
+ if (!bus->polling_mode)
289
+ finish_wait(&bus->rirb_wq, &wait);
259290
260291 return -EIO;
261292 }
....@@ -376,7 +407,7 @@
376407 {
377408 unsigned long timeout;
378409
379
- snd_hdac_chip_updateb(bus, GCTL, 0, AZX_GCTL_RESET);
410
+ snd_hdac_chip_updateb(bus, GCTL, AZX_GCTL_RESET, AZX_GCTL_RESET);
380411
381412 timeout = jiffies + msecs_to_jiffies(100);
382413 while (!snd_hdac_chip_readb(bus, GCTL) && time_before(jiffies, timeout))
....@@ -415,9 +446,6 @@
415446 return -EBUSY;
416447 }
417448
418
- /* Accept unsolicited responses */
419
- snd_hdac_chip_updatel(bus, GCTL, 0, AZX_GCTL_UNSOL);
420
-
421449 /* detect codecs */
422450 if (!bus->codec_mask) {
423451 bus->codec_mask = snd_hdac_chip_readw(bus, STATESTS);
....@@ -432,7 +460,9 @@
432460 static void azx_int_enable(struct hdac_bus *bus)
433461 {
434462 /* enable controller CIE and GIE */
435
- snd_hdac_chip_updatel(bus, INTCTL, 0, AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN);
463
+ snd_hdac_chip_updatel(bus, INTCTL,
464
+ AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN,
465
+ AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN);
436466 }
437467
438468 /* disable interrupts */
....@@ -499,6 +529,7 @@
499529 }
500530
501531 bus->chip_init = true;
532
+
502533 return true;
503534 }
504535 EXPORT_SYMBOL_GPL(snd_hdac_bus_init_chip);
....@@ -533,7 +564,7 @@
533564 * snd_hdac_bus_handle_stream_irq - interrupt handler for streams
534565 * @bus: HD-audio core bus
535566 * @status: INTSTS register value
536
- * @ask: callback to be called for woken streams
567
+ * @ack: callback to be called for woken streams
537568 *
538569 * Returns the bits of handled streams, or zero if no stream is handled.
539570 */
....@@ -572,12 +603,13 @@
572603 {
573604 struct hdac_stream *s;
574605 int num_streams = 0;
606
+ int dma_type = bus->dma_type ? bus->dma_type : SNDRV_DMA_TYPE_DEV;
575607 int err;
576608
577609 list_for_each_entry(s, &bus->stream_list, list) {
578610 /* allocate memory for the BDL for each stream */
579
- err = bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV,
580
- BDL_SIZE, &s->bdl);
611
+ err = snd_dma_alloc_pages(dma_type, bus->dev,
612
+ BDL_SIZE, &s->bdl);
581613 num_streams++;
582614 if (err < 0)
583615 return -ENOMEM;
....@@ -586,16 +618,15 @@
586618 if (WARN_ON(!num_streams))
587619 return -EINVAL;
588620 /* allocate memory for the position buffer */
589
- err = bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV,
590
- num_streams * 8, &bus->posbuf);
621
+ err = snd_dma_alloc_pages(dma_type, bus->dev,
622
+ num_streams * 8, &bus->posbuf);
591623 if (err < 0)
592624 return -ENOMEM;
593625 list_for_each_entry(s, &bus->stream_list, list)
594626 s->posbuf = (__le32 *)(bus->posbuf.area + s->index * 8);
595627
596628 /* single page (at least 4096 bytes) must suffice for both ringbuffes */
597
- return bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV,
598
- PAGE_SIZE, &bus->rb);
629
+ return snd_dma_alloc_pages(dma_type, bus->dev, PAGE_SIZE, &bus->rb);
599630 }
600631 EXPORT_SYMBOL_GPL(snd_hdac_bus_alloc_stream_pages);
601632
....@@ -609,12 +640,12 @@
609640
610641 list_for_each_entry(s, &bus->stream_list, list) {
611642 if (s->bdl.area)
612
- bus->io_ops->dma_free_pages(bus, &s->bdl);
643
+ snd_dma_free_pages(&s->bdl);
613644 }
614645
615646 if (bus->rb.area)
616
- bus->io_ops->dma_free_pages(bus, &bus->rb);
647
+ snd_dma_free_pages(&bus->rb);
617648 if (bus->posbuf.area)
618
- bus->io_ops->dma_free_pages(bus, &bus->posbuf);
649
+ snd_dma_free_pages(&bus->posbuf);
619650 }
620651 EXPORT_SYMBOL_GPL(snd_hdac_bus_free_stream_pages);