[PATCH v3 0/5] ASoC: fsl: Support register and unregister rpmsg sound card through remoteproc

echo /lib/firmware/fw.elf > /sys/class/remoteproc/remoteproc0/firmware (A) echo start > /sys/class/remoteproc/remoteproc0/state (B) echo stop > /sys/class/remoteproc/remoteproc0/state
The rpmsg sound card is registered in (A) and unregistered in (B). After "start", imx-audio-rpmsg registers devices for ASoC platform driver and machine driver. Then sound card is registered. After "stop", imx-audio-rpmsg unregisters devices for ASoC platform driver and machine driver. Then sound card is unregistered.
changes in v2 - Fix build errors reported by kernel test robot
changes in v3 - Add a new patch for fsl_rpmsg to register CPU DAI with rpmsg channel name - Update imx-rpmsg.c to get DT node of ASoC CPU DAI device with rpmsg channel name instead of using undocumented bindings
Chancel Liu (5): ASoC: fsl: imx-pcm-rpmsg: Register component with rpmsg channel name ASoC: fsl: imx-audio-rpmsg: Register device with rpmsg channel name ASoC: fsl: Let imx-audio-rpmsg register platform device for card ASoC: fsl: fsl_rpmsg: Register CPU DAI with name of rpmsg channel ASoC: fsl: imx-rpmsg: Update to correct DT node
sound/soc/fsl/fsl_rpmsg.c | 43 ++++++++++++++++++++------------- sound/soc/fsl/imx-audio-rpmsg.c | 21 +++++++++++++--- sound/soc/fsl/imx-pcm-rpmsg.c | 11 ++++++--- sound/soc/fsl/imx-rpmsg.c | 28 ++++++++++++++------- 4 files changed, 71 insertions(+), 32 deletions(-)
-- 2.43.0

Machine driver uses rpmsg channel name to link this platform component. However if the component is re-registerd card will not find this new created component in snd_soc_try_rebind_card().
Explicitly register this component with rpmsg channel name so that card can always find this component.
Signed-off-by: Chancel Liu chancel.liu@nxp.com --- sound/soc/fsl/imx-pcm-rpmsg.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/sound/soc/fsl/imx-pcm-rpmsg.c b/sound/soc/fsl/imx-pcm-rpmsg.c index fb9244c1e9c5..b84d1dfddba2 100644 --- a/sound/soc/fsl/imx-pcm-rpmsg.c +++ b/sound/soc/fsl/imx-pcm-rpmsg.c @@ -732,9 +732,6 @@ static int imx_rpmsg_pcm_probe(struct platform_device *pdev) goto fail; }
- /* platform component name is used by machine driver to link with */ - component->name = info->rpdev->id.name; - #ifdef CONFIG_DEBUG_FS component->debugfs_prefix = "rpmsg"; #endif @@ -822,9 +819,17 @@ static const struct dev_pm_ops imx_rpmsg_pcm_pm_ops = { imx_rpmsg_pcm_resume) };
+static const struct platform_device_id imx_rpmsg_pcm_id_table[] = { + { .name = "rpmsg-audio-channel" }, + { .name = "rpmsg-micfil-channel" }, + { }, +}; +MODULE_DEVICE_TABLE(platform, imx_rpmsg_pcm_id_table); + static struct platform_driver imx_pcm_rpmsg_driver = { .probe = imx_rpmsg_pcm_probe, .remove_new = imx_rpmsg_pcm_remove, + .id_table = imx_rpmsg_pcm_id_table, .driver = { .name = IMX_PCM_DRV_NAME, .pm = &imx_rpmsg_pcm_pm_ops,

This rpmsg driver registers device for ASoC platform driver. To align with platform driver use rpmsg channel name to create device.
Signed-off-by: Chancel Liu chancel.liu@nxp.com --- sound/soc/fsl/imx-audio-rpmsg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/fsl/imx-audio-rpmsg.c b/sound/soc/fsl/imx-audio-rpmsg.c index 289e47c03d40..40820d5ad92d 100644 --- a/sound/soc/fsl/imx-audio-rpmsg.c +++ b/sound/soc/fsl/imx-audio-rpmsg.c @@ -87,8 +87,8 @@ static int imx_audio_rpmsg_probe(struct rpmsg_device *rpdev)
/* Register platform driver for rpmsg routine */ data->rpmsg_pdev = platform_device_register_data(&rpdev->dev, - IMX_PCM_DRV_NAME, - PLATFORM_DEVID_AUTO, + rpdev->id.name, + PLATFORM_DEVID_NONE, NULL, 0); if (IS_ERR(data->rpmsg_pdev)) { dev_err(&rpdev->dev, "failed to register rpmsg platform.\n");

Let imx-audio-rpmsg register platform device for card. So that card register and unregister can be controlled by rpmsg driver's register and unregister.
Signed-off-by: Chancel Liu chancel.liu@nxp.com --- sound/soc/fsl/fsl_rpmsg.c | 11 ----------- sound/soc/fsl/imx-audio-rpmsg.c | 17 ++++++++++++++++- 2 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/sound/soc/fsl/fsl_rpmsg.c b/sound/soc/fsl/fsl_rpmsg.c index 00852f174a69..53bd517e59d6 100644 --- a/sound/soc/fsl/fsl_rpmsg.c +++ b/sound/soc/fsl/fsl_rpmsg.c @@ -240,17 +240,6 @@ static int fsl_rpmsg_probe(struct platform_device *pdev) if (ret) goto err_pm_disable;
- rpmsg->card_pdev = platform_device_register_data(&pdev->dev, - "imx-audio-rpmsg", - PLATFORM_DEVID_AUTO, - NULL, - 0); - if (IS_ERR(rpmsg->card_pdev)) { - dev_err(&pdev->dev, "failed to register rpmsg card\n"); - ret = PTR_ERR(rpmsg->card_pdev); - goto err_pm_disable; - } - return 0;
err_pm_disable: diff --git a/sound/soc/fsl/imx-audio-rpmsg.c b/sound/soc/fsl/imx-audio-rpmsg.c index 40820d5ad92d..38aafb8954c7 100644 --- a/sound/soc/fsl/imx-audio-rpmsg.c +++ b/sound/soc/fsl/imx-audio-rpmsg.c @@ -12,6 +12,7 @@ */ struct imx_audio_rpmsg { struct platform_device *rpmsg_pdev; + struct platform_device *card_pdev; };
static int imx_audio_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len, @@ -95,6 +96,16 @@ static int imx_audio_rpmsg_probe(struct rpmsg_device *rpdev) ret = PTR_ERR(data->rpmsg_pdev); }
+ data->card_pdev = platform_device_register_data(&rpdev->dev, + "imx-audio-rpmsg", + PLATFORM_DEVID_AUTO, + rpdev->id.name, + strlen(rpdev->id.name) + 1); + if (IS_ERR(data->card_pdev)) { + dev_err(&rpdev->dev, "failed to register rpmsg card.\n"); + ret = PTR_ERR(data->card_pdev); + } + return ret; }
@@ -105,6 +116,9 @@ static void imx_audio_rpmsg_remove(struct rpmsg_device *rpdev) if (data->rpmsg_pdev) platform_device_unregister(data->rpmsg_pdev);
+ if (data->card_pdev) + platform_device_unregister(data->card_pdev); + dev_info(&rpdev->dev, "audio rpmsg driver is removed\n"); }
@@ -113,6 +127,7 @@ static struct rpmsg_device_id imx_audio_rpmsg_id_table[] = { { .name = "rpmsg-micfil-channel" }, { }, }; +MODULE_DEVICE_TABLE(rpmsg, imx_audio_rpmsg_id_table);
static struct rpmsg_driver imx_audio_rpmsg_driver = { .drv.name = "imx_audio_rpmsg", @@ -126,5 +141,5 @@ module_rpmsg_driver(imx_audio_rpmsg_driver);
MODULE_DESCRIPTION("Freescale SoC Audio RPMSG interface"); MODULE_AUTHOR("Shengjiu Wang shengjiu.wang@nxp.com"); -MODULE_ALIAS("platform:imx_audio_rpmsg"); +MODULE_ALIAS("rpmsg:imx_audio_rpmsg"); MODULE_LICENSE("GPL v2");

Each rpmsg sound card sits on one rpmsg channel. Register CPU DAI with name of rpmsg channel so that ASoC machine driver can easily link CPU DAI with rpmsg channel name.
Signed-off-by: Chancel Liu chancel.liu@nxp.com --- sound/soc/fsl/fsl_rpmsg.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/sound/soc/fsl/fsl_rpmsg.c b/sound/soc/fsl/fsl_rpmsg.c index 53bd517e59d6..bc41a0666856 100644 --- a/sound/soc/fsl/fsl_rpmsg.c +++ b/sound/soc/fsl/fsl_rpmsg.c @@ -135,7 +135,6 @@ static struct snd_soc_dai_driver fsl_rpmsg_dai = {
static const struct snd_soc_component_driver fsl_component = { .name = "fsl-rpmsg", - .legacy_dai_naming = 1, };
static const struct fsl_rpmsg_soc_data imx7ulp_data = { @@ -190,19 +189,40 @@ MODULE_DEVICE_TABLE(of, fsl_rpmsg_ids); static int fsl_rpmsg_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; + struct snd_soc_dai_driver *dai_drv; + const char *dai_name; struct fsl_rpmsg *rpmsg; int ret;
+ dai_drv = devm_kzalloc(&pdev->dev, sizeof(struct snd_soc_dai_driver), GFP_KERNEL); + if (!dai_drv) + return -ENOMEM; + memcpy(dai_drv, &fsl_rpmsg_dai, sizeof(fsl_rpmsg_dai)); + rpmsg = devm_kzalloc(&pdev->dev, sizeof(struct fsl_rpmsg), GFP_KERNEL); if (!rpmsg) return -ENOMEM;
rpmsg->soc_data = of_device_get_match_data(&pdev->dev);
- fsl_rpmsg_dai.playback.rates = rpmsg->soc_data->rates; - fsl_rpmsg_dai.capture.rates = rpmsg->soc_data->rates; - fsl_rpmsg_dai.playback.formats = rpmsg->soc_data->formats; - fsl_rpmsg_dai.capture.formats = rpmsg->soc_data->formats; + if (rpmsg->soc_data) { + dai_drv->playback.rates = rpmsg->soc_data->rates; + dai_drv->capture.rates = rpmsg->soc_data->rates; + dai_drv->playback.formats = rpmsg->soc_data->formats; + dai_drv->capture.formats = rpmsg->soc_data->formats; + } + + /* Use rpmsg channel name as cpu dai name */ + ret = of_property_read_string(np, "fsl,rpmsg-channel-name", &dai_name); + if (ret) { + if (ret == -EINVAL) { + dai_name = "rpmsg-audio-channel"; + } else { + dev_err(&pdev->dev, "Failed to get rpmsg channel name: %d!\n", ret); + return ret; + } + } + dai_drv->name = dai_name;
if (of_property_read_bool(np, "fsl,enable-lpa")) { rpmsg->enable_lpa = 1; @@ -236,7 +256,7 @@ static int fsl_rpmsg_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev);
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component, - &fsl_rpmsg_dai, 1); + dai_drv, 1); if (ret) goto err_pm_disable;

In order to support register and unregister rpmsg sound card through remoteproc platform device for card to probe is registered in imx-audio-rpmsg. ASoC machine driver no longer can get DT node of ASoC CPU DAI device through parent device.
ASoC machine driver can get DT node of ASoC CPU DAI device with rpmsg channel name acquired from platform specific data.
Signed-off-by: Chancel Liu chancel.liu@nxp.com --- sound/soc/fsl/imx-rpmsg.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/sound/soc/fsl/imx-rpmsg.c b/sound/soc/fsl/imx-rpmsg.c index e5bd63dab10c..0f1ad7ad7d27 100644 --- a/sound/soc/fsl/imx-rpmsg.c +++ b/sound/soc/fsl/imx-rpmsg.c @@ -108,10 +108,8 @@ static int imx_rpmsg_late_probe(struct snd_soc_card *card) static int imx_rpmsg_probe(struct platform_device *pdev) { struct snd_soc_dai_link_component *dlc; - struct device *dev = pdev->dev.parent; - /* rpmsg_pdev is the platform device for the rpmsg node that probed us */ - struct platform_device *rpmsg_pdev = to_platform_device(dev); - struct device_node *np = rpmsg_pdev->dev.of_node; + struct snd_soc_dai *cpu_dai; + struct device_node *np = NULL; struct of_phandle_args args; const char *platform_name; struct imx_rpmsg *data; @@ -127,10 +125,6 @@ static int imx_rpmsg_probe(struct platform_device *pdev) goto fail; }
- ret = of_reserved_mem_device_init_by_idx(&pdev->dev, np, 0); - if (ret) - dev_warn(&pdev->dev, "no reserved DMA memory\n"); - data->dai.cpus = &dlc[0]; data->dai.num_cpus = 1; data->dai.platforms = &dlc[1]; @@ -152,6 +146,23 @@ static int imx_rpmsg_probe(struct platform_device *pdev) */ data->dai.ignore_pmdown_time = 1;
+ data->dai.cpus->dai_name = pdev->dev.platform_data; + cpu_dai = snd_soc_find_dai(data->dai.cpus); + if (!cpu_dai) { + ret = -EPROBE_DEFER; + goto fail; + } + np = cpu_dai->dev->of_node; + if (!np) { + dev_err(&pdev->dev, "failed to parse CPU DAI device node\n"); + ret = -ENODEV; + goto fail; + } + + ret = of_reserved_mem_device_init_by_idx(&pdev->dev, np, 0); + if (ret) + dev_warn(&pdev->dev, "no reserved DMA memory\n"); + /* Optional codec node */ ret = of_parse_phandle_with_fixed_args(np, "audio-codec", 0, 0, &args); if (ret) { @@ -170,7 +181,6 @@ static int imx_rpmsg_probe(struct platform_device *pdev) data->sysclk = clk_get_rate(clk); }
- data->dai.cpus->dai_name = dev_name(&rpmsg_pdev->dev); if (!of_property_read_string(np, "fsl,rpmsg-channel-name", &platform_name)) data->dai.platforms->name = platform_name; else

On Mon, Mar 11, 2024 at 7:14 PM Chancel Liu chancel.liu@nxp.com wrote:
echo /lib/firmware/fw.elf > /sys/class/remoteproc/remoteproc0/firmware
(A) echo start > /sys/class/remoteproc/remoteproc0/state (B) echo stop > /sys/class/remoteproc/remoteproc0/state
The rpmsg sound card is registered in (A) and unregistered in (B). After "start", imx-audio-rpmsg registers devices for ASoC platform driver and machine driver. Then sound card is registered. After "stop", imx-audio-rpmsg unregisters devices for ASoC platform driver and machine driver. Then sound card is unregistered.
Acked-by: Shengjiu Wang shengjiu.wang@gmail.com
Best regards Shengjiu Wang
changes in v2
- Fix build errors reported by kernel test robot
changes in v3
- Add a new patch for fsl_rpmsg to register CPU DAI with rpmsg channel name
- Update imx-rpmsg.c to get DT node of ASoC CPU DAI device with rpmsg channel name instead of using undocumented bindings
Chancel Liu (5): ASoC: fsl: imx-pcm-rpmsg: Register component with rpmsg channel name ASoC: fsl: imx-audio-rpmsg: Register device with rpmsg channel name ASoC: fsl: Let imx-audio-rpmsg register platform device for card ASoC: fsl: fsl_rpmsg: Register CPU DAI with name of rpmsg channel ASoC: fsl: imx-rpmsg: Update to correct DT node
sound/soc/fsl/fsl_rpmsg.c | 43 ++++++++++++++++++++------------- sound/soc/fsl/imx-audio-rpmsg.c | 21 +++++++++++++--- sound/soc/fsl/imx-pcm-rpmsg.c | 11 ++++++--- sound/soc/fsl/imx-rpmsg.c | 28 ++++++++++++++------- 4 files changed, 71 insertions(+), 32 deletions(-)
-- 2.43.0

On Mon, 11 Mar 2024 20:13:44 +0900, Chancel Liu wrote:
echo /lib/firmware/fw.elf > /sys/class/remoteproc/remoteproc0/firmware (A) echo start > /sys/class/remoteproc/remoteproc0/state (B) echo stop > /sys/class/remoteproc/remoteproc0/state
The rpmsg sound card is registered in (A) and unregistered in (B). After "start", imx-audio-rpmsg registers devices for ASoC platform driver and machine driver. Then sound card is registered. After "stop", imx-audio-rpmsg unregisters devices for ASoC platform driver and machine driver. Then sound card is unregistered.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/5] ASoC: fsl: imx-pcm-rpmsg: Register component with rpmsg channel name commit: 41f96cd53f2838ac4894491ac5eadb06f1e5b858 [2/5] ASoC: fsl: imx-audio-rpmsg: Register device with rpmsg channel name commit: dacc7459745df168152b5cceba34efade9b5e063 [3/5] ASoC: fsl: Let imx-audio-rpmsg register platform device for card commit: c73524768e9e1a7ac9eb3a4d36a1ac0d34f22644 [4/5] ASoC: fsl: fsl_rpmsg: Register CPU DAI with name of rpmsg channel commit: 0aa7f5406afa828a93d84d75c9b9ac991cd75367 [5/5] ASoC: fsl: imx-rpmsg: Update to correct DT node commit: c14445bdcb98feddf9afaeb05e6193cc1f8eec1a
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (3)
-
Chancel Liu
-
Mark Brown
-
Shengjiu Wang