diff options
author | Mark Brown <broonie@kernel.org> | 2020-06-01 14:01:13 +0200 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2020-06-01 14:01:13 +0200 |
commit | a72ff08faf3d6b2a1c21c9b815bf02af44cc70ab (patch) | |
tree | 5d9292f82ef7a236930febee51373565e1842398 /sound/soc | |
parent | Linux 5.7-rc7 (diff) | |
parent | ASoC: dapm: Move dai_link widgets to runtime to fix use after free (diff) | |
download | linux-a72ff08faf3d6b2a1c21c9b815bf02af44cc70ab.tar.xz linux-a72ff08faf3d6b2a1c21c9b815bf02af44cc70ab.zip |
Merge remote-tracking branch 'asoc/for-5.7' into asoc-linus
Diffstat (limited to 'sound/soc')
30 files changed, 182 insertions, 218 deletions
diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c index e362f0bc9e46..a36c5cb848cd 100644 --- a/sound/soc/amd/raven/acp3x-pcm-dma.c +++ b/sound/soc/amd/raven/acp3x-pcm-dma.c @@ -241,14 +241,6 @@ static int acp3x_dma_open(struct snd_soc_component *component, adata->i2ssp_play_stream && !adata->i2ssp_capture_stream) rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - adata->play_stream = substream; - adata->i2ssp_play_stream = substream; - } else { - adata->capture_stream = substream; - adata->i2ssp_capture_stream = substream; - } - i2s_data->acp3x_base = adata->acp3x_base; runtime->private_data = i2s_data; return ret; @@ -263,23 +255,42 @@ static int acp3x_dma_hw_params(struct snd_soc_component *component, struct snd_soc_pcm_runtime *prtd; struct snd_soc_card *card; struct acp3x_platform_info *pinfo; + struct i2s_dev_data *adata; u64 size; prtd = substream->private_data; card = prtd->card; pinfo = snd_soc_card_get_drvdata(card); + adata = dev_get_drvdata(component->dev); rtd = substream->runtime->private_data; if (!rtd) return -EINVAL; - if (pinfo) - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + if (pinfo) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { rtd->i2s_instance = pinfo->play_i2s_instance; - else + switch (rtd->i2s_instance) { + case I2S_BT_INSTANCE: + adata->play_stream = substream; + break; + case I2S_SP_INSTANCE: + default: + adata->i2ssp_play_stream = substream; + } + } else { rtd->i2s_instance = pinfo->cap_i2s_instance; - else + switch (rtd->i2s_instance) { + case I2S_BT_INSTANCE: + adata->capture_stream = substream; + break; + case I2S_SP_INSTANCE: + default: + adata->i2ssp_capture_stream = substream; + } + } + } else { pr_err("pinfo failed\n"); - + } size = params_buffer_bytes(params); rtd->dma_addr = substream->dma_buffer.addr; rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); diff --git a/sound/soc/codecs/adau7118-i2c.c b/sound/soc/codecs/adau7118-i2c.c index a8211362fe82..aa7afb3b826d 100644 --- a/sound/soc/codecs/adau7118-i2c.c +++ b/sound/soc/codecs/adau7118-i2c.c @@ -32,6 +32,12 @@ static const struct reg_default adau7118_reg_defaults[] = { { ADAU7118_REG_RESET, 0x00 }, }; +static bool adau7118_volatile(struct device *dev, unsigned int reg) +{ + return (reg == ADAU7118_REG_RESET); +} + + static const struct regmap_config adau7118_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -39,6 +45,7 @@ static const struct regmap_config adau7118_regmap_config = { .num_reg_defaults = ARRAY_SIZE(adau7118_reg_defaults), .cache_type = REGCACHE_RBTREE, .max_register = ADAU7118_REG_RESET, + .volatile_reg = adau7118_volatile, }; static int adau7118_probe_i2c(struct i2c_client *i2c, diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c index d0737db5868a..39dda1b03b3d 100644 --- a/sound/soc/codecs/max9768.c +++ b/sound/soc/codecs/max9768.c @@ -220,6 +220,6 @@ static struct i2c_driver max9768_i2c_driver = { }; module_i2c_driver(max9768_i2c_driver); -MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>"); +MODULE_AUTHOR("Wolfram Sang <kernel@pengutronix.de>"); MODULE_DESCRIPTION("ASoC MAX9768 amplifier driver"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c index cae1def8902d..96718e3a1ad0 100644 --- a/sound/soc/codecs/max98373.c +++ b/sound/soc/codecs/max98373.c @@ -850,8 +850,8 @@ static int max98373_resume(struct device *dev) { struct max98373_priv *max98373 = dev_get_drvdata(dev); - max98373_reset(max98373, dev); regcache_cache_only(max98373->regmap, false); + max98373_reset(max98373, dev); regcache_sync(max98373->regmap); return 0; } diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c index 8600c5439e1e..6d49a1cc98c6 100644 --- a/sound/soc/codecs/max9867.c +++ b/sound/soc/codecs/max9867.c @@ -46,19 +46,19 @@ static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max9867_micboost_tlv, static const struct snd_kcontrol_new max9867_snd_controls[] = { SOC_DOUBLE_R_TLV("Master Playback Volume", MAX9867_LEFTVOL, - MAX9867_RIGHTVOL, 0, 41, 1, max9867_master_tlv), + MAX9867_RIGHTVOL, 0, 40, 1, max9867_master_tlv), SOC_DOUBLE_R_TLV("Line Capture Volume", MAX9867_LEFTLINELVL, MAX9867_RIGHTLINELVL, 0, 15, 1, max9867_line_tlv), SOC_DOUBLE_R_TLV("Mic Capture Volume", MAX9867_LEFTMICGAIN, MAX9867_RIGHTMICGAIN, 0, 20, 1, max9867_mic_tlv), SOC_DOUBLE_R_TLV("Mic Boost Capture Volume", MAX9867_LEFTMICGAIN, - MAX9867_RIGHTMICGAIN, 5, 4, 0, max9867_micboost_tlv), + MAX9867_RIGHTMICGAIN, 5, 3, 0, max9867_micboost_tlv), SOC_SINGLE("Digital Sidetone Volume", MAX9867_SIDETONE, 0, 31, 1), SOC_SINGLE_TLV("Digital Playback Volume", MAX9867_DACLEVEL, 0, 15, 1, max9867_dac_tlv), SOC_SINGLE_TLV("Digital Boost Playback Volume", MAX9867_DACLEVEL, 4, 3, 0, max9867_dacboost_tlv), - SOC_DOUBLE_TLV("Digital Capture Volume", MAX9867_ADCLEVEL, 0, 4, 15, 1, + SOC_DOUBLE_TLV("Digital Capture Volume", MAX9867_ADCLEVEL, 4, 0, 15, 1, max9867_adc_tlv), SOC_ENUM("Speaker Mode", max9867_spkmode), SOC_SINGLE("Volume Smoothing Switch", MAX9867_MODECONFIG, 6, 1, 0), diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 38897568ee96..1d7d7b34a46e 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -511,11 +511,11 @@ static const struct snd_soc_dapm_route adcx140_audio_map[] = { static const struct snd_kcontrol_new adcx140_snd_controls[] = { SOC_SINGLE_TLV("Analog CH1 Mic Gain Volume", ADCX140_CH1_CFG1, 2, 42, 0, adc_tlv), - SOC_SINGLE_TLV("Analog CH2 Mic Gain Volume", ADCX140_CH1_CFG2, 2, 42, 0, + SOC_SINGLE_TLV("Analog CH2 Mic Gain Volume", ADCX140_CH2_CFG1, 2, 42, 0, adc_tlv), - SOC_SINGLE_TLV("Analog CH3 Mic Gain Volume", ADCX140_CH1_CFG3, 2, 42, 0, + SOC_SINGLE_TLV("Analog CH3 Mic Gain Volume", ADCX140_CH3_CFG1, 2, 42, 0, adc_tlv), - SOC_SINGLE_TLV("Analog CH4 Mic Gain Volume", ADCX140_CH1_CFG4, 2, 42, 0, + SOC_SINGLE_TLV("Analog CH4 Mic Gain Volume", ADCX140_CH4_CFG1, 2, 42, 0, adc_tlv), SOC_SINGLE_TLV("DRE Threshold", ADCX140_DRE_CFG0, 4, 9, 0, @@ -739,11 +739,12 @@ static int adcx140_codec_probe(struct snd_soc_component *component) { struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component); int sleep_cfg_val = ADCX140_WAKE_DEV; - u8 bias_source; - u8 vref_source; + u32 bias_source; + u32 vref_source; + u8 bias_cfg; int ret; - ret = device_property_read_u8(adcx140->dev, "ti,mic-bias-source", + ret = device_property_read_u32(adcx140->dev, "ti,mic-bias-source", &bias_source); if (ret) bias_source = ADCX140_MIC_BIAS_VAL_VREF; @@ -754,7 +755,7 @@ static int adcx140_codec_probe(struct snd_soc_component *component) return -EINVAL; } - ret = device_property_read_u8(adcx140->dev, "ti,vref-source", + ret = device_property_read_u32(adcx140->dev, "ti,vref-source", &vref_source); if (ret) vref_source = ADCX140_MIC_BIAS_VREF_275V; @@ -765,7 +766,7 @@ static int adcx140_codec_probe(struct snd_soc_component *component) return -EINVAL; } - bias_source |= vref_source; + bias_cfg = bias_source << ADCX140_MIC_BIAS_SHIFT | vref_source; ret = adcx140_reset(adcx140); if (ret) @@ -785,7 +786,7 @@ static int adcx140_codec_probe(struct snd_soc_component *component) ret = regmap_update_bits(adcx140->regmap, ADCX140_BIAS_CFG, ADCX140_MIC_BIAS_VAL_MSK | - ADCX140_MIC_BIAS_VREF_MSK, bias_source); + ADCX140_MIC_BIAS_VREF_MSK, bias_cfg); if (ret) dev_err(adcx140->dev, "setting MIC bias failed %d\n", ret); out: diff --git a/sound/soc/codecs/tlv320adcx140.h b/sound/soc/codecs/tlv320adcx140.h index 6d055e55909e..69de52d473f4 100644 --- a/sound/soc/codecs/tlv320adcx140.h +++ b/sound/soc/codecs/tlv320adcx140.h @@ -116,6 +116,7 @@ #define ADCX140_MIC_BIAS_VAL_VREF_1096 1 #define ADCX140_MIC_BIAS_VAL_AVDD 6 #define ADCX140_MIC_BIAS_VAL_MSK GENMASK(6, 4) +#define ADCX140_MIC_BIAS_SHIFT 4 #define ADCX140_MIC_BIAS_VREF_275V 0 #define ADCX140_MIC_BIAS_VREF_25V 1 diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index d9d59f45833f..08d19df8a700 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -118,7 +118,7 @@ static const struct reg_default wm8962_reg[] = { { 5, 0x0018 }, /* R5 - ADC & DAC Control 1 */ { 6, 0x2008 }, /* R6 - ADC & DAC Control 2 */ { 7, 0x000A }, /* R7 - Audio Interface 0 */ - + { 8, 0x01E4 }, /* R8 - Clocking2 */ { 9, 0x0300 }, /* R9 - Audio Interface 1 */ { 10, 0x00C0 }, /* R10 - Left DAC volume */ { 11, 0x00C0 }, /* R11 - Right DAC volume */ @@ -788,7 +788,6 @@ static bool wm8962_volatile_register(struct device *dev, unsigned int reg) { switch (reg) { case WM8962_CLOCKING1: - case WM8962_CLOCKING2: case WM8962_SOFTWARE_RESET: case WM8962_THERMAL_SHUTDOWN_STATUS: case WM8962_ADDITIONAL_CONTROL_4: @@ -3799,8 +3798,8 @@ static int wm8962_runtime_resume(struct device *dev) /* SYSCLK defaults to on; make sure it is off so we can safely * write to registers if the device is declocked. */ - regmap_update_bits(wm8962->regmap, WM8962_CLOCKING2, - WM8962_SYSCLK_ENA, 0); + regmap_write_bits(wm8962->regmap, WM8962_CLOCKING2, + WM8962_SYSCLK_ENA, 0); /* Ensure we have soft control over all registers */ regmap_update_bits(wm8962->regmap, WM8962_CLOCKING2, diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index c7a49d03463a..84290be778f0 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -87,6 +87,10 @@ static irqreturn_t esai_isr(int irq, void *devid) if ((saisr & (ESAI_SAISR_TUE | ESAI_SAISR_ROE)) && esai_priv->reset_at_xrun) { dev_dbg(&pdev->dev, "reset module for xrun\n"); + regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, + ESAI_xCR_xEIE_MASK, 0); + regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, + ESAI_xCR_xEIE_MASK, 0); tasklet_schedule(&esai_priv->task); } diff --git a/sound/soc/intel/baytrail/sst-baytrail-ipc.c b/sound/soc/intel/baytrail/sst-baytrail-ipc.c index 74274bd38f7a..34746fd871b0 100644 --- a/sound/soc/intel/baytrail/sst-baytrail-ipc.c +++ b/sound/soc/intel/baytrail/sst-baytrail-ipc.c @@ -666,8 +666,8 @@ static bool byt_is_dsp_busy(struct sst_dsp *dsp) { u64 ipcx; - ipcx = sst_dsp_shim_read_unlocked(dsp, SST_IPCX); - return (ipcx & (SST_IPCX_BUSY | SST_IPCX_DONE)); + ipcx = sst_dsp_shim_read64_unlocked(dsp, SST_IPCX); + return (ipcx & (SST_BYT_IPCX_BUSY | SST_BYT_IPCX_DONE)); } int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata) diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c index f9a8336a0541..86deea6f136a 100644 --- a/sound/soc/intel/boards/broadwell.c +++ b/sound/soc/intel/boards/broadwell.c @@ -230,7 +230,8 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = { }, }; -static int broadwell_suspend(struct snd_soc_card *card){ +static int broadwell_disable_jack(struct snd_soc_card *card) +{ struct snd_soc_component *component; for_each_card_components(card, component) { @@ -241,9 +242,15 @@ static int broadwell_suspend(struct snd_soc_card *card){ break; } } + return 0; } +static int broadwell_suspend(struct snd_soc_card *card) +{ + return broadwell_disable_jack(card); +} + static int broadwell_resume(struct snd_soc_card *card){ struct snd_soc_component *component; @@ -292,8 +299,16 @@ static int broadwell_audio_probe(struct platform_device *pdev) return devm_snd_soc_register_card(&pdev->dev, &broadwell_rt286); } +static int broadwell_audio_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + return broadwell_disable_jack(card); +} + static struct platform_driver broadwell_audio = { .probe = broadwell_audio_probe, + .remove = broadwell_audio_remove, .driver = { .name = "broadwell-audio", }, diff --git a/sound/soc/intel/common/sst-dsp.c b/sound/soc/intel/common/sst-dsp.c index ec66be269b69..36c077aa386e 100644 --- a/sound/soc/intel/common/sst-dsp.c +++ b/sound/soc/intel/common/sst-dsp.c @@ -10,7 +10,7 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/platform_device.h> -#include <linux/io.h> +#include <linux/io-64-nonatomic-lo-hi.h> #include <linux/delay.h> #include "sst-dsp.h" @@ -34,16 +34,13 @@ EXPORT_SYMBOL_GPL(sst_shim32_read); void sst_shim32_write64(void __iomem *addr, u32 offset, u64 value) { - memcpy_toio(addr + offset, &value, sizeof(value)); + writeq(value, addr + offset); } EXPORT_SYMBOL_GPL(sst_shim32_write64); u64 sst_shim32_read64(void __iomem *addr, u32 offset) { - u64 val; - - memcpy_fromio(&val, addr + offset, sizeof(val)); - return val; + return readq(addr + offset); } EXPORT_SYMBOL_GPL(sst_shim32_read64); diff --git a/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c b/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c index c8ded53bde1d..e0c4714da92c 100644 --- a/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c +++ b/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c @@ -1186,10 +1186,9 @@ static int mt8183_afe_pcm_dev_probe(struct platform_device *pdev) /* request irq */ irq_id = platform_get_irq(pdev, 0); - if (!irq_id) { - dev_err(dev, "%pOFn no irq found\n", dev->of_node); - return -ENXIO; - } + if (irq_id < 0) + return irq_id; + ret = devm_request_irq(dev, irq_id, mt8183_afe_irq_handler, IRQF_TRIGGER_NONE, "asys-isr", (void *)afe); if (ret) { diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c index 3548a2634a63..90a9bc81be80 100644 --- a/sound/soc/pxa/mmp-sspa.c +++ b/sound/soc/pxa/mmp-sspa.c @@ -275,9 +275,6 @@ static int mmp_sspa_hw_params(struct snd_pcm_substream *substream, case SNDRV_PCM_FORMAT_S16_LE: sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_16_BITS); break; - case SNDRV_PCM_FORMAT_S20_3LE: - sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_20_BITS); - break; case SNDRV_PCM_FORMAT_S24_3LE: sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_24_BITS); break; @@ -362,7 +359,7 @@ static int mmp_sspa_probe(struct snd_soc_dai *dai) #define MMP_SSPA_RATES SNDRV_PCM_RATE_8000_192000 #define MMP_SSPA_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ - SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S24_3LE | \ SNDRV_PCM_FMTBIT_S32_LE) static const struct snd_soc_dai_ops mmp_sspa_dai_ops = { diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index e2632841b321..c0aa64ff8e32 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -4340,16 +4340,16 @@ static void dapm_connect_dai_pair(struct snd_soc_card *card, codec = codec_dai->playback_widget; if (playback_cpu && codec) { - if (dai_link->params && !dai_link->playback_widget) { + if (dai_link->params && !rtd->playback_widget) { substream = streams[SNDRV_PCM_STREAM_PLAYBACK].substream; dai = snd_soc_dapm_new_dai(card, substream, "playback"); if (IS_ERR(dai)) goto capture; - dai_link->playback_widget = dai; + rtd->playback_widget = dai; } dapm_connect_dai_routes(&card->dapm, cpu_dai, playback_cpu, - dai_link->playback_widget, + rtd->playback_widget, codec_dai, codec); } @@ -4358,16 +4358,16 @@ capture: codec = codec_dai->capture_widget; if (codec && capture_cpu) { - if (dai_link->params && !dai_link->capture_widget) { + if (dai_link->params && !rtd->capture_widget) { substream = streams[SNDRV_PCM_STREAM_CAPTURE].substream; dai = snd_soc_dapm_new_dai(card, substream, "capture"); if (IS_ERR(dai)) return; - dai_link->capture_widget = dai; + rtd->capture_widget = dai; } dapm_connect_dai_routes(&card->dapm, codec_dai, codec, - dai_link->capture_widget, + rtd->capture_widget, cpu_dai, capture_cpu); } } diff --git a/sound/soc/sof/control.c b/sound/soc/sof/control.c index dfc412e2d956..6d63768d42aa 100644 --- a/sound/soc/sof/control.c +++ b/sound/soc/sof/control.c @@ -19,8 +19,8 @@ static void update_mute_led(struct snd_sof_control *scontrol, struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - unsigned int temp = 0; - unsigned int mask; + int temp = 0; + int mask; int i; mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index bf65f31af858..875a5fc13297 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -56,7 +56,7 @@ struct snd_sof_pcm { struct snd_sof_led_control { unsigned int use_led; unsigned int direction; - unsigned int led_value; + int led_value; }; /* ALSA SOF Kcontrol device */ diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index fe8ba3e05e08..ab2b69de1d4d 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1203,6 +1203,8 @@ static int sof_control_load(struct snd_soc_component *scomp, int index, return ret; } + scontrol->led_ctl.led_value = -1; + dobj->private = scontrol; list_add(&scontrol->list, &sdev->kcontrol_list); return ret; diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index ec39ecba1e8b..2839c6cb8c38 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c @@ -205,13 +205,11 @@ static int tegra_alc5632_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); - goto err_fini_utils; + goto err_put_cpu_of_node; } return 0; -err_fini_utils: - tegra_asoc_utils_fini(&alc5632->util_data); err_put_cpu_of_node: of_node_put(tegra_alc5632_dai.cpus->of_node); tegra_alc5632_dai.cpus->of_node = NULL; @@ -226,12 +224,9 @@ err: static int tegra_alc5632_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card); snd_soc_unregister_card(card); - tegra_asoc_utils_fini(&machine->util_data); - of_node_put(tegra_alc5632_dai.cpus->of_node); tegra_alc5632_dai.cpus->of_node = NULL; tegra_alc5632_dai.platforms->of_node = NULL; diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c index 536a578e9512..587f62a288d1 100644 --- a/sound/soc/tegra/tegra_asoc_utils.c +++ b/sound/soc/tegra/tegra_asoc_utils.c @@ -60,8 +60,6 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, data->set_mclk = 0; clk_disable_unprepare(data->clk_cdev1); - clk_disable_unprepare(data->clk_pll_a_out0); - clk_disable_unprepare(data->clk_pll_a); err = clk_set_rate(data->clk_pll_a, new_baseclock); if (err) { @@ -77,18 +75,6 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, /* Don't set cdev1/extern1 rate; it's locked to pll_a_out0 */ - err = clk_prepare_enable(data->clk_pll_a); - if (err) { - dev_err(data->dev, "Can't enable pll_a: %d\n", err); - return err; - } - - err = clk_prepare_enable(data->clk_pll_a_out0); - if (err) { - dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err); - return err; - } - err = clk_prepare_enable(data->clk_cdev1); if (err) { dev_err(data->dev, "Can't enable cdev1: %d\n", err); @@ -109,8 +95,6 @@ int tegra_asoc_utils_set_ac97_rate(struct tegra_asoc_utils_data *data) int err; clk_disable_unprepare(data->clk_cdev1); - clk_disable_unprepare(data->clk_pll_a_out0); - clk_disable_unprepare(data->clk_pll_a); /* * AC97 rate is fixed at 24.576MHz and is used for both the host @@ -130,18 +114,6 @@ int tegra_asoc_utils_set_ac97_rate(struct tegra_asoc_utils_data *data) /* Don't set cdev1/extern1 rate; it's locked to pll_a_out0 */ - err = clk_prepare_enable(data->clk_pll_a); - if (err) { - dev_err(data->dev, "Can't enable pll_a: %d\n", err); - return err; - } - - err = clk_prepare_enable(data->clk_pll_a_out0); - if (err) { - dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err); - return err; - } - err = clk_prepare_enable(data->clk_cdev1); if (err) { dev_err(data->dev, "Can't enable cdev1: %d\n", err); @@ -158,6 +130,7 @@ EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_ac97_rate); int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, struct device *dev) { + struct clk *clk_out_1, *clk_extern1; int ret; data->dev = dev; @@ -175,52 +148,78 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, return -EINVAL; } - data->clk_pll_a = clk_get(dev, "pll_a"); + data->clk_pll_a = devm_clk_get(dev, "pll_a"); if (IS_ERR(data->clk_pll_a)) { dev_err(data->dev, "Can't retrieve clk pll_a\n"); - ret = PTR_ERR(data->clk_pll_a); - goto err; + return PTR_ERR(data->clk_pll_a); } - data->clk_pll_a_out0 = clk_get(dev, "pll_a_out0"); + data->clk_pll_a_out0 = devm_clk_get(dev, "pll_a_out0"); if (IS_ERR(data->clk_pll_a_out0)) { dev_err(data->dev, "Can't retrieve clk pll_a_out0\n"); - ret = PTR_ERR(data->clk_pll_a_out0); - goto err_put_pll_a; + return PTR_ERR(data->clk_pll_a_out0); } - data->clk_cdev1 = clk_get(dev, "mclk"); + data->clk_cdev1 = devm_clk_get(dev, "mclk"); if (IS_ERR(data->clk_cdev1)) { dev_err(data->dev, "Can't retrieve clk cdev1\n"); - ret = PTR_ERR(data->clk_cdev1); - goto err_put_pll_a_out0; + return PTR_ERR(data->clk_cdev1); } - ret = tegra_asoc_utils_set_rate(data, 44100, 256 * 44100); - if (ret) - goto err_put_cdev1; + /* + * If clock parents are not set in DT, configure here to use clk_out_1 + * as mclk and extern1 as parent for Tegra30 and higher. + */ + if (!of_find_property(dev->of_node, "assigned-clock-parents", NULL) && + data->soc > TEGRA_ASOC_UTILS_SOC_TEGRA20) { + dev_warn(data->dev, + "Configuring clocks for a legacy device-tree\n"); + dev_warn(data->dev, + "Please update DT to use assigned-clock-parents\n"); + clk_extern1 = devm_clk_get(dev, "extern1"); + if (IS_ERR(clk_extern1)) { + dev_err(data->dev, "Can't retrieve clk extern1\n"); + return PTR_ERR(clk_extern1); + } + + ret = clk_set_parent(clk_extern1, data->clk_pll_a_out0); + if (ret < 0) { + dev_err(data->dev, + "Set parent failed for clk extern1\n"); + return ret; + } + + clk_out_1 = devm_clk_get(dev, "pmc_clk_out_1"); + if (IS_ERR(clk_out_1)) { + dev_err(data->dev, "Can't retrieve pmc_clk_out_1\n"); + return PTR_ERR(clk_out_1); + } + + ret = clk_set_parent(clk_out_1, clk_extern1); + if (ret < 0) { + dev_err(data->dev, + "Set parent failed for pmc_clk_out_1\n"); + return ret; + } + + data->clk_cdev1 = clk_out_1; + } - return 0; + /* + * FIXME: There is some unknown dependency between audio mclk disable + * and suspend-resume functionality on Tegra30, although audio mclk is + * only needed for audio. + */ + ret = clk_prepare_enable(data->clk_cdev1); + if (ret) { + dev_err(data->dev, "Can't enable cdev1: %d\n", ret); + return ret; + } -err_put_cdev1: - clk_put(data->clk_cdev1); -err_put_pll_a_out0: - clk_put(data->clk_pll_a_out0); -err_put_pll_a: - clk_put(data->clk_pll_a); -err: - return ret; + return 0; } EXPORT_SYMBOL_GPL(tegra_asoc_utils_init); -void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data) -{ - clk_put(data->clk_cdev1); - clk_put(data->clk_pll_a_out0); - clk_put(data->clk_pll_a); -} -EXPORT_SYMBOL_GPL(tegra_asoc_utils_fini); - MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); MODULE_DESCRIPTION("Tegra ASoC utility code"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h index 0c13818dee75..a34439587d59 100644 --- a/sound/soc/tegra/tegra_asoc_utils.h +++ b/sound/soc/tegra/tegra_asoc_utils.h @@ -34,6 +34,5 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, int tegra_asoc_utils_set_ac97_rate(struct tegra_asoc_utils_data *data); int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, struct device *dev); -void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data); #endif diff --git a/sound/soc/tegra/tegra_max98090.c b/sound/soc/tegra/tegra_max98090.c index d800b62b36f8..ec9050516cd7 100644 --- a/sound/soc/tegra/tegra_max98090.c +++ b/sound/soc/tegra/tegra_max98090.c @@ -218,19 +218,18 @@ static int tegra_max98090_probe(struct platform_device *pdev) ret = snd_soc_of_parse_card_name(card, "nvidia,model"); if (ret) - goto err; + return ret; ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing"); if (ret) - goto err; + return ret; tegra_max98090_dai.codecs->of_node = of_parse_phandle(np, "nvidia,audio-codec", 0); if (!tegra_max98090_dai.codecs->of_node) { dev_err(&pdev->dev, "Property 'nvidia,audio-codec' missing or invalid\n"); - ret = -EINVAL; - goto err; + return -EINVAL; } tegra_max98090_dai.cpus->of_node = of_parse_phandle(np, @@ -238,40 +237,31 @@ static int tegra_max98090_probe(struct platform_device *pdev) if (!tegra_max98090_dai.cpus->of_node) { dev_err(&pdev->dev, "Property 'nvidia,i2s-controller' missing or invalid\n"); - ret = -EINVAL; - goto err; + return -EINVAL; } tegra_max98090_dai.platforms->of_node = tegra_max98090_dai.cpus->of_node; ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); if (ret) - goto err; + return ret; ret = snd_soc_register_card(card); if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); - goto err_fini_utils; + return ret; } return 0; - -err_fini_utils: - tegra_asoc_utils_fini(&machine->util_data); -err: - return ret; } static int tegra_max98090_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - struct tegra_max98090 *machine = snd_soc_card_get_drvdata(card); snd_soc_unregister_card(card); - tegra_asoc_utils_fini(&machine->util_data); - return 0; } diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c index 9878bc3eb89e..201d132731f9 100644 --- a/sound/soc/tegra/tegra_rt5640.c +++ b/sound/soc/tegra/tegra_rt5640.c @@ -164,19 +164,18 @@ static int tegra_rt5640_probe(struct platform_device *pdev) ret = snd_soc_of_parse_card_name(card, "nvidia,model"); if (ret) - goto err; + return ret; ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing"); if (ret) - goto err; + return ret; tegra_rt5640_dai.codecs->of_node = of_parse_phandle(np, "nvidia,audio-codec", 0); if (!tegra_rt5640_dai.codecs->of_node) { dev_err(&pdev->dev, "Property 'nvidia,audio-codec' missing or invalid\n"); - ret = -EINVAL; - goto err; + return -EINVAL; } tegra_rt5640_dai.cpus->of_node = of_parse_phandle(np, @@ -184,40 +183,31 @@ static int tegra_rt5640_probe(struct platform_device *pdev) if (!tegra_rt5640_dai.cpus->of_node) { dev_err(&pdev->dev, "Property 'nvidia,i2s-controller' missing or invalid\n"); - ret = -EINVAL; - goto err; + return -EINVAL; } tegra_rt5640_dai.platforms->of_node = tegra_rt5640_dai.cpus->of_node; ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); if (ret) - goto err; + return ret; ret = snd_soc_register_card(card); if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); - goto err_fini_utils; + return ret; } return 0; - -err_fini_utils: - tegra_asoc_utils_fini(&machine->util_data); -err: - return ret; } static int tegra_rt5640_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card); snd_soc_unregister_card(card); - tegra_asoc_utils_fini(&machine->util_data); - return 0; } diff --git a/sound/soc/tegra/tegra_rt5677.c b/sound/soc/tegra/tegra_rt5677.c index 5821313db977..8f71e21f6ee9 100644 --- a/sound/soc/tegra/tegra_rt5677.c +++ b/sound/soc/tegra/tegra_rt5677.c @@ -270,13 +270,11 @@ static int tegra_rt5677_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); - goto err_fini_utils; + goto err_put_cpu_of_node; } return 0; -err_fini_utils: - tegra_asoc_utils_fini(&machine->util_data); err_put_cpu_of_node: of_node_put(tegra_rt5677_dai.cpus->of_node); tegra_rt5677_dai.cpus->of_node = NULL; @@ -291,12 +289,9 @@ err: static int tegra_rt5677_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - struct tegra_rt5677 *machine = snd_soc_card_get_drvdata(card); snd_soc_unregister_card(card); - tegra_asoc_utils_fini(&machine->util_data); - tegra_rt5677_dai.platforms->of_node = NULL; of_node_put(tegra_rt5677_dai.codecs->of_node); tegra_rt5677_dai.codecs->of_node = NULL; diff --git a/sound/soc/tegra/tegra_sgtl5000.c b/sound/soc/tegra/tegra_sgtl5000.c index dc411ba2e36d..692fcc3d7d6e 100644 --- a/sound/soc/tegra/tegra_sgtl5000.c +++ b/sound/soc/tegra/tegra_sgtl5000.c @@ -156,13 +156,11 @@ static int tegra_sgtl5000_driver_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); - goto err_fini_utils; + goto err_put_cpu_of_node; } return 0; -err_fini_utils: - tegra_asoc_utils_fini(&machine->util_data); err_put_cpu_of_node: of_node_put(tegra_sgtl5000_dai.cpus->of_node); tegra_sgtl5000_dai.cpus->of_node = NULL; @@ -177,13 +175,10 @@ err: static int tegra_sgtl5000_driver_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - struct tegra_sgtl5000 *machine = snd_soc_card_get_drvdata(card); int ret; ret = snd_soc_unregister_card(card); - tegra_asoc_utils_fini(&machine->util_data); - of_node_put(tegra_sgtl5000_dai.cpus->of_node); tegra_sgtl5000_dai.cpus->of_node = NULL; tegra_sgtl5000_dai.platforms->of_node = NULL; diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index 0d653a605358..2ee2ed190872 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c @@ -127,19 +127,18 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) ret = snd_soc_of_parse_card_name(card, "nvidia,model"); if (ret) - goto err; + return ret; ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing"); if (ret) - goto err; + return ret; tegra_wm8753_dai.codecs->of_node = of_parse_phandle(np, "nvidia,audio-codec", 0); if (!tegra_wm8753_dai.codecs->of_node) { dev_err(&pdev->dev, "Property 'nvidia,audio-codec' missing or invalid\n"); - ret = -EINVAL; - goto err; + return -EINVAL; } tegra_wm8753_dai.cpus->of_node = of_parse_phandle(np, @@ -147,40 +146,31 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) if (!tegra_wm8753_dai.cpus->of_node) { dev_err(&pdev->dev, "Property 'nvidia,i2s-controller' missing or invalid\n"); - ret = -EINVAL; - goto err; + return -EINVAL; } tegra_wm8753_dai.platforms->of_node = tegra_wm8753_dai.cpus->of_node; ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); if (ret) - goto err; + return ret; ret = snd_soc_register_card(card); if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); - goto err_fini_utils; + return ret; } return 0; - -err_fini_utils: - tegra_asoc_utils_fini(&machine->util_data); -err: - return ret; } static int tegra_wm8753_driver_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); snd_soc_unregister_card(card); - tegra_asoc_utils_fini(&machine->util_data); - return 0; } diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 9b5651502f12..6525b93cb75c 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -319,19 +319,18 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) ret = snd_soc_of_parse_card_name(card, "nvidia,model"); if (ret) - goto err; + return ret; ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing"); if (ret) - goto err; + return ret; tegra_wm8903_dai.codecs->of_node = of_parse_phandle(np, "nvidia,audio-codec", 0); if (!tegra_wm8903_dai.codecs->of_node) { dev_err(&pdev->dev, "Property 'nvidia,audio-codec' missing or invalid\n"); - ret = -EINVAL; - goto err; + return -EINVAL; } tegra_wm8903_dai.cpus->of_node = of_parse_phandle(np, @@ -339,40 +338,31 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) if (!tegra_wm8903_dai.cpus->of_node) { dev_err(&pdev->dev, "Property 'nvidia,i2s-controller' missing or invalid\n"); - ret = -EINVAL; - goto err; + return -EINVAL; } tegra_wm8903_dai.platforms->of_node = tegra_wm8903_dai.cpus->of_node; ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); if (ret) - goto err; + return ret; ret = snd_soc_register_card(card); if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); - goto err_fini_utils; + return ret; } return 0; - -err_fini_utils: - tegra_asoc_utils_fini(&machine->util_data); -err: - return ret; } static int tegra_wm8903_driver_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); snd_soc_unregister_card(card); - tegra_asoc_utils_fini(&machine->util_data); - return 0; } diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c index b85bd9f89073..726edfa21a29 100644 --- a/sound/soc/tegra/tegra_wm9712.c +++ b/sound/soc/tegra/tegra_wm9712.c @@ -113,19 +113,17 @@ static int tegra_wm9712_driver_probe(struct platform_device *pdev) ret = tegra_asoc_utils_set_ac97_rate(&machine->util_data); if (ret) - goto asoc_utils_fini; + goto codec_unregister; ret = snd_soc_register_card(card); if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); - goto asoc_utils_fini; + goto codec_unregister; } return 0; -asoc_utils_fini: - tegra_asoc_utils_fini(&machine->util_data); codec_unregister: platform_device_del(machine->codec); codec_put: @@ -140,8 +138,6 @@ static int tegra_wm9712_driver_remove(struct platform_device *pdev) snd_soc_unregister_card(card); - tegra_asoc_utils_fini(&machine->util_data); - platform_device_unregister(machine->codec); return 0; diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index f9834afaa2e8..6dca6836aa04 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c @@ -125,8 +125,7 @@ static int tegra_snd_trimslice_probe(struct platform_device *pdev) if (!trimslice_tlv320aic23_dai.codecs->of_node) { dev_err(&pdev->dev, "Property 'nvidia,audio-codec' missing or invalid\n"); - ret = -EINVAL; - goto err; + return -EINVAL; } trimslice_tlv320aic23_dai.cpus->of_node = of_parse_phandle(np, @@ -134,8 +133,7 @@ static int tegra_snd_trimslice_probe(struct platform_device *pdev) if (!trimslice_tlv320aic23_dai.cpus->of_node) { dev_err(&pdev->dev, "Property 'nvidia,i2s-controller' missing or invalid\n"); - ret = -EINVAL; - goto err; + return -EINVAL; } trimslice_tlv320aic23_dai.platforms->of_node = @@ -143,32 +141,24 @@ static int tegra_snd_trimslice_probe(struct platform_device *pdev) ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev); if (ret) - goto err; + return ret; ret = snd_soc_register_card(card); if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); - goto err_fini_utils; + return ret; } return 0; - -err_fini_utils: - tegra_asoc_utils_fini(&trimslice->util_data); -err: - return ret; } static int tegra_snd_trimslice_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card); snd_soc_unregister_card(card); - tegra_asoc_utils_fini(&trimslice->util_data); - return 0; } diff --git a/sound/soc/ti/davinci-mcasp.c b/sound/soc/ti/davinci-mcasp.c index 734ffe925c4d..7a7db743dc5b 100644 --- a/sound/soc/ti/davinci-mcasp.c +++ b/sound/soc/ti/davinci-mcasp.c @@ -1896,8 +1896,10 @@ static int davinci_mcasp_get_dma_type(struct davinci_mcasp *mcasp) PTR_ERR(chan)); return PTR_ERR(chan); } - if (WARN_ON(!chan->device || !chan->device->dev)) + if (WARN_ON(!chan->device || !chan->device->dev)) { + dma_release_channel(chan); return -EINVAL; + } if (chan->device->dev->of_node) ret = of_property_read_string(chan->device->dev->of_node, |