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:
Родитель
8005c49d9a
Коммит
f5f76ea75d
|
@ -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;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче