ASoC: qcom: use correct device pointer in dma allocation

dev pointer in struct snd_soc_pcm_runtime does not have dma_ops set. In
v4.4 kernel dma_ops would end up pointing to dummy_dma_ops in such cases.
So attempting to use such device in allocating coherent memory on aarch64
would fail.

According to commit 1dccb598df ("arm64:
simplify dma_get_ops") The current behavior of dma_get_ops is to fall
back to the global dma_ops when a device has not set its own dma_ops,
but only for DT based systems.

So, this patch fixes the driver to use correct device pointer while
allocating coherent memory, and also deletes un-necessary dma_mask setup
on soc_runtime->dev.

Without this patch lpass driver would fail with below log:
...
[    6.541542]  ADV7533: lpass_platform_alloc_buffer: Could not allocate DMA buffer
[    6.541914] apq8016-lpass-cpu 7708000.lpass-cpu: ASoC: pcm constructor failed: -12
[    6.548216] qcom-apq8016-sbc 7702000.sound: ASoC: can't create pcm ADV7533 :-12
[    6.555581] qcom-apq8016-sbc 7702000.sound: ASoC: failed to instantiate card -12
[    6.566072] qcom-apq8016-sbc: probe of 7702000.sound failed with error -12
...

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Srinivas Kandagatla 2016-01-11 15:17:23 +00:00 коммит произвёл Mark Brown
Родитель 8005c49d9a
Коммит f5f76ea75d
1 изменённых файлов: 6 добавлений и 9 удалений

Просмотреть файл

@ -440,18 +440,18 @@ static irqreturn_t lpass_platform_lpaif_irq(int irq, void *data)
} }
static int lpass_platform_alloc_buffer(struct snd_pcm_substream *substream, static int lpass_platform_alloc_buffer(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *soc_runtime) struct snd_soc_pcm_runtime *rt)
{ {
struct snd_dma_buffer *buf = &substream->dma_buffer; struct snd_dma_buffer *buf = &substream->dma_buffer;
size_t size = lpass_platform_pcm_hardware.buffer_bytes_max; size_t size = lpass_platform_pcm_hardware.buffer_bytes_max;
buf->dev.type = SNDRV_DMA_TYPE_DEV; buf->dev.type = SNDRV_DMA_TYPE_DEV;
buf->dev.dev = soc_runtime->dev; buf->dev.dev = rt->platform->dev;
buf->private_data = NULL; buf->private_data = NULL;
buf->area = dma_alloc_coherent(soc_runtime->dev, size, &buf->addr, buf->area = dma_alloc_coherent(rt->platform->dev, size, &buf->addr,
GFP_KERNEL); GFP_KERNEL);
if (!buf->area) { if (!buf->area) {
dev_err(soc_runtime->dev, "%s: Could not allocate DMA buffer\n", dev_err(rt->platform->dev, "%s: Could not allocate DMA buffer\n",
__func__); __func__);
return -ENOMEM; return -ENOMEM;
} }
@ -461,12 +461,12 @@ static int lpass_platform_alloc_buffer(struct snd_pcm_substream *substream,
} }
static void lpass_platform_free_buffer(struct snd_pcm_substream *substream, static void lpass_platform_free_buffer(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *soc_runtime) struct snd_soc_pcm_runtime *rt)
{ {
struct snd_dma_buffer *buf = &substream->dma_buffer; struct snd_dma_buffer *buf = &substream->dma_buffer;
if (buf->area) { if (buf->area) {
dma_free_coherent(soc_runtime->dev, buf->bytes, buf->area, dma_free_coherent(rt->dev, buf->bytes, buf->area,
buf->addr); buf->addr);
} }
buf->area = NULL; buf->area = NULL;
@ -499,9 +499,6 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
snd_soc_pcm_set_drvdata(soc_runtime, data); snd_soc_pcm_set_drvdata(soc_runtime, data);
soc_runtime->dev->coherent_dma_mask = DMA_BIT_MASK(32);
soc_runtime->dev->dma_mask = &soc_runtime->dev->coherent_dma_mask;
ret = lpass_platform_alloc_buffer(substream, soc_runtime); ret = lpass_platform_alloc_buffer(substream, soc_runtime);
if (ret) if (ret)
return ret; return ret;