summaryrefslogtreecommitdiffstats
path: root/sound/hda/hdac_controller.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/hda/hdac_controller.c')
-rw-r--r--sound/hda/hdac_controller.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
index c0069d0b7875..b5a17cb510a0 100644
--- a/sound/hda/hdac_controller.c
+++ b/sound/hda/hdac_controller.c
@@ -447,3 +447,61 @@ void snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
}
}
EXPORT_SYMBOL_GPL(snd_hdac_bus_handle_stream_irq);
+
+/**
+ * snd_hdac_bus_alloc_stream_pages - allocate BDL and other buffers
+ * @bus: HD-audio core bus
+ *
+ * Call this after assigning the all streams.
+ * Returns zero for success, or a negative error code.
+ */
+int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus)
+{
+ struct hdac_stream *s;
+ int num_streams = 0;
+ int err;
+
+ list_for_each_entry(s, &bus->stream_list, list) {
+ /* allocate memory for the BDL for each stream */
+ err = bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV,
+ BDL_SIZE, &s->bdl);
+ num_streams++;
+ if (err < 0)
+ return -ENOMEM;
+ }
+
+ if (WARN_ON(!num_streams))
+ return -EINVAL;
+ /* allocate memory for the position buffer */
+ err = bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV,
+ num_streams * 8, &bus->posbuf);
+ if (err < 0)
+ return -ENOMEM;
+ list_for_each_entry(s, &bus->stream_list, list)
+ s->posbuf = (__le32 *)(bus->posbuf.area + s->index * 8);
+
+ /* single page (at least 4096 bytes) must suffice for both ringbuffes */
+ return bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV,
+ PAGE_SIZE, &bus->rb);
+}
+EXPORT_SYMBOL_GPL(snd_hdac_bus_alloc_stream_pages);
+
+/**
+ * snd_hdac_bus_free_stream_pages - release BDL and other buffers
+ * @bus: HD-audio core bus
+ */
+void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus)
+{
+ struct hdac_stream *s;
+
+ list_for_each_entry(s, &bus->stream_list, list) {
+ if (s->bdl.area)
+ bus->io_ops->dma_free_pages(bus, &s->bdl);
+ }
+
+ if (bus->rb.area)
+ bus->io_ops->dma_free_pages(bus, &bus->rb);
+ if (bus->posbuf.area)
+ bus->io_ops->dma_free_pages(bus, &bus->posbuf);
+}
+EXPORT_SYMBOL_GPL(snd_hdac_bus_free_stream_pages);