OSDN Git Service

ALSA: core: Add device-managed request_dma()
authorTakashi Iwai <tiwai@suse.de>
Thu, 15 Jul 2021 07:58:25 +0000 (09:58 +0200)
committerTakashi Iwai <tiwai@suse.de>
Mon, 19 Jul 2021 14:16:34 +0000 (16:16 +0200)
This patch adds a devres-supported helper for requesting an ISA DMA
channel that will be automatically freed at the device unbinding.
It'll be used by quite a few ISA sound drivers.

Link: https://lore.kernel.org/r/20210715075941.23332-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/sound/core.h
sound/core/isadma.c

index 7885f90..b7e9b58 100644 (file)
@@ -329,6 +329,7 @@ int snd_device_get_state(struct snd_card *card, void *device_data);
 void snd_dma_program(unsigned long dma, unsigned long addr, unsigned int size, unsigned short mode);
 void snd_dma_disable(unsigned long dma);
 unsigned int snd_dma_pointer(unsigned long dma, unsigned int size);
+int snd_devm_request_dma(struct device *dev, int dma, const char *name);
 #endif
 
 /* misc.c */
index c3d789e..1f45ede 100644 (file)
@@ -97,3 +97,41 @@ unsigned int snd_dma_pointer(unsigned long dma, unsigned int size)
                return size - result;
 }
 EXPORT_SYMBOL(snd_dma_pointer);
+
+struct snd_dma_data {
+       int dma;
+};
+
+static void __snd_release_dma(struct device *dev, void *data)
+{
+       struct snd_dma_data *p = data;
+
+       snd_dma_disable(p->dma);
+       free_dma(p->dma);
+}
+
+/**
+ * snd_devm_request_dma - the managed version of request_dma()
+ * @dev: the device pointer
+ * @dma: the dma number
+ * @name: the name string of the requester
+ *
+ * Returns zero on success, or a negative error code.
+ * The requested DMA will be automatically released at unbinding via devres.
+ */
+int snd_devm_request_dma(struct device *dev, int dma, const char *name)
+{
+       struct snd_dma_data *p;
+
+       if (request_dma(dma, name))
+               return -EBUSY;
+       p = devres_alloc(__snd_release_dma, sizeof(*p), GFP_KERNEL);
+       if (!p) {
+               free_dma(dma);
+               return -ENOMEM;
+       }
+       p->dma = dma;
+       devres_add(dev, p);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(snd_devm_request_dma);