From 6ba9dd6c893b8e60639cfe34e983786068dba9fa Mon Sep 17 00:00:00 2001 From: James Schulman Date: Thu, 7 Feb 2019 12:12:15 -0600 Subject: ASoC: cs35l36: Add support for Cirrus CS35L36 Amplifier Add driver support for Cirrus Logic CS35L36 boosted speaker amplifier Signed-off-by: James Schulman Reviewed-by: Charles Keepax Acked-by: Brian Austin Signed-off-by: Mark Brown --- include/sound/cs35l36.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 include/sound/cs35l36.h (limited to 'include/sound') diff --git a/include/sound/cs35l36.h b/include/sound/cs35l36.h new file mode 100644 index 000000000000..8f8049d390f0 --- /dev/null +++ b/include/sound/cs35l36.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * linux/sound/cs35l36.h -- Platform data for CS35L36 + * + * Copyright 2018 Cirrus Logic, Inc. + * + * Author: James Schulman + * + */ + +#ifndef __CS35L36_H +#define __CS35L36_H + +struct cs35l36_vpbr_cfg { + bool is_present; + bool vpbr_en; + int vpbr_thld; + int vpbr_atk_rate; + int vpbr_atk_vol; + int vpbr_max_attn; + int vpbr_wait; + int vpbr_rel_rate; + int vpbr_mute_en; +}; + +struct cs35l36_platform_data { + bool multi_amp_mode; + bool dcm_mode; + bool amp_pcm_inv; + bool imon_pol_inv; + bool vmon_pol_inv; + int boost_ind; + int bst_vctl; + int bst_vctl_sel; + int bst_ipk; + bool extern_boost; + int temp_warn_thld; + int irq_drv_sel; + int irq_gpio_sel; + struct cs35l36_vpbr_cfg vpbr_config; +}; + +#endif /* __CS35L36_H */ -- cgit v1.2.3-58-ga151 From b450b87847b157d69dbf9af7aefb4cec29e89cc9 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 1 Feb 2019 11:22:23 -0600 Subject: ASoC: core: don't increase component module refcount unconditionally The ASoC core has for the longest time increased the module reference counts, even before the transition to the component model. This is probably fine on most platforms, but it introduces a deadlock case on Intel devices with the Skylake and SOF drivers which cannot be removed due to their reference counts being modified by the core. In these 2 cases, the PCI or ACPI driver .probe creates a platform device to let the machine driver .probe register the audio card. Conversely the PCI or ACPI driver .remove will unregister the platform device which results in the card being removed by the machine driver .remove. With ascii art, this can be represented as modprobe snd_soc_skl/ soc-pci-dev/sof-acpci-dev ----------> pci/acpi probe ^ | | ---------------| | | | | V V increase register register machine refcount component platform_device ^ | | | | V component <---- register card <---- probe probe The issue is that by playing with the component's module reference counts during the card registration, it's no longer possible to remove the module which controls the component. This can be shown, e.g. with the following error: root@plb-XPS-13-9350:~# lsmod | grep snd_soc_skl snd_soc_skl 110592 1 root@plb-XPS-13-9350:~# rmmod snd_soc_skl rmmod: ERROR: Module snd_soc_skl is in use Increasing the reference count during the component probe is not useful. If the PCI/ACPI module is removed, the card will be removed anyway. To avoid breaking existing platforms and allowing Intel platforms to safely deal with module load/unload cases, this patch introduces a flag which needs to be set during the component initialization. This is a strictly opt-in capability that should only be used when the handling of the component module does not require a reference count increase to prevent removal during use. Note that this solution is not directly applicable to the legacy Atom/SST driver, which uses a different device hierarchy. There are however additional refcount issues which prevent the ACPI driver from being removed. This is a different issue which would need a different patch. Signed-off-by: Pierre-Louis Bossart Signed-off-by: Mark Brown --- include/sound/soc.h | 3 +++ sound/soc/soc-core.c | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'include/sound') diff --git a/include/sound/soc.h b/include/sound/soc.h index 95689680336b..eb7db605955b 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -802,6 +802,9 @@ struct snd_soc_component_driver { int probe_order; int remove_order; + /* signal if the module handling the component cannot be removed */ + unsigned int ignore_module_refcount:1; + /* bits */ unsigned int idle_bias_on:1; unsigned int suspend_bias_off:1; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 994d21d7ba0f..93d316d5bf8e 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -947,7 +947,8 @@ static void soc_cleanup_component(struct snd_soc_component *component) snd_soc_dapm_free(snd_soc_component_get_dapm(component)); soc_cleanup_component_debugfs(component); component->card = NULL; - module_put(component->dev->driver->owner); + if (!component->driver->ignore_module_refcount) + module_put(component->dev->driver->owner); } static void soc_remove_component(struct snd_soc_component *component) @@ -1380,7 +1381,8 @@ static int soc_probe_component(struct snd_soc_card *card, return 0; } - if (!try_module_get(component->dev->driver->owner)) + if (!component->driver->ignore_module_refcount && + !try_module_get(component->dev->driver->owner)) return -ENODEV; component->card = card; -- cgit v1.2.3-58-ga151 From ecefff3e5b9b6a427a1a78c0c3f5eb147fd2d761 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 8 Feb 2019 17:45:56 -0600 Subject: ASoC: soc-acpi: remove asoc_plat_name field This field was never used, let's remove it Signed-off-by: Pierre-Louis Bossart Signed-off-by: Mark Brown --- include/sound/soc-acpi.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/sound') diff --git a/include/sound/soc-acpi.h b/include/sound/soc-acpi.h index 6cbbeed9cdd0..655e4e010cc8 100644 --- a/include/sound/soc-acpi.h +++ b/include/sound/soc-acpi.h @@ -86,8 +86,6 @@ struct snd_soc_acpi_mach_params { * is not constant since this field may be updated at run-time * @sof_fw_filename: Sound Open Firmware file name, if enabled * @sof_tplg_filename: Sound Open Firmware topology file name, if enabled - * @asoc_plat_name: ASoC platform name, used for binding machine drivers - * if non NULL * @new_mach_data: machine driver private data fixup */ /* Descriptor for SST ASoC machine driver */ @@ -102,7 +100,6 @@ struct snd_soc_acpi_mach { struct snd_soc_acpi_mach_params mach_params; const char *sof_fw_filename; const char *sof_tplg_filename; - const char *asoc_plat_name; struct platform_device * (*new_mach_data)(void *pdata); }; -- cgit v1.2.3-58-ga151 From b3d8f7cad1b41411de443018cc5323070db06ab2 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 8 Feb 2019 17:45:57 -0600 Subject: ASoC: soc-acpi: remove new_mach_data field We never used this field (or in older SOF implementations), let's remove it Signed-off-by: Pierre-Louis Bossart Signed-off-by: Mark Brown --- include/sound/soc-acpi.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/sound') diff --git a/include/sound/soc-acpi.h b/include/sound/soc-acpi.h index 655e4e010cc8..35b38e41e5b2 100644 --- a/include/sound/soc-acpi.h +++ b/include/sound/soc-acpi.h @@ -86,7 +86,6 @@ struct snd_soc_acpi_mach_params { * is not constant since this field may be updated at run-time * @sof_fw_filename: Sound Open Firmware file name, if enabled * @sof_tplg_filename: Sound Open Firmware topology file name, if enabled - * @new_mach_data: machine driver private data fixup */ /* Descriptor for SST ASoC machine driver */ struct snd_soc_acpi_mach { @@ -100,7 +99,6 @@ struct snd_soc_acpi_mach { struct snd_soc_acpi_mach_params mach_params; const char *sof_fw_filename; const char *sof_tplg_filename; - struct platform_device * (*new_mach_data)(void *pdata); }; #define SND_SOC_ACPI_MAX_CODECS 3 -- cgit v1.2.3-58-ga151 From 76d9c68b360f852e784170f10cb431e4713c7d0b Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Thu, 14 Feb 2019 16:45:55 +0100 Subject: ASoC: dmaengine: Remove unused SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME flag There is now no users of this flag so remove it together with related code. The chan_name field of snd_dmaengine_dai_dma_data data structure is not removed as it is still in use by the PXA platform. Signed-off-by: Sylwester Nawrocki Acked-by: Krzysztof Kozlowski Signed-off-by: Mark Brown --- include/sound/dmaengine_pcm.h | 4 ---- sound/soc/soc-generic-dmaengine-pcm.c | 21 ++++----------------- 2 files changed, 4 insertions(+), 21 deletions(-) (limited to 'include/sound') diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index 2c4cfaa135a6..c679f6116580 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -99,10 +99,6 @@ void snd_dmaengine_pcm_set_config_from_dai_data( * playback. */ #define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3) -/* - * The PCM streams have custom channel names specified. - */ -#define SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME BIT(4) /** * struct snd_dmaengine_pcm_config - Configuration data for dmaengine based PCM diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index 1b44e363c50c..f1ab6285a085 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c @@ -265,7 +265,6 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) struct dmaengine_pcm *pcm = soc_component_to_pcm(component); const struct snd_dmaengine_pcm_config *config = pcm->config; struct device *dev = component->dev; - struct snd_dmaengine_dai_dma_data *dma_data; struct snd_pcm_substream *substream; size_t prealloc_buffer_size; size_t max_buffer_size; @@ -285,19 +284,9 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) if (!substream) continue; - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - if (!pcm->chan[i] && - ((pcm->flags & SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME) || - (config && config->chan_names[i]))) { - const char *chan_name = dma_data->chan_name; - - if (config && config->chan_names[i]) - chan_name = config->chan_names[i]; - + if (!pcm->chan[i] && config && config->chan_names[i]) pcm->chan[i] = dma_request_slave_channel(dev, - chan_name); - } + config->chan_names[i]); if (!pcm->chan[i] && (pcm->flags & SND_DMAENGINE_PCM_FLAG_COMPAT)) { pcm->chan[i] = dmaengine_pcm_compat_request_channel(rtd, @@ -420,10 +409,8 @@ static int dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, const char *name; struct dma_chan *chan; - if ((pcm->flags & (SND_DMAENGINE_PCM_FLAG_NO_DT | - SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME)) || - (!dev->of_node && !(config && config->dma_dev && - config->dma_dev->of_node))) + if ((pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_DT) || (!dev->of_node && + !(config && config->dma_dev && config->dma_dev->of_node))) return 0; if (config && config->dma_dev) { -- cgit v1.2.3-58-ga151