Message ID | 20201005182446.977325-3-david.m.ertman@intel.com |
---|---|
State | New |
Headers | show |
Series | Ancillary bus implementation and SOF multi-client support | expand |
On 10/5/20 11:24 AM, Dave Ertman wrote: > diff --git a/sound/soc/sof/Kconfig b/sound/soc/sof/Kconfig > index 4dda4b62509f..cea7efedafef 100644 > --- a/sound/soc/sof/Kconfig > +++ b/sound/soc/sof/Kconfig > @@ -50,6 +50,24 @@ config SND_SOC_SOF_DEBUG_PROBES > Say Y if you want to enable probes. > If unsure, select "N". > > +config SND_SOC_SOF_CLIENT > + tristate > + select ANCILLARY_BUS > + help > + This option is not user-selectable but automagically handled by > + 'select' statements at a higher level > + > +config SND_SOC_SOF_CLIENT_SUPPORT > + bool "SOF enable clients" Tell users what "SOF" means. > + depends on SND_SOC_SOF > + help > + This adds support for ancillary client devices to separate out the debug > + functionality for IPC tests, probes etc. into separate devices. This > + option would also allow adding client devices based on DSP FW spell out firmware > + capabilities and ACPI/OF device information. > + Say Y if you want to enable clients with SOF. > + If unsure select "N". > +
>> +config SND_SOC_SOF_CLIENT >> + tristate >> + select ANCILLARY_BUS >> + help >> + This option is not user-selectable but automagically handled by >> + 'select' statements at a higher level >> + >> +config SND_SOC_SOF_CLIENT_SUPPORT >> + bool "SOF enable clients" > > Tell users what "SOF" means. This option can only be reached if the user already selected the topic-level option. From there on the SOF acronym is used. Is this not enough? config SND_SOC_SOF_TOPLEVEL bool "Sound Open Firmware Support" help This adds support for Sound Open Firmware (SOF). SOF is a free and generic open source audio DSP firmware for multiple devices. Say Y if you have such a device that is supported by SOF. > >> + depends on SND_SOC_SOF >> + help >> + This adds support for ancillary client devices to separate out the debug >> + functionality for IPC tests, probes etc. into separate devices. This >> + option would also allow adding client devices based on DSP FW > > spell out firmware agree on this one. > >> + capabilities and ACPI/OF device information. >> + Say Y if you want to enable clients with SOF. >> + If unsure select "N". >> + > >
On 10/12/20 6:31 PM, Pierre-Louis Bossart wrote: > >>> +config SND_SOC_SOF_CLIENT >>> + tristate >>> + select ANCILLARY_BUS >>> + help >>> + This option is not user-selectable but automagically handled by >>> + 'select' statements at a higher level >>> + >>> +config SND_SOC_SOF_CLIENT_SUPPORT >>> + bool "SOF enable clients" >> >> Tell users what "SOF" means. > > This option can only be reached if the user already selected the topic-level option. From there on the SOF acronym is used. Is this not enough? Yes, that's enough. I didn't see it. Sorry about that. > config SND_SOC_SOF_TOPLEVEL > bool "Sound Open Firmware Support" > help > This adds support for Sound Open Firmware (SOF). SOF is a free and > generic open source audio DSP firmware for multiple devices. > Say Y if you have such a device that is supported by SOF. > >> >>> + depends on SND_SOC_SOF >>> + help >>> + This adds support for ancillary client devices to separate out the debug >>> + functionality for IPC tests, probes etc. into separate devices. This >>> + option would also allow adding client devices based on DSP FW >> >> spell out firmware > > agree on this one. > >> >>> + capabilities and ACPI/OF device information. >>> + Say Y if you want to enable clients with SOF. >>> + If unsure select "N". >>> + >> >> thanks.
On 10/12/20 6:55 PM, Randy Dunlap wrote: > On 10/12/20 6:31 PM, Pierre-Louis Bossart wrote: >> >>>> +config SND_SOC_SOF_CLIENT >>>> + tristate >>>> + select ANCILLARY_BUS >>>> + help >>>> + This option is not user-selectable but automagically handled by >>>> + 'select' statements at a higher level >>>> + >>>> +config SND_SOC_SOF_CLIENT_SUPPORT >>>> + bool "SOF enable clients" >>> >>> Tell users what "SOF" means. >> >> This option can only be reached if the user already selected the topic-level option. From there on the SOF acronym is used. Is this not enough? > > Yes, that's enough. I didn't see it. Sorry about that. Huh. I still don't see that Kconfig option. Which patch is it in? I only saw patches 1,2,3 on LKML. >> config SND_SOC_SOF_TOPLEVEL >> bool "Sound Open Firmware Support" >> help >> This adds support for Sound Open Firmware (SOF). SOF is a free and >> generic open source audio DSP firmware for multiple devices. >> Say Y if you have such a device that is supported by SOF. >> >>> >>>> + depends on SND_SOC_SOF >>>> + help >>>> + This adds support for ancillary client devices to separate out the debug >>>> + functionality for IPC tests, probes etc. into separate devices. This >>>> + option would also allow adding client devices based on DSP FW >>> >>> spell out firmware >> >> agree on this one. >> >>> >>>> + capabilities and ACPI/OF device information. >>>> + Say Y if you want to enable clients with SOF. >>>> + If unsure select "N". >>>> + >>> >>> > > thanks. >
>>>>> +config SND_SOC_SOF_CLIENT >>>>> + tristate >>>>> + select ANCILLARY_BUS >>>>> + help >>>>> + This option is not user-selectable but automagically handled by >>>>> + 'select' statements at a higher level >>>>> + >>>>> +config SND_SOC_SOF_CLIENT_SUPPORT >>>>> + bool "SOF enable clients" >>>> >>>> Tell users what "SOF" means. >>> >>> This option can only be reached if the user already selected the topic-level option. From there on the SOF acronym is used. Is this not enough? >> >> Yes, that's enough. I didn't see it. Sorry about that. > > Huh. I still don't see that Kconfig option. > Which patch is it in? > > I only saw patches 1,2,3 on LKML. The Sound Open Firmware (SOF) driver is upstream since 2019, see https://elixir.bootlin.com/linux/latest/source/sound/soc/sof/Kconfig What was shared in these patches is just an evolution to make the driver more modular to handle of 'subfunctions' with the auxiliary bus. we'd love to hear your feedback if you think the help text can be improved. Thanks!
On 10/13/20 8:08 AM, Pierre-Louis Bossart wrote: > >>>>>> +config SND_SOC_SOF_CLIENT >>>>>> + tristate >>>>>> + select ANCILLARY_BUS >>>>>> + help >>>>>> + This option is not user-selectable but automagically handled by >>>>>> + 'select' statements at a higher level >>>>>> + >>>>>> +config SND_SOC_SOF_CLIENT_SUPPORT >>>>>> + bool "SOF enable clients" >>>>> >>>>> Tell users what "SOF" means. >>>> >>>> This option can only be reached if the user already selected the topic-level option. From there on the SOF acronym is used. Is this not enough? >>> >>> Yes, that's enough. I didn't see it. Sorry about that. >> >> Huh. I still don't see that Kconfig option. >> Which patch is it in? >> >> I only saw patches 1,2,3 on LKML. > > The Sound Open Firmware (SOF) driver is upstream since 2019, see https://elixir.bootlin.com/linux/latest/source/sound/soc/sof/Kconfig > > What was shared in these patches is just an evolution to make the driver more modular to handle of 'subfunctions' with the auxiliary bus. > > we'd love to hear your feedback if you think the help text can be improved. Thanks! > OK, I looked at the SOF Kconfig files. They are mostly OK except for missing '.' at the end of lots of sentences and a few other typos. Do you want patches?
>>>>>>> +config SND_SOC_SOF_CLIENT_SUPPORT >>>>>>> + bool "SOF enable clients" >>>>>> >>>>>> Tell users what "SOF" means. >>>>> >>>>> This option can only be reached if the user already selected the topic-level option. From there on the SOF acronym is used. Is this not enough? >>>> >>>> Yes, that's enough. I didn't see it. Sorry about that. >>> >>> Huh. I still don't see that Kconfig option. >>> Which patch is it in? >>> >>> I only saw patches 1,2,3 on LKML. >> >> The Sound Open Firmware (SOF) driver is upstream since 2019, see https://elixir.bootlin.com/linux/latest/source/sound/soc/sof/Kconfig >> >> What was shared in these patches is just an evolution to make the driver more modular to handle of 'subfunctions' with the auxiliary bus. >> >> we'd love to hear your feedback if you think the help text can be improved. Thanks! >> > > OK, I looked at the SOF Kconfig files. They are mostly OK except for > missing '.' at the end of lots of sentences and a few other typos. > > Do you want patches? Sure! Thanks in advance.
diff --git a/sound/soc/sof/Kconfig b/sound/soc/sof/Kconfig index 4dda4b62509f..cea7efedafef 100644 --- a/sound/soc/sof/Kconfig +++ b/sound/soc/sof/Kconfig @@ -50,6 +50,24 @@ config SND_SOC_SOF_DEBUG_PROBES Say Y if you want to enable probes. If unsure, select "N". +config SND_SOC_SOF_CLIENT + tristate + select ANCILLARY_BUS + help + This option is not user-selectable but automagically handled by + 'select' statements at a higher level + +config SND_SOC_SOF_CLIENT_SUPPORT + bool "SOF enable clients" + depends on SND_SOC_SOF + help + This adds support for ancillary client devices to separate out the debug + functionality for IPC tests, probes etc. into separate devices. This + option would also allow adding client devices based on DSP FW + capabilities and ACPI/OF device information. + Say Y if you want to enable clients with SOF. + If unsure select "N". + config SND_SOC_SOF_DEVELOPER_SUPPORT bool "SOF developer options support" depends on EXPERT @@ -186,6 +204,7 @@ endif ## SND_SOC_SOF_DEVELOPER_SUPPORT config SND_SOC_SOF tristate + select SND_SOC_SOF_CLIENT if SND_SOC_SOF_CLIENT_SUPPORT select SND_SOC_TOPOLOGY select SND_SOC_SOF_NOCODEC if SND_SOC_SOF_NOCODEC_SUPPORT help diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index 05718dfe6cd2..5e46f25a3851 100644 --- a/sound/soc/sof/Makefile +++ b/sound/soc/sof/Makefile @@ -2,6 +2,7 @@ snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\ control.o trace.o utils.o sof-audio.o +snd-sof-client-objs := sof-client.o snd-sof-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += probe.o compress.o snd-sof-pci-objs := sof-pci-dev.o @@ -18,6 +19,8 @@ obj-$(CONFIG_SND_SOC_SOF_ACPI) += snd-sof-acpi.o obj-$(CONFIG_SND_SOC_SOF_OF) += snd-sof-of.o obj-$(CONFIG_SND_SOC_SOF_PCI) += snd-sof-pci.o +obj-$(CONFIG_SND_SOC_SOF_CLIENT) += snd-sof-client.o + obj-$(CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL) += intel/ obj-$(CONFIG_SND_SOC_SOF_IMX_TOPLEVEL) += imx/ obj-$(CONFIG_SND_SOC_SOF_XTENSA) += xtensa/ diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index adc7c37145d6..72a97219395f 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -314,8 +314,10 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) INIT_LIST_HEAD(&sdev->widget_list); INIT_LIST_HEAD(&sdev->dai_list); INIT_LIST_HEAD(&sdev->route_list); + INIT_LIST_HEAD(&sdev->client_list); spin_lock_init(&sdev->ipc_lock); spin_lock_init(&sdev->hw_lock); + mutex_init(&sdev->client_mutex); if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) INIT_WORK(&sdev->probe_work, sof_probe_work); diff --git a/sound/soc/sof/sof-client.c b/sound/soc/sof/sof-client.c new file mode 100644 index 000000000000..8d861686bdc2 --- /dev/null +++ b/sound/soc/sof/sof-client.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2020 Intel Corporation. All rights reserved. +// +// Author: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> +// + +#include <linux/debugfs.h> +#include <linux/errno.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/slab.h> +#include "sof-client.h" +#include "sof-priv.h" + +static void sof_client_ancildev_release(struct device *dev) +{ + struct ancillary_device *ancildev = to_ancillary_dev(dev); + struct sof_client_dev *cdev = ancillary_dev_to_sof_client_dev(ancildev); + + ida_simple_remove(cdev->client_ida, ancildev->id); + kfree(cdev); +} + +static struct sof_client_dev *sof_client_dev_alloc(struct snd_sof_dev *sdev, const char *name, + struct ida *client_ida) +{ + struct sof_client_dev *cdev; + struct ancillary_device *ancildev; + int ret; + + cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + if (!cdev) + return ERR_PTR(-ENOMEM); + + cdev->sdev = sdev; + cdev->client_ida = client_ida; + ancildev = &cdev->ancildev; + ancildev->name = name; + ancildev->dev.parent = sdev->dev; + ancildev->dev.release = sof_client_ancildev_release; + + ancildev->id = ida_alloc(client_ida, GFP_KERNEL); + if (ancildev->id < 0) { + dev_err(sdev->dev, "error: get IDA idx for ancillary device %s failed\n", name); + ret = ancildev->id; + goto err_free; + } + + ret = ancillary_device_initialize(ancildev); + if (ret < 0) { + dev_err(sdev->dev, "error: failed to initialize client dev %s\n", name); + goto ida_free; + } + + return cdev; +ida_free: + ida_simple_remove(client_ida, ancildev->id); +err_free: + kfree(cdev); + return NULL; +} + +int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name, + struct ida *client_ida) +{ + struct sof_client_dev *cdev; + int ret; + + cdev = sof_client_dev_alloc(sdev, name, client_ida); + if (IS_ERR_OR_NULL(cdev)) + return PTR_ERR(cdev); + + ret = ancillary_device_add(&cdev->ancildev); + if (ret < 0) { + dev_err(sdev->dev, "error: failed to add client dev %s\n", name); + put_device(&cdev->ancildev.dev); + return ret; + } + + /* add to list of SOF client devices */ + mutex_lock(&sdev->client_mutex); + list_add(&cdev->list, &sdev->client_list); + mutex_unlock(&sdev->client_mutex); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(sof_client_dev_register, SND_SOC_SOF_CLIENT); + +void sof_client_dev_unregister(struct sof_client_dev *cdev) +{ + struct snd_sof_dev *sdev = cdev->sdev; + + lockdep_assert_held(&sdev->client_mutex); + + /* remove from list of SOF client devices */ + list_del(&cdev->list); + + /* cdev will be freed when the release callback for the ancillary device is invoked */ + ancillary_device_unregister(&cdev->ancildev); +} +EXPORT_SYMBOL_NS_GPL(sof_client_dev_unregister, SND_SOC_SOF_CLIENT); + +int sof_client_ipc_tx_message(struct sof_client_dev *cdev, u32 header, void *msg_data, + size_t msg_bytes, void *reply_data, size_t reply_bytes) +{ + return sof_ipc_tx_message(cdev->sdev->ipc, header, msg_data, msg_bytes, + reply_data, reply_bytes); +} +EXPORT_SYMBOL_NS_GPL(sof_client_ipc_tx_message, SND_SOC_SOF_CLIENT); + +struct dentry *sof_client_get_debugfs_root(struct sof_client_dev *cdev) +{ + return cdev->sdev->debugfs_root; +} +EXPORT_SYMBOL_NS_GPL(sof_client_get_debugfs_root, SND_SOC_SOF_CLIENT); + +MODULE_LICENSE("GPL"); diff --git a/sound/soc/sof/sof-client.h b/sound/soc/sof/sof-client.h new file mode 100644 index 000000000000..0a67f0211074 --- /dev/null +++ b/sound/soc/sof/sof-client.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOUND_SOC_SOF_CLIENT_H +#define __SOUND_SOC_SOF_CLIENT_H + +#include <linux/ancillary_bus.h> +#include <linux/device.h> +#include <linux/idr.h> +#include <linux/list.h> + +#define SOF_CLIENT_PROBE_TIMEOUT_MS 2000 + +struct snd_sof_dev; + +/* SOF client device */ +struct sof_client_dev { + struct ancillary_device ancildev; + struct snd_sof_dev *sdev; + struct list_head list; /* item in SOF core client dev list */ + struct ida *client_ida; + void *data; +}; + +/* client-specific ops, all optional */ +struct sof_client_ops { + int (*client_ipc_rx)(struct sof_client_dev *cdev, u32 msg_cmd); +}; + +struct sof_client_drv { + const char *name; + const struct sof_client_ops ops; + struct ancillary_driver ancillary_drv; +}; + +#define ancillary_dev_to_sof_client_dev(ancillary_dev) \ + container_of(ancillary_dev, struct sof_client_dev, ancildev) + +static inline int sof_client_drv_register(struct sof_client_drv *drv) +{ + return ancillary_driver_register(&drv->ancillary_drv); +} + +static inline void sof_client_drv_unregister(struct sof_client_drv *drv) +{ + ancillary_driver_unregister(&drv->ancillary_drv); +} + +int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name, + struct ida *client_ida); +void sof_client_dev_unregister(struct sof_client_dev *cdev); + +int sof_client_ipc_tx_message(struct sof_client_dev *cdev, u32 header, void *msg_data, + size_t msg_bytes, void *reply_data, size_t reply_bytes); + +struct dentry *sof_client_get_debugfs_root(struct sof_client_dev *cdev); + +/** + * module_sof_client_driver() - Helper macro for registering an SOF Client + * driver + * @__sof_client_driver: SOF client driver struct + * + * Helper macro for SOF client drivers which do not do anything special in + * module init/exit. This eliminates a lot of boilerplate. Each module may only + * use this macro once, and calling it replaces module_init() and module_exit() + */ +#define module_sof_client_driver(__sof_client_driver) \ + module_driver(__sof_client_driver, sof_client_drv_register, sof_client_drv_unregister) + +#endif diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 64f28e082049..8603924e56e3 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -438,6 +438,15 @@ struct snd_sof_dev { bool msi_enabled; + /* + * Used to keep track of registered client devices so that they can be removed when the + * parent SOF module is removed. + */ + struct list_head client_list; + + /* mutex to protect client list */ + struct mutex client_mutex; + void *private; /* core does not touch this */ };