Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 75aac820 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branch 'asoc/topic/dma' into asoc-next

parents 01ad154e 2b67f8ba
Loading
Loading
Loading
Loading
+31 −4
Original line number Diff line number Diff line
@@ -540,6 +540,8 @@ EXPORT_SYMBOL_GPL(dma_get_slave_channel);
 * @mask: capabilities that the channel must satisfy
 * @fn: optional callback to disposition available channels
 * @fn_param: opaque parameter to pass to dma_filter_fn
 *
 * Returns pointer to appropriate DMA channel on success or NULL.
 */
struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
				       dma_filter_fn fn, void *fn_param)
@@ -591,18 +593,43 @@ EXPORT_SYMBOL_GPL(__dma_request_channel);
 * dma_request_slave_channel - try to allocate an exclusive slave channel
 * @dev:	pointer to client device structure
 * @name:	slave channel name
 *
 * Returns pointer to appropriate DMA channel on success or an error pointer.
 */
struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name)
struct dma_chan *dma_request_slave_channel_reason(struct device *dev,
						  const char *name)
{
	struct dma_chan *chan;

	/* If device-tree is present get slave info from here */
	if (dev->of_node)
		return of_dma_request_slave_channel(dev->of_node, name);

	/* If device was enumerated by ACPI get slave info from here */
	if (ACPI_HANDLE(dev))
		return acpi_dma_request_slave_chan_by_name(dev, name);
	if (ACPI_HANDLE(dev)) {
		chan = acpi_dma_request_slave_chan_by_name(dev, name);
		if (chan)
			return chan;
	}

	return ERR_PTR(-ENODEV);
}
EXPORT_SYMBOL_GPL(dma_request_slave_channel_reason);

/**
 * dma_request_slave_channel - try to allocate an exclusive slave channel
 * @dev:	pointer to client device structure
 * @name:	slave channel name
 *
 * Returns pointer to appropriate DMA channel on success or NULL.
 */
struct dma_chan *dma_request_slave_channel(struct device *dev,
					   const char *name)
{
	struct dma_chan *ch = dma_request_slave_channel_reason(dev, name);
	if (IS_ERR(ch))
		return NULL;
	return ch;
}
EXPORT_SYMBOL_GPL(dma_request_slave_channel);

+9 −6
Original line number Diff line number Diff line
@@ -143,7 +143,7 @@ static int of_dma_match_channel(struct device_node *np, const char *name,
 * @np:		device node to get DMA request from
 * @name:	name of desired channel
 *
 * Returns pointer to appropriate dma channel on success or NULL on error.
 * Returns pointer to appropriate DMA channel on success or an error pointer.
 */
struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
					      const char *name)
@@ -152,17 +152,18 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
	struct of_dma		*ofdma;
	struct dma_chan		*chan;
	int			count, i;
	int			ret_no_channel = -ENODEV;

	if (!np || !name) {
		pr_err("%s: not enough information provided\n", __func__);
		return NULL;
		return ERR_PTR(-ENODEV);
	}

	count = of_property_count_strings(np, "dma-names");
	if (count < 0) {
		pr_err("%s: dma-names property of node '%s' missing or empty\n",
			__func__, np->full_name);
		return NULL;
		return ERR_PTR(-ENODEV);
	}

	for (i = 0; i < count; i++) {
@@ -172,10 +173,12 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
		mutex_lock(&of_dma_lock);
		ofdma = of_dma_find_controller(&dma_spec);

		if (ofdma)
		if (ofdma) {
			chan = ofdma->of_dma_xlate(&dma_spec, ofdma);
		else
		} else {
			ret_no_channel = -EPROBE_DEFER;
			chan = NULL;
		}

		mutex_unlock(&of_dma_lock);

@@ -185,7 +188,7 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
			return chan;
	}

	return NULL;
	return ERR_PTR(ret_no_channel);
}

/**
+8 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#define LINUX_DMAENGINE_H

#include <linux/device.h>
#include <linux/err.h>
#include <linux/uio.h>
#include <linux/bug.h>
#include <linux/scatterlist.h>
@@ -1040,6 +1041,8 @@ enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx);
void dma_issue_pending_all(void);
struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
					dma_filter_fn fn, void *fn_param);
struct dma_chan *dma_request_slave_channel_reason(struct device *dev,
						  const char *name);
struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name);
void dma_release_channel(struct dma_chan *chan);
#else
@@ -1063,6 +1066,11 @@ static inline struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
{
	return NULL;
}
static inline struct dma_chan *dma_request_slave_channel_reason(
					struct device *dev, const char *name)
{
	return ERR_PTR(-ENODEV);
}
static inline struct dma_chan *dma_request_slave_channel(struct device *dev,
							 const char *name)
{
+10 −0
Original line number Diff line number Diff line
@@ -114,6 +114,10 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
 * @compat_filter_fn: Will be used as the filter function when requesting a
 *  channel for platforms which do not use devicetree. The filter parameter
 *  will be the DAI's DMA data.
 * @dma_dev: If set, request DMA channel on this device rather than the DAI
 *  device.
 * @chan_names: If set, these custom DMA channel names will be requested at
 *  registration time.
 * @pcm_hardware: snd_pcm_hardware struct to be used for the PCM.
 * @prealloc_buffer_size: Size of the preallocated audio buffer.
 *
@@ -130,6 +134,8 @@ struct snd_dmaengine_pcm_config {
			struct snd_soc_pcm_runtime *rtd,
			struct snd_pcm_substream *substream);
	dma_filter_fn compat_filter_fn;
	struct device *dma_dev;
	const char *chan_names[SNDRV_PCM_STREAM_LAST + 1];

	const struct snd_pcm_hardware *pcm_hardware;
	unsigned int prealloc_buffer_size;
@@ -140,6 +146,10 @@ int snd_dmaengine_pcm_register(struct device *dev,
	unsigned int flags);
void snd_dmaengine_pcm_unregister(struct device *dev);

int devm_snd_dmaengine_pcm_register(struct device *dev,
	const struct snd_dmaengine_pcm_config *config,
	unsigned int flags);

int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params,
	struct dma_slave_config *slave_config);
+41 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <sound/soc.h>
#include <sound/dmaengine_pcm.h>

static void devm_component_release(struct device *dev, void *res)
{
@@ -84,3 +85,43 @@ int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card)
	return ret;
}
EXPORT_SYMBOL_GPL(devm_snd_soc_register_card);

#ifdef CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM

static void devm_dmaengine_pcm_release(struct device *dev, void *res)
{
	snd_dmaengine_pcm_unregister(*(struct device **)res);
}

/**
 * devm_snd_dmaengine_pcm_register - resource managed dmaengine PCM registration
 * @dev: The parent device for the PCM device
 * @config: Platform specific PCM configuration
 * @flags: Platform specific quirks
 *
 * Register a dmaengine based PCM device with automatic unregistration when the
 * device is unregistered.
 */
int devm_snd_dmaengine_pcm_register(struct device *dev,
	const struct snd_dmaengine_pcm_config *config, unsigned int flags)
{
	struct device **ptr;
	int ret;

	ptr = devres_alloc(devm_dmaengine_pcm_release, sizeof(*ptr), GFP_KERNEL);
	if (!ptr)
		return -ENOMEM;

	ret = snd_dmaengine_pcm_register(dev, config, flags);
	if (ret == 0) {
		*ptr = dev;
		devres_add(dev, ptr);
	} else {
		devres_free(ptr);
	}

	return ret;
}
EXPORT_SYMBOL_GPL(devm_snd_dmaengine_pcm_register);

#endif
Loading