diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-03-23 15:11:12 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-03-23 15:11:12 -0700 |
commit | 40037e4f8b2f7d33b8d266f139bf345962c48d46 (patch) | |
tree | 177880adcf13999593f2f09ed4432b665e4868bd /sound/soc/sof/core.c | |
parent | 182966e1cd74ec0e326cd376de241803ee79741b (diff) | |
parent | ef248d9bd616b04df8be25539a4dc5db4b6c56f4 (diff) | |
download | linux-40037e4f8b2f7d33b8d266f139bf345962c48d46.tar.gz linux-40037e4f8b2f7d33b8d266f139bf345962c48d46.tar.bz2 linux-40037e4f8b2f7d33b8d266f139bf345962c48d46.zip |
Merge tag 'sound-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"It's been a fairly calm development cycle. There are a few last-minute
ALSA core fixes, most notably for covering PCM ioctl races, but the
most of rest are device-specific changes.
Below are some highlights:
ALSA core:
- Fixes for PCM ioctl races that may lead to UAF
- Fix for oversized allocations in PCM OSS layer
ASoC:
- Start of moving SoF to support multiple IPC mechanisms
- Use of NHLT ACPI table to reduce the amount of quirking required
for Intel systems
- Preliminary works forthcoming Intel AVS driver for legacy Intel DSP
firmwares
- Support for AMD PDM, Atmel PDMC, Awinic AW8738, i.MX cards with
TLV320AIC31xx, Intel machines with CS35L41 and ESSX8336, Mediatek
MT8181 wideband bluetooth, nVidia Tegra234, Qualcomm SC7280,
Renesas RZ/V2L, Texas Instruments TAS585M
HD-audio:
- Driver re-binding fix for HD-audio
- Updates for Intel ADL and Tegra234, various platform quirks for
Dell, HP, Lenovo, ASUS, Samsung and Clevo machines
USB-audio:
- Quirk updates for Scarlett2, RODE, Corsair devices"
* tag 'sound-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (486 commits)
ALSA: hda/realtek: Add alc256-samsung-headphone fixup
ALSA: pci: fix reading of swapped values from pcmreg in AC97 codec
ALSA: pcm: Add stream lock during PCM reset ioctl operations
ALSA: pcm: Fix races among concurrent prealloc proc writes
ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls
ALSA: pcm: Fix races among concurrent read/write and buffer changes
ALSA: pcm: Fix races among concurrent hw_params and hw_free calls
ASoC: atmel: mchp-pdmc: print the correct property name
MAINTAINERS: Add Shengjiu to maintainer list of sound/soc/fsl
ASoC: SOF: Add a new dai_get_clk topology IPC op
ASoC: SOF: topology: Add ops for setting up and tearing down pipelines
ASoC: SOF: expose sof_route_setup()
ASoC: SOF: Add dai_link_fixup PCM op for IPC3
ASoC: SOF: Add trigger PCM op for IPC3
ASoC: SOF: Define hw_params PCM op for IPC3
ASoC: SOF: Introduce IPC3 PCM hw_free op
ASoC: SOF: pcm: expose the sof_pcm_setup_connected_widgets() function
ASoC: SOF: Introduce IPC-specific PCM ops
ASoC: SOF: Add bytes_ext control IPC ops for IPC3
ASoC: SOF: Add bytes_get/put control IPC ops for IPC3
...
Diffstat (limited to 'sound/soc/sof/core.c')
-rw-r--r-- | sound/soc/sof/core.c | 73 |
1 files changed, 55 insertions, 18 deletions
diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 8f32b5b12b3e..e91631618bff 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -14,9 +14,6 @@ #include <sound/sof.h> #include "sof-priv.h" #include "ops.h" -#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) -#include "sof-probes.h" -#endif /* see SOF_DBG_ flags */ static int sof_core_debug = IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_FIRMWARE_TRACE); @@ -122,6 +119,27 @@ out: } EXPORT_SYMBOL(sof_print_oops_and_stack); +/* Helper to manage DSP state */ +void sof_set_fw_state(struct snd_sof_dev *sdev, enum sof_fw_state new_state) +{ + if (sdev->fw_state == new_state) + return; + + dev_dbg(sdev->dev, "fw_state change: %d -> %d\n", sdev->fw_state, new_state); + sdev->fw_state = new_state; + + switch (new_state) { + case SOF_FW_BOOT_NOT_STARTED: + case SOF_FW_BOOT_COMPLETE: + case SOF_FW_CRASHED: + sof_client_fw_state_dispatcher(sdev); + fallthrough; + default: + break; + } +} +EXPORT_SYMBOL(sof_set_fw_state); + /* * FW Boot State Transition Diagram * @@ -266,6 +284,12 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) goto fw_trace_err; } + ret = sof_register_clients(sdev); + if (ret < 0) { + dev_err(sdev->dev, "failed to register clients %d\n", ret); + goto sof_machine_err; + } + /* * Some platforms in SOF, ex: BYT, may not have their platform PM * callbacks set. Increment the usage count so as to @@ -281,6 +305,8 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) return 0; +sof_machine_err: + snd_sof_machine_unregister(sdev, plat_data); fw_trace_err: snd_sof_free_trace(sdev); fw_run_err: @@ -329,18 +355,13 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) sdev->pdata = plat_data; sdev->first_boot = true; - sof_set_fw_state(sdev, SOF_FW_BOOT_NOT_STARTED); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) - sdev->extractor_stream_tag = SOF_PROBE_INVALID_NODE_ID; -#endif dev_set_drvdata(dev, sdev); /* check all mandatory ops */ if (!sof_ops(sdev) || !sof_ops(sdev)->probe || !sof_ops(sdev)->run || !sof_ops(sdev)->block_read || !sof_ops(sdev)->block_write || !sof_ops(sdev)->send_msg || !sof_ops(sdev)->load_firmware || - !sof_ops(sdev)->ipc_msg_data || !sof_ops(sdev)->ipc_pcm_params || - !sof_ops(sdev)->fw_ready) { + !sof_ops(sdev)->ipc_msg_data || !sof_ops(sdev)->fw_ready) { dev_err(dev, "error: missing mandatory ops\n"); return -EINVAL; } @@ -349,10 +370,16 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) INIT_LIST_HEAD(&sdev->kcontrol_list); INIT_LIST_HEAD(&sdev->widget_list); INIT_LIST_HEAD(&sdev->dai_list); + INIT_LIST_HEAD(&sdev->dai_link_list); INIT_LIST_HEAD(&sdev->route_list); + INIT_LIST_HEAD(&sdev->ipc_client_list); + INIT_LIST_HEAD(&sdev->ipc_rx_handler_list); + INIT_LIST_HEAD(&sdev->fw_state_handler_list); spin_lock_init(&sdev->ipc_lock); spin_lock_init(&sdev->hw_lock); mutex_init(&sdev->power_state_access); + mutex_init(&sdev->ipc_client_mutex); + mutex_init(&sdev->client_event_handler_mutex); /* set default timeouts if none provided */ if (plat_data->desc->ipc_timeout == 0) @@ -364,6 +391,8 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) else sdev->boot_timeout = plat_data->desc->boot_timeout; + sof_set_fw_state(sdev, SOF_FW_BOOT_NOT_STARTED); + if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) { INIT_WORK(&sdev->probe_work, sof_probe_work); schedule_work(&sdev->probe_work); @@ -392,6 +421,12 @@ int snd_sof_device_remove(struct device *dev) cancel_work_sync(&sdev->probe_work); /* + * Unregister any registered client device first before IPC and debugfs + * to allow client drivers to be removed cleanly + */ + sof_unregister_clients(sdev); + + /* * Unregister machine driver. This will unbind the snd_card which * will remove the component driver and unload the topology * before freeing the snd_card. @@ -407,16 +442,8 @@ int snd_sof_device_remove(struct device *dev) snd_sof_ipc_free(sdev); snd_sof_free_debug(sdev); - } - - /* - * Unregistering the machine driver results in unloading the topology. - * Some widgets, ex: scheduler, attempt to power down the core they are - * scheduled on, when they are unloaded. Therefore, the DSP must be - * removed only after the topology has been unloaded. - */ - if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) snd_sof_remove(sdev); + } /* release firmware */ snd_sof_fw_unload(sdev); @@ -428,10 +455,19 @@ EXPORT_SYMBOL(snd_sof_device_remove); int snd_sof_device_shutdown(struct device *dev) { struct snd_sof_dev *sdev = dev_get_drvdata(dev); + struct snd_sof_pdata *pdata = sdev->pdata; if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) cancel_work_sync(&sdev->probe_work); + /* + * make sure clients and machine driver(s) are unregistered to force + * all userspace devices to be closed prior to the DSP shutdown sequence + */ + sof_unregister_clients(sdev); + + snd_sof_machine_unregister(sdev, pdata); + if (sdev->fw_state == SOF_FW_BOOT_COMPLETE) return snd_sof_shutdown(sdev); @@ -443,3 +479,4 @@ MODULE_AUTHOR("Liam Girdwood"); MODULE_DESCRIPTION("Sound Open Firmware (SOF) Core"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_ALIAS("platform:sof-audio"); +MODULE_IMPORT_NS(SND_SOC_SOF_CLIENT); |