Skip to content

Commit

Permalink
Merge tag 'asoc-fix-v5.0-rc2' of https://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/broonie/sound into for-linus

ASoC: Fixes for v5.0

Quite a big batch of fixes here.  There's a couple of things going on,
the main one is that we found some issues with not deferring probe when
we should, causing us to skip some driver initialization.  The fixes for
this then in turn exposed some issues with how we were searching for
components which had previously gone unnoticed due to the original
issue.

There's also been the normal driver specific stuff and there's been what
looks like several batches of automated scanning for issues which have
generated quite a large set of smaller fixes for potential crashes and
missed error handling.
  • Loading branch information
Takashi Iwai committed Jan 18, 2019
2 parents 687ae9e + 4cb79ef commit b3c4014
Show file tree
Hide file tree
Showing 23 changed files with 208 additions and 184 deletions.
6 changes: 6 additions & 0 deletions include/sound/soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,12 @@ struct snd_soc_dai_link {
/* Do not create a PCM for this DAI link (Backend link) */
unsigned int ignore:1;

/*
* This driver uses legacy platform naming. Set by the core, machine
* drivers should not modify this value.
*/
unsigned int legacy_platform:1;

struct list_head list; /* DAI link list of the soc card */
struct snd_soc_dobj dobj; /* For topology */
};
Expand Down
3 changes: 2 additions & 1 deletion sound/core/compress_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,8 @@ static int snd_compress_check_input(struct snd_compr_params *params)
{
/* first let's check the buffer parameter's */
if (params->buffer.fragment_size == 0 ||
params->buffer.fragments > INT_MAX / params->buffer.fragment_size)
params->buffer.fragments > INT_MAX / params->buffer.fragment_size ||
params->buffer.fragments == 0)
return -EINVAL;

/* now codec parameters */
Expand Down
6 changes: 4 additions & 2 deletions sound/soc/amd/raven/acp3x-pcm-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,14 +611,16 @@ static int acp3x_audio_probe(struct platform_device *pdev)
}
irqflags = *((unsigned int *)(pdev->dev.platform_data));

adata = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dev_data),
GFP_KERNEL);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n");
return -ENODEV;
}

adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL);
if (!adata)
return -ENOMEM;

adata->acp3x_base = devm_ioremap(&pdev->dev, res->start,
resource_size(res));

Expand Down
11 changes: 4 additions & 7 deletions sound/soc/codecs/pcm512x.c
Original file line number Diff line number Diff line change
Expand Up @@ -1400,24 +1400,20 @@ static int pcm512x_digital_mute(struct snd_soc_dai *dai, int mute)
if (ret != 0) {
dev_err(component->dev,
"Failed to set digital mute: %d\n", ret);
mutex_unlock(&pcm512x->mutex);
return ret;
goto unlock;
}

regmap_read_poll_timeout(pcm512x->regmap,
PCM512x_ANALOG_MUTE_DET,
mute_det, (mute_det & 0x3) == 0,
200, 10000);

mutex_unlock(&pcm512x->mutex);
} else {
pcm512x->mute &= ~0x1;
ret = pcm512x_update_mute(pcm512x);
if (ret != 0) {
dev_err(component->dev,
"Failed to update digital mute: %d\n", ret);
mutex_unlock(&pcm512x->mutex);
return ret;
goto unlock;
}

regmap_read_poll_timeout(pcm512x->regmap,
Expand All @@ -1428,9 +1424,10 @@ static int pcm512x_digital_mute(struct snd_soc_dai *dai, int mute)
200, 10000);
}

unlock:
mutex_unlock(&pcm512x->mutex);

return 0;
return ret;
}

static const struct snd_soc_dai_ops pcm512x_dai_ops = {
Expand Down
5 changes: 4 additions & 1 deletion sound/soc/codecs/rt274.c
Original file line number Diff line number Diff line change
Expand Up @@ -1128,8 +1128,11 @@ static int rt274_i2c_probe(struct i2c_client *i2c,
return ret;
}

regmap_read(rt274->regmap,
ret = regmap_read(rt274->regmap,
RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &val);
if (ret)
return ret;

if (val != RT274_VENDOR_ID) {
dev_err(&i2c->dev,
"Device with ID register %#x is not rt274\n", val);
Expand Down
2 changes: 2 additions & 0 deletions sound/soc/codecs/rt5514-spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,8 @@ static int rt5514_spi_pcm_probe(struct snd_soc_component *component)

rt5514_dsp = devm_kzalloc(component->dev, sizeof(*rt5514_dsp),
GFP_KERNEL);
if (!rt5514_dsp)
return -ENOMEM;

rt5514_dsp->dev = &rt5514_spi->dev;
mutex_init(&rt5514_dsp->dma_lock);
Expand Down
1 change: 1 addition & 0 deletions sound/soc/codecs/rt5682.c
Original file line number Diff line number Diff line change
Expand Up @@ -2512,6 +2512,7 @@ static void rt5682_calibrate(struct rt5682_priv *rt5682)
regmap_write(rt5682->regmap, RT5682_PWR_DIG_1, 0x0000);
regmap_write(rt5682->regmap, RT5682_CHOP_DAC, 0x2000);
regmap_write(rt5682->regmap, RT5682_CALIB_ADC_CTRL, 0x2005);
regmap_write(rt5682->regmap, RT5682_STO1_ADC_MIXER, 0xc0c4);

mutex_unlock(&rt5682->calibrate_mutex);

Expand Down
24 changes: 12 additions & 12 deletions sound/soc/codecs/rt5682.h
Original file line number Diff line number Diff line change
Expand Up @@ -849,18 +849,18 @@
#define RT5682_SCLK_SRC_PLL2 (0x2 << 13)
#define RT5682_SCLK_SRC_SDW (0x3 << 13)
#define RT5682_SCLK_SRC_RCCLK (0x4 << 13)
#define RT5682_PLL1_SRC_MASK (0x3 << 10)
#define RT5682_PLL1_SRC_SFT 10
#define RT5682_PLL1_SRC_MCLK (0x0 << 10)
#define RT5682_PLL1_SRC_BCLK1 (0x1 << 10)
#define RT5682_PLL1_SRC_SDW (0x2 << 10)
#define RT5682_PLL1_SRC_RC (0x3 << 10)
#define RT5682_PLL2_SRC_MASK (0x3 << 8)
#define RT5682_PLL2_SRC_SFT 8
#define RT5682_PLL2_SRC_MCLK (0x0 << 8)
#define RT5682_PLL2_SRC_BCLK1 (0x1 << 8)
#define RT5682_PLL2_SRC_SDW (0x2 << 8)
#define RT5682_PLL2_SRC_RC (0x3 << 8)
#define RT5682_PLL2_SRC_MASK (0x3 << 10)
#define RT5682_PLL2_SRC_SFT 10
#define RT5682_PLL2_SRC_MCLK (0x0 << 10)
#define RT5682_PLL2_SRC_BCLK1 (0x1 << 10)
#define RT5682_PLL2_SRC_SDW (0x2 << 10)
#define RT5682_PLL2_SRC_RC (0x3 << 10)
#define RT5682_PLL1_SRC_MASK (0x3 << 8)
#define RT5682_PLL1_SRC_SFT 8
#define RT5682_PLL1_SRC_MCLK (0x0 << 8)
#define RT5682_PLL1_SRC_BCLK1 (0x1 << 8)
#define RT5682_PLL1_SRC_SDW (0x2 << 8)
#define RT5682_PLL1_SRC_RC (0x3 << 8)



Expand Down
4 changes: 4 additions & 0 deletions sound/soc/codecs/tlv320aic32x4.c
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,10 @@ static int aic32x4_set_bias_level(struct snd_soc_component *component,
case SND_SOC_BIAS_PREPARE:
break;
case SND_SOC_BIAS_STANDBY:
/* Initial cold start */
if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
break;

/* Switch off BCLK_N Divider */
snd_soc_component_update_bits(component, AIC32X4_BCLKN,
AIC32X4_BCLKEN, 0);
Expand Down
24 changes: 12 additions & 12 deletions sound/soc/fsl/imx-audmux.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,49 +86,49 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
if (!buf)
return -ENOMEM;

ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
ret = scnprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
pdcr, ptcr);

if (ptcr & IMX_AUDMUX_V2_PTCR_TFSDIR)
ret += snprintf(buf + ret, PAGE_SIZE - ret,
ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"TxFS output from %s, ",
audmux_port_string((ptcr >> 27) & 0x7));
else
ret += snprintf(buf + ret, PAGE_SIZE - ret,
ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"TxFS input, ");

if (ptcr & IMX_AUDMUX_V2_PTCR_TCLKDIR)
ret += snprintf(buf + ret, PAGE_SIZE - ret,
ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"TxClk output from %s",
audmux_port_string((ptcr >> 22) & 0x7));
else
ret += snprintf(buf + ret, PAGE_SIZE - ret,
ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"TxClk input");

ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\n");

if (ptcr & IMX_AUDMUX_V2_PTCR_SYN) {
ret += snprintf(buf + ret, PAGE_SIZE - ret,
ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"Port is symmetric");
} else {
if (ptcr & IMX_AUDMUX_V2_PTCR_RFSDIR)
ret += snprintf(buf + ret, PAGE_SIZE - ret,
ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"RxFS output from %s, ",
audmux_port_string((ptcr >> 17) & 0x7));
else
ret += snprintf(buf + ret, PAGE_SIZE - ret,
ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"RxFS input, ");

if (ptcr & IMX_AUDMUX_V2_PTCR_RCLKDIR)
ret += snprintf(buf + ret, PAGE_SIZE - ret,
ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"RxClk output from %s",
audmux_port_string((ptcr >> 12) & 0x7));
else
ret += snprintf(buf + ret, PAGE_SIZE - ret,
ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"RxClk input");
}

ret += snprintf(buf + ret, PAGE_SIZE - ret,
ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"\nData received from %s\n",
audmux_port_string((pdcr >> 13) & 0x7));

Expand Down
2 changes: 1 addition & 1 deletion sound/soc/intel/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ config SND_SST_ATOM_HIFI2_PLATFORM_PCI
config SND_SST_ATOM_HIFI2_PLATFORM_ACPI
tristate "ACPI HiFi2 (Baytrail, Cherrytrail) Platforms"
default ACPI
depends on X86 && ACPI
depends on X86 && ACPI && PCI
select SND_SST_IPC_ACPI
select SND_SST_ATOM_HIFI2_PLATFORM
select SND_SOC_ACPI_INTEL_MATCH
Expand Down
8 changes: 7 additions & 1 deletion sound/soc/intel/atom/sst-mfld-platform-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,13 @@ static int sst_media_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
int ret;

ret =
snd_pcm_lib_malloc_pages(substream,
params_buffer_bytes(params));
if (ret)
return ret;
memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/intel/boards/broadwell.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = {
.stream_name = "Loopback",
.cpu_dai_name = "Loopback Pin",
.platform_name = "haswell-pcm-audio",
.dynamic = 0,
.dynamic = 1,
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
Expand Down
45 changes: 7 additions & 38 deletions sound/soc/intel/boards/glk_rt5682_max98357a.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,39 +55,6 @@ enum {
GLK_DPCM_AUDIO_HDMI3_PB,
};

static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
struct snd_soc_dapm_context *dapm = w->dapm;
struct snd_soc_card *card = dapm->card;
struct snd_soc_dai *codec_dai;
int ret = 0;

codec_dai = snd_soc_card_get_codec_dai(card, GLK_REALTEK_CODEC_DAI);
if (!codec_dai) {
dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n");
return -EIO;
}

if (SND_SOC_DAPM_EVENT_OFF(event)) {
ret = snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
if (ret)
dev_err(card->dev, "failed to stop sysclk: %d\n", ret);
} else if (SND_SOC_DAPM_EVENT_ON(event)) {
ret = snd_soc_dai_set_pll(codec_dai, 0, RT5682_PLL1_S_MCLK,
GLK_PLAT_CLK_FREQ, RT5682_PLL_FREQ);
if (ret < 0) {
dev_err(card->dev, "can't set codec pll: %d\n", ret);
return ret;
}
}

if (ret)
dev_err(card->dev, "failed to start internal clk: %d\n", ret);

return ret;
}

static const struct snd_kcontrol_new geminilake_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone Jack"),
SOC_DAPM_PIN_SWITCH("Headset Mic"),
Expand All @@ -102,22 +69,17 @@ static const struct snd_soc_dapm_widget geminilake_widgets[] = {
SND_SOC_DAPM_SPK("HDMI1", NULL),
SND_SOC_DAPM_SPK("HDMI2", NULL),
SND_SOC_DAPM_SPK("HDMI3", NULL),
SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
platform_clock_control, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
};

static const struct snd_soc_dapm_route geminilake_map[] = {
/* HP jack connectors - unknown if we have jack detection */
{ "Headphone Jack", NULL, "Platform Clock" },
{ "Headphone Jack", NULL, "HPOL" },
{ "Headphone Jack", NULL, "HPOR" },

/* speaker */
{ "Spk", NULL, "Speaker" },

/* other jacks */
{ "Headset Mic", NULL, "Platform Clock" },
{ "IN1P", NULL, "Headset Mic" },

/* digital mics */
Expand Down Expand Up @@ -177,6 +139,13 @@ static int geminilake_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
struct snd_soc_jack *jack;
int ret;

ret = snd_soc_dai_set_pll(codec_dai, 0, RT5682_PLL1_S_MCLK,
GLK_PLAT_CLK_FREQ, RT5682_PLL_FREQ);
if (ret < 0) {
dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
return ret;
}

/* Configure sysclk for codec */
ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1,
RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/intel/boards/haswell.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ static struct snd_soc_dai_link haswell_rt5640_dais[] = {
.stream_name = "Loopback",
.cpu_dai_name = "Loopback Pin",
.platform_name = "haswell-pcm-audio",
.dynamic = 0,
.dynamic = 1,
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
Expand Down
17 changes: 12 additions & 5 deletions sound/soc/qcom/qdsp6/q6asm-dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,10 +570,10 @@ static int q6asm_dai_compr_open(struct snd_compr_stream *stream)
prtd->audio_client = q6asm_audio_client_alloc(dev,
(q6asm_cb)compress_event_handler,
prtd, stream_id, LEGACY_PCM_MODE);
if (!prtd->audio_client) {
if (IS_ERR(prtd->audio_client)) {
dev_err(dev, "Could not allocate memory\n");
kfree(prtd);
return -ENOMEM;
ret = PTR_ERR(prtd->audio_client);
goto free_prtd;
}

size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE *
Expand All @@ -582,7 +582,7 @@ static int q6asm_dai_compr_open(struct snd_compr_stream *stream)
&prtd->dma_buffer);
if (ret) {
dev_err(dev, "Cannot allocate buffer(s)\n");
return ret;
goto free_client;
}

if (pdata->sid < 0)
Expand All @@ -595,6 +595,13 @@ static int q6asm_dai_compr_open(struct snd_compr_stream *stream)
runtime->private_data = prtd;

return 0;

free_client:
q6asm_audio_client_free(prtd->audio_client);
free_prtd:
kfree(prtd);

return ret;
}

static int q6asm_dai_compr_free(struct snd_compr_stream *stream)
Expand Down Expand Up @@ -874,7 +881,7 @@ static int of_q6asm_parse_dai_data(struct device *dev,

for_each_child_of_node(dev->of_node, node) {
ret = of_property_read_u32(node, "reg", &id);
if (ret || id > MAX_SESSIONS || id < 0) {
if (ret || id >= MAX_SESSIONS || id < 0) {
dev_err(dev, "valid dai id not found:%d\n", ret);
continue;
}
Expand Down
Loading

0 comments on commit b3c4014

Please sign in to comment.