[alsa-devel] [PATCH 07/10] ASoC: ux500: Store DMA data in the DAI differently in the pdata and DT case
In this patch we do two things. Firstly, instead of open coding the store of DMA data in to the DAI for later use, we use the API provided. Secondly we create and store similar DMA data for the DT case, only this time we use 'struct snd_dmaengine_dai_dma_data' which is provided by the core for this very reason.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Acked-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org --- sound/soc/ux500/ux500_msp_dai.c | 42 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-)
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index c6fb5cc..8d1b01f 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c @@ -17,12 +17,14 @@ #include <linux/bitops.h> #include <linux/platform_device.h> #include <linux/clk.h> +#include <linux/of.h> #include <linux/regulator/consumer.h> #include <linux/mfd/dbx500-prcmu.h> #include <linux/platform_data/asoc-ux500-msp.h>
#include <sound/soc.h> #include <sound/soc-dai.h> +#include <sound/dmaengine_pcm.h>
#include "ux500_msp_i2s.h" #include "ux500_msp_dai.h" @@ -654,16 +656,52 @@ static int ux500_msp_dai_trigger(struct snd_pcm_substream *substream, return ret; }
+static int ux500_msp_dai_of_probe(struct snd_soc_dai *dai) +{ + struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); + struct snd_dmaengine_dai_dma_data *playback_dma_data; + struct snd_dmaengine_dai_dma_data *capture_dma_data; + + playback_dma_data = devm_kzalloc(dai->dev, + sizeof(*playback_dma_data), + GFP_KERNEL); + if (!playback_dma_data) + return -ENOMEM; + + capture_dma_data = devm_kzalloc(dai->dev, + sizeof(*capture_dma_data), + GFP_KERNEL); + if (!capture_dma_data) + return -ENOMEM; + + playback_dma_data->addr = drvdata->msp->playback_dma_data.tx_rx_addr; + capture_dma_data->addr = drvdata->msp->capture_dma_data.tx_rx_addr; + + playback_dma_data->maxburst = 4; + capture_dma_data->maxburst = 4; + + snd_soc_dai_init_dma_data(dai, playback_dma_data, capture_dma_data); + + return 0; +} + static int ux500_msp_dai_probe(struct snd_soc_dai *dai) { struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); + struct device_node *np = dai->dev->of_node; + int ret;
- dai->playback_dma_data = &drvdata->msp->playback_dma_data; - dai->capture_dma_data = &drvdata->msp->capture_dma_data; + if (np) { + ret = ux500_msp_dai_of_probe(dai); + return ret; + }
drvdata->msp->playback_dma_data.data_size = drvdata->slot_width; drvdata->msp->capture_dma_data.data_size = drvdata->slot_width;
+ snd_soc_dai_init_dma_data(dai, + &drvdata->msp->playback_dma_data, + &drvdata->msp->capture_dma_data); return 0; }
On Tue, Nov 19, 2013 at 11:07:46AM +0000, Lee Jones wrote:
In this patch we do two things. Firstly, instead of open coding the store of DMA data in to the DAI for later use, we use the API provided. Secondly we create and store similar DMA data for the DT case, only this time we use 'struct snd_dmaengine_dai_dma_data' which is provided by the core for this very reason.
Applied, thanks.
Hi,
On Tue, Nov 19, 2013 at 3:07 AM, Lee Jones lee.jones@linaro.org wrote:
In this patch we do two things. Firstly, instead of open coding the store of DMA data in to the DAI for later use, we use the API provided. Secondly we create and store similar DMA data for the DT case, only this time we use 'struct snd_dmaengine_dai_dma_data' which is provided by the core for this very reason.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Acked-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org
Seems like this hit -next for the first time today, and it panics snowball on boot of u8500_defconfig. I bisected down to this patch.
The panic is below. Last output is the dev_dbg() in ux500_pcm_request_chan. dma_cfg seems to be 0x0000004(!) at that point. It's indeed crashing on first deref of dma_cfg (confirmed via addr2line).
ux500-msp-i2s ux500-msp-i2s.1: ux500_pcm_request_chan: MSP 1 (Playback): Enter. Unable to handle kernel NULL pointer dereference at virtual address 0000002c pgd = c0004000 [0000002c] *pgd=00000000 Internal error: Oops: 805 [#1] PREEMPT SMP ARM Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.13.0-rc1-00003-g6bcb570-dirty #19 task: ef060000 ti: ef04a000 task.ti: ef04a000 PC is at ux500_pcm_request_chan+0xbc/0xe4 LR is at ux500_pcm_request_chan+0x8c/0xe4 pc : [<c02edf00>] lr : [<c02eded0>] psr: 60000113 sp : ef04bd10 ip : 00000001 fp : 00020000 r10: ef20be10 r9 : 00800000 r8 : ef1ec010 r7 : ef20be10 r6 : ef0e5c90 r5 : 00000004 r4 : ef1f6800 r3 : 00000004 r2 : 00000000 r1 : 00000004 r0 : c01ed7d4 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c5787d Table: 0000404a DAC: 00000015 Process swapper/0 (pid: 1, stack limit = 0xef04a240) Stack: (0xef04bd10 to 0xef04c000) bd00: ef1f6800 c04b8e9c 00000000 00000000 bd20: ef1f6800 ef1b80c0 ef1b80cc c02eaa44 00000001 ef1b80cc ef1b8000 ef1ec010 bd40: 00000000 00000001 ef1b80cc ef1b8000 ef226d80 00000000 ef04bd70 c02e98a0 bd60: 00000000 ef04bd6c ef0e6100 ef1f6c00 35386261 305f3030 38626120 2d303035 bd80: 65646f63 61642d63 2d302e69 00000030 ef0e6100 ef0e6100 ef0e5e40 ef0e6100 bda0: 00000000 ef0e5e40 c056c630 c00fc240 00000000 c056c4a0 ef1ec010 ef1b8000 bdc0: c056c630 ef226d80 00000000 00000000 00000002 c02dfdec c056c4b0 00000000 bde0: eec10088 c0569050 00000000 c056c5a8 c056c598 c0569050 c0569090 c02da820 be00: c00303a8 ef1f7400 c056c580 c0569050 c04b7ec4 c056c4c0 c022147c c056c4a0 be20: 000005b8 c104138c c10415e4 ef221e10 00000069 ef04a030 00000000 c02e01a4 be40: c056c448 c1041df4 c104138c c10415e4 ef221e10 c02ee0b8 ef221e10 c056c45c be60: 00000000 c056c45c c052d958 c0220860 c0220848 ef221e10 c05a1f3c c021f0dc be80: 00000000 ef221e10 c056c45c ef221e44 00000000 c021f2c8 00000000 c056c45c bea0: c021f23c c021d70c ef03065c ef1a9db4 c056c45c ef1e3200 c055e4d8 c021e8a4 bec0: c04bbd08 c056c45c 00000006 c056c45c 00000006 c0572680 c0572680 c021f8ac bee0: 00000000 c053de50 00000006 c0008870 ef010900 c04846d4 ef09a100 c03b54e8 bf00: 00000000 c0572680 0000150c c00f3c6c 00000000 c054edd0 a0000013 00000001 bf20: c104273d c03c868c 00000069 c0035398 c04ee1bc 00000006 c1042748 00000006 bf40: c054edc0 c053de50 00000006 c0572680 c0572680 c051150c 00000069 c0535bdc bf60: c0535bd0 c0511c30 00000006 00000006 c051150c 00000000 80000000 10000000 bf80: 00000000 00000000 c03aa2ac 00000000 00000000 00000000 00000000 00000000 bfa0: 00000000 c03aa2b4 00000000 c000e478 00000000 00000000 00000000 00000000 bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000002 00000000 [<c02edf00>] (ux500_pcm_request_chan+0xbc/0xe4) from [<c02eaa44>] (dmaengine_pcm_new+0x16c/0x1a0) [<c02eaa44>] (dmaengine_pcm_new+0x16c/0x1a0) from [<c02e98a0>] (soc_new_pcm+0x2bc/0x3c8) [<c02e98a0>] (soc_new_pcm+0x2bc/0x3c8) from [<c02dfdec>] (snd_soc_instantiate_card+0xff0/0x113c) [<c02dfdec>] (snd_soc_instantiate_card+0xff0/0x113c) from [<c02e01a4>] (snd_soc_register_card+0x26c/0x3a4) [<c02e01a4>] (snd_soc_register_card+0x26c/0x3a4) from [<c02ee0b8>] (mop500_probe+0xe0/0x128) [<c02ee0b8>] (mop500_probe+0xe0/0x128) from [<c0220860>] (platform_drv_probe+0x18/0x48) [<c0220860>] (platform_drv_probe+0x18/0x48) from [<c021f0dc>] (driver_probe_device+0x124/0x240) [<c021f0dc>] (driver_probe_device+0x124/0x240) from [<c021f2c8>] (__driver_attach+0x8c/0x90) [<c021f2c8>] (__driver_attach+0x8c/0x90) from [<c021d70c>] (bus_for_each_dev+0x60/0x94) [<c021d70c>] (bus_for_each_dev+0x60/0x94) from [<c021e8a4>] (bus_add_driver+0x148/0x1f0) [<c021e8a4>] (bus_add_driver+0x148/0x1f0) from [<c021f8ac>] (driver_register+0x78/0xf8) [<c021f8ac>] (driver_register+0x78/0xf8) from [<c0008870>] (do_one_initcall+0x100/0x14c) [<c0008870>] (do_one_initcall+0x100/0x14c) from [<c0511c30>] (kernel_init_freeable+0x138/0x1d8) [<c0511c30>] (kernel_init_freeable+0x138/0x1d8) from [<c03aa2b4>] (kernel_init+0x8/0x120) [<c03aa2b4>] (kernel_init+0x8/0x120) from [<c000e478>] (ret_from_fork+0x14/0x3c) Code: e1a01005 e30d07d4 e34c001e e3520000 (05853028)
I'm out of time to debug this more until tomorrow night or possibly later, so I figured I'd report it at least.
-Olof
On Sun, 01 Dec 2013, Olof Johansson wrote:
Hi,
On Tue, Nov 19, 2013 at 3:07 AM, Lee Jones lee.jones@linaro.org wrote:
In this patch we do two things. Firstly, instead of open coding the store of DMA data in to the DAI for later use, we use the API provided. Secondly we create and store similar DMA data for the DT case, only this time we use 'struct snd_dmaengine_dai_dma_data' which is provided by the core for this very reason.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Acked-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org
Seems like this hit -next for the first time today, and it panics snowball on boot of u8500_defconfig. I bisected down to this patch.
The panic is below. Last output is the dev_dbg() in ux500_pcm_request_chan. dma_cfg seems to be 0x0000004(!) at that point. It's indeed crashing on first deref of dma_cfg (confirmed via addr2line).
Okay, I just debugged this.
It's actually my fault. I had two patches round the wrong way in the series. The imediately subsequent patch in the set fixes this issue:
Author: Lee Jones lee.jones@linaro.org Date: Tue Nov 5 22:57:31 2013 +0000
ASoC: ux500_pcm: Differentiate between pdata and DT initialisation
If booting with full DT support (i.e. DMA too, the last piece of the puzzle), then we don't need to use the compatible request channel call back and, due to the work we laid down earlier in this patch-set, we can use core function calls to populate the DMA slave_config. We also require slightly different flags to inform the core that we 'are' booting with DT.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Acked-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index ce554de..acfec98 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -139,15 +139,33 @@ static const struct snd_dmaengine_pcm_config ux500_dmaengine_pcm_config = { .prepare_slave_config = ux500_pcm_prepare_slave_config, };
+static const struct snd_dmaengine_pcm_config ux500_dmaengine_of_pcm_config = { + .pcm_hardware = &ux500_pcm_hw, + .prealloc_buffer_size = 128 * 1024, + .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, +}; + int ux500_pcm_register_platform(struct platform_device *pdev) { + const struct snd_dmaengine_pcm_config *pcm_config; + struct device_node *np = pdev->dev.of_node; + unsigned int pcm_flags; int ret;
- ret = snd_dmaengine_pcm_register(&pdev->dev, - &ux500_dmaengine_pcm_config, - SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | - SND_DMAENGINE_PCM_FLAG_COMPAT | - SND_DMAENGINE_PCM_FLAG_NO_DT); + if (np) { + pcm_config = &ux500_dmaengine_of_pcm_config; + + pcm_flags = SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | + SND_DMAENGINE_PCM_FLAG_COMPAT; + } else { + pcm_config = &ux500_dmaengine_pcm_config; + + pcm_flags = SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | + SND_DMAENGINE_PCM_FLAG_NO_DT | + SND_DMAENGINE_PCM_FLAG_COMPAT; + } + + ret = snd_dmaengine_pcm_register(&pdev->dev, pcm_config, pcm_flags); if (ret < 0) { dev_err(&pdev->dev, "%s: ERROR: Failed to register platform '%s' (%d)!\n",
On Mon, Dec 02, 2013 at 10:12:56AM +0000, Lee Jones wrote:
It's actually my fault. I had two patches round the wrong way in the series. The imediately subsequent patch in the set fixes this issue:
OK, so what do we do about this? Is there going to be a revision of that patch adding the note about not using the autoconfiguration stuff and what (if any) are the dependencies on the arch/arm changes?
On Mon, 02 Dec 2013, Mark Brown wrote:
On Mon, Dec 02, 2013 at 10:12:56AM +0000, Lee Jones wrote:
It's actually my fault. I had two patches round the wrong way in the series. The imediately subsequent patch in the set fixes this issue:
OK, so what do we do about this? Is there going to be a revision of that patch adding the note about not using the autoconfiguration stuff and what (if any) are the dependencies on the arch/arm changes?
I can shoot out a revision no problem.
I'm not aware of any dependencies on the ARM changes. I haven't tested the arch/arm and sound/soc adaptions orthogonally, but I _think_ the right decisions should be made depending on the information passed from platform/dt code.
On Mon, Dec 02, 2013 at 02:03:24PM +0000, Lee Jones wrote:
I'm not aware of any dependencies on the ARM changes. I haven't tested the arch/arm and sound/soc adaptions orthogonally, but I _think_ the right decisions should be made depending on the information passed from platform/dt code.
OK, that sounds great thanks.
On Tue, Nov 19, 2013 at 3:07 AM, Lee Jones lee.jones@linaro.org wrote:
In this patch we do two things. Firstly, instead of open coding the store of DMA data in to the DAI for later use, we use the API provided. Secondly we create and store similar DMA data for the DT case, only this time we use 'struct snd_dmaengine_dai_dma_data' which is provided by the core for this very reason.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Acked-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org
sound/soc/ux500/ux500_msp_dai.c | 42 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-)
Today's next (next-20131204) has a new boot failure[1] on ux500/snowball which bisected down to this commit. Full boot log attached.
It doesn't find the alsa device which in turn seems to prevent the emmc rootfs from being mounted. It boots fine to an initramfs.
Kevin
[1] http://lists.linaro.org/pipermail/kernel-build-reports/2013-December/001382....
Today's next (next-20131204) has a new boot failure[1] on ux500/snowball which bisected down to this commit. Full boot log attached.
Right.
Anyone not on CC (which I think you are Kevin) can follow the fun here: http://www.spinics.net/lists/arm-kernel/msg291374.html
It doesn't find the alsa device which in turn seems to prevent the emmc rootfs from being mounted. It boots fine to an initramfs.
<snip>
of_dma_request_slave_channel: dma-names property of node '/soc/msp@80124000' missing or empty of_dma_request_slave_channel: dma-names property of node '/soc/msp@80124000' missing or empty of_dma_request_slave_channel: dma-names property of node '/soc/msp@80125000' missing or empty mmc1: new high speed MMC card at address 0001 of_dma_request_slave_channel: dma-names property of node '/soc/msp@80125000' missing or empty mmcblk0: mmc1:0001 7.28 GiB mmcblk0boot0: mmc1:0001 partition 1 2.00 MiB mmcblk0boot1: mmc1:0001 partition 2 2.00 MiB mmcblk0rpmb: mmc1:0001 partition 3 128 KiB dma dma0chan22: [d40_config_memcpy] No memcpy dma dma0chan22: [d40_alloc_chan_resources] Failed to configure memcpy channel ux500-msp-i2s ux500-msp-i2s.1: Missing dma channel for stream: 0 ux500-msp-i2s ux500-msp-i2s.1: ASoC: pcm constructor failed: -22 snd-soc-mop500 snd-soc-mop500.0: ASoC: can't create pcm ab8500_0 :-22 snd-soc-mop500 snd-soc-mop500.0: ASoC: failed to instantiate card -22 snd-soc-mop500 snd-soc-mop500.0: Error: snd_soc_register_card failed (-22)! snd-soc-mop500: probe of snd-soc-mop500.0 failed with error -22
<snip>
mmci-pl18x sdi4: error during DMA transfer! mmcblk0rpmb: error -110 transferring data, sector 0, nr 8, cmd response 0x900, card status 0x0 mmcblk0rpmb: retrying using single block read
It's interesting that the MSP failure has managed to fudge the entire DMA Controller. I have absolutely no idea how that can even happen?
participants (4)
-
Kevin Hilman
-
Lee Jones
-
Mark Brown
-
Olof Johansson