diff options
author | Takashi Iwai <tiwai@suse.de> | 2021-07-15 09:58:25 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2021-07-19 16:16:34 +0200 |
commit | c2b94954add3cb25b40a9aa8badd196671d9872b (patch) | |
tree | 89809a72a67ffec8c3056e9765aed56221983747 | |
parent | e8ad415b7a55cb9a9fbfc04696518d5ea0b609b3 (diff) | |
download | linux-c2b94954add3cb25b40a9aa8badd196671d9872b.tar.bz2 |
ALSA: core: Add device-managed request_dma()
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>
-rw-r--r-- | include/sound/core.h | 1 | ||||
-rw-r--r-- | sound/core/isadma.c | 38 |
2 files changed, 39 insertions, 0 deletions
diff --git a/include/sound/core.h b/include/sound/core.h index 7885f903cd5a..b7e9b58d3c78 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -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 */ diff --git a/sound/core/isadma.c b/sound/core/isadma.c index c3d789ef6975..1f45ede023b4 100644 --- a/sound/core/isadma.c +++ b/sound/core/isadma.c @@ -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); |