提交 3fc6c5a1 编写于 作者: T Takashi Iwai

Merge tag 'asoc-fix-v4.0-rc4' of...

Merge tag 'asoc-fix-v4.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Fixes for v4.0

As well as the usual collection of driver specific fixes there's a few
more generic things:

 - Lots of fixes from Takashi for drivers using the wrong field in the
   control union to communicate with userspace, leading to potential
   errors on 64 bit systems.
 - A fix from Lars for locking of the lists of devices we maintain,
   mostly only likely to trigger during device probe and removal.
...@@ -317,7 +317,7 @@ static int adav80x_put_deemph(struct snd_kcontrol *kcontrol, ...@@ -317,7 +317,7 @@ static int adav80x_put_deemph(struct snd_kcontrol *kcontrol,
{ {
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
unsigned int deemph = ucontrol->value.enumerated.item[0]; unsigned int deemph = ucontrol->value.integer.value[0];
if (deemph > 1) if (deemph > 1)
return -EINVAL; return -EINVAL;
...@@ -333,7 +333,7 @@ static int adav80x_get_deemph(struct snd_kcontrol *kcontrol, ...@@ -333,7 +333,7 @@ static int adav80x_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
ucontrol->value.enumerated.item[0] = adav80x->deemph; ucontrol->value.integer.value[0] = adav80x->deemph;
return 0; return 0;
}; };
......
...@@ -76,7 +76,7 @@ static int ak4641_put_deemph(struct snd_kcontrol *kcontrol, ...@@ -76,7 +76,7 @@ static int ak4641_put_deemph(struct snd_kcontrol *kcontrol,
{ {
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
int deemph = ucontrol->value.enumerated.item[0]; int deemph = ucontrol->value.integer.value[0];
if (deemph > 1) if (deemph > 1)
return -EINVAL; return -EINVAL;
...@@ -92,7 +92,7 @@ static int ak4641_get_deemph(struct snd_kcontrol *kcontrol, ...@@ -92,7 +92,7 @@ static int ak4641_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
ucontrol->value.enumerated.item[0] = ak4641->deemph; ucontrol->value.integer.value[0] = ak4641->deemph;
return 0; return 0;
}; };
......
...@@ -343,25 +343,25 @@ static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = { ...@@ -343,25 +343,25 @@ static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = {
}; };
static const struct snd_soc_dapm_route ak4671_intercon[] = { static const struct snd_soc_dapm_route ak4671_intercon[] = {
{"DAC Left", "NULL", "PMPLL"}, {"DAC Left", NULL, "PMPLL"},
{"DAC Right", "NULL", "PMPLL"}, {"DAC Right", NULL, "PMPLL"},
{"ADC Left", "NULL", "PMPLL"}, {"ADC Left", NULL, "PMPLL"},
{"ADC Right", "NULL", "PMPLL"}, {"ADC Right", NULL, "PMPLL"},
/* Outputs */ /* Outputs */
{"LOUT1", "NULL", "LOUT1 Mixer"}, {"LOUT1", NULL, "LOUT1 Mixer"},
{"ROUT1", "NULL", "ROUT1 Mixer"}, {"ROUT1", NULL, "ROUT1 Mixer"},
{"LOUT2", "NULL", "LOUT2 Mix Amp"}, {"LOUT2", NULL, "LOUT2 Mix Amp"},
{"ROUT2", "NULL", "ROUT2 Mix Amp"}, {"ROUT2", NULL, "ROUT2 Mix Amp"},
{"LOUT3", "NULL", "LOUT3 Mixer"}, {"LOUT3", NULL, "LOUT3 Mixer"},
{"ROUT3", "NULL", "ROUT3 Mixer"}, {"ROUT3", NULL, "ROUT3 Mixer"},
{"LOUT1 Mixer", "DACL", "DAC Left"}, {"LOUT1 Mixer", "DACL", "DAC Left"},
{"ROUT1 Mixer", "DACR", "DAC Right"}, {"ROUT1 Mixer", "DACR", "DAC Right"},
{"LOUT2 Mixer", "DACHL", "DAC Left"}, {"LOUT2 Mixer", "DACHL", "DAC Left"},
{"ROUT2 Mixer", "DACHR", "DAC Right"}, {"ROUT2 Mixer", "DACHR", "DAC Right"},
{"LOUT2 Mix Amp", "NULL", "LOUT2 Mixer"}, {"LOUT2 Mix Amp", NULL, "LOUT2 Mixer"},
{"ROUT2 Mix Amp", "NULL", "ROUT2 Mixer"}, {"ROUT2 Mix Amp", NULL, "ROUT2 Mixer"},
{"LOUT3 Mixer", "DACSL", "DAC Left"}, {"LOUT3 Mixer", "DACSL", "DAC Left"},
{"ROUT3 Mixer", "DACSR", "DAC Right"}, {"ROUT3 Mixer", "DACSR", "DAC Right"},
...@@ -381,18 +381,18 @@ static const struct snd_soc_dapm_route ak4671_intercon[] = { ...@@ -381,18 +381,18 @@ static const struct snd_soc_dapm_route ak4671_intercon[] = {
{"LIN2", NULL, "Mic Bias"}, {"LIN2", NULL, "Mic Bias"},
{"RIN2", NULL, "Mic Bias"}, {"RIN2", NULL, "Mic Bias"},
{"ADC Left", "NULL", "LIN MUX"}, {"ADC Left", NULL, "LIN MUX"},
{"ADC Right", "NULL", "RIN MUX"}, {"ADC Right", NULL, "RIN MUX"},
/* Analog Loops */ /* Analog Loops */
{"LIN1 Mixing Circuit", "NULL", "LIN1"}, {"LIN1 Mixing Circuit", NULL, "LIN1"},
{"RIN1 Mixing Circuit", "NULL", "RIN1"}, {"RIN1 Mixing Circuit", NULL, "RIN1"},
{"LIN2 Mixing Circuit", "NULL", "LIN2"}, {"LIN2 Mixing Circuit", NULL, "LIN2"},
{"RIN2 Mixing Circuit", "NULL", "RIN2"}, {"RIN2 Mixing Circuit", NULL, "RIN2"},
{"LIN3 Mixing Circuit", "NULL", "LIN3"}, {"LIN3 Mixing Circuit", NULL, "LIN3"},
{"RIN3 Mixing Circuit", "NULL", "RIN3"}, {"RIN3 Mixing Circuit", NULL, "RIN3"},
{"LIN4 Mixing Circuit", "NULL", "LIN4"}, {"LIN4 Mixing Circuit", NULL, "LIN4"},
{"RIN4 Mixing Circuit", "NULL", "RIN4"}, {"RIN4 Mixing Circuit", NULL, "RIN4"},
{"LOUT1 Mixer", "LINL1", "LIN1 Mixing Circuit"}, {"LOUT1 Mixer", "LINL1", "LIN1 Mixing Circuit"},
{"ROUT1 Mixer", "RINR1", "RIN1 Mixing Circuit"}, {"ROUT1 Mixer", "RINR1", "RIN1 Mixing Circuit"},
......
...@@ -286,7 +286,7 @@ static int cs4271_get_deemph(struct snd_kcontrol *kcontrol, ...@@ -286,7 +286,7 @@ static int cs4271_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
ucontrol->value.enumerated.item[0] = cs4271->deemph; ucontrol->value.integer.value[0] = cs4271->deemph;
return 0; return 0;
} }
...@@ -296,7 +296,7 @@ static int cs4271_put_deemph(struct snd_kcontrol *kcontrol, ...@@ -296,7 +296,7 @@ static int cs4271_put_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
cs4271->deemph = ucontrol->value.enumerated.item[0]; cs4271->deemph = ucontrol->value.integer.value[0];
return cs4271_set_deemph(codec); return cs4271_set_deemph(codec);
} }
......
...@@ -876,11 +876,11 @@ static const struct snd_soc_dapm_widget da732x_dapm_widgets[] = { ...@@ -876,11 +876,11 @@ static const struct snd_soc_dapm_widget da732x_dapm_widgets[] = {
static const struct snd_soc_dapm_route da732x_dapm_routes[] = { static const struct snd_soc_dapm_route da732x_dapm_routes[] = {
/* Inputs */ /* Inputs */
{"AUX1L PGA", "NULL", "AUX1L"}, {"AUX1L PGA", NULL, "AUX1L"},
{"AUX1R PGA", "NULL", "AUX1R"}, {"AUX1R PGA", NULL, "AUX1R"},
{"MIC1 PGA", NULL, "MIC1"}, {"MIC1 PGA", NULL, "MIC1"},
{"MIC2 PGA", "NULL", "MIC2"}, {"MIC2 PGA", NULL, "MIC2"},
{"MIC3 PGA", "NULL", "MIC3"}, {"MIC3 PGA", NULL, "MIC3"},
/* Capture Path */ /* Capture Path */
{"ADC1 Left MUX", "MIC1", "MIC1 PGA"}, {"ADC1 Left MUX", "MIC1", "MIC1 PGA"},
......
...@@ -120,7 +120,7 @@ static int es8328_get_deemph(struct snd_kcontrol *kcontrol, ...@@ -120,7 +120,7 @@ static int es8328_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
ucontrol->value.enumerated.item[0] = es8328->deemph; ucontrol->value.integer.value[0] = es8328->deemph;
return 0; return 0;
} }
...@@ -129,7 +129,7 @@ static int es8328_put_deemph(struct snd_kcontrol *kcontrol, ...@@ -129,7 +129,7 @@ static int es8328_put_deemph(struct snd_kcontrol *kcontrol,
{ {
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
int deemph = ucontrol->value.enumerated.item[0]; int deemph = ucontrol->value.integer.value[0];
int ret; int ret;
if (deemph > 1) if (deemph > 1)
......
...@@ -118,7 +118,7 @@ static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol, ...@@ -118,7 +118,7 @@ static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
ucontrol->value.enumerated.item[0] = priv->deemph; ucontrol->value.integer.value[0] = priv->deemph;
return 0; return 0;
} }
...@@ -129,7 +129,7 @@ static int pcm1681_put_deemph(struct snd_kcontrol *kcontrol, ...@@ -129,7 +129,7 @@ static int pcm1681_put_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
priv->deemph = ucontrol->value.enumerated.item[0]; priv->deemph = ucontrol->value.integer.value[0];
return pcm1681_set_deemph(codec); return pcm1681_set_deemph(codec);
} }
......
...@@ -1198,7 +1198,7 @@ static struct dmi_system_id dmi_dell_dino[] = { ...@@ -1198,7 +1198,7 @@ static struct dmi_system_id dmi_dell_dino[] = {
.ident = "Dell Dino", .ident = "Dell Dino",
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_BOARD_NAME, "0144P8") DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343")
} }
}, },
{ } { }
......
...@@ -1151,13 +1151,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec) ...@@ -1151,13 +1151,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
/* Enable VDDC charge pump */ /* Enable VDDC charge pump */
ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP; ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP;
} else if (vddio >= 3100 && vdda >= 3100) { } else if (vddio >= 3100 && vdda >= 3100) {
/* ana_pwr &= ~SGTL5000_VDDC_CHRGPMP_POWERUP;
* if vddio and vddd > 3.1v,
* charge pump should be clean before set ana_pwr
*/
snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
SGTL5000_VDDC_CHRGPMP_POWERUP, 0);
/* VDDC use VDDIO rail */ /* VDDC use VDDIO rail */
lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD; lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD;
lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO << lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO <<
......
...@@ -538,8 +538,8 @@ static const struct snd_soc_dapm_route sn95031_audio_map[] = { ...@@ -538,8 +538,8 @@ static const struct snd_soc_dapm_route sn95031_audio_map[] = {
/* speaker map */ /* speaker map */
{ "IHFOUTL", NULL, "Speaker Rail"}, { "IHFOUTL", NULL, "Speaker Rail"},
{ "IHFOUTR", NULL, "Speaker Rail"}, { "IHFOUTR", NULL, "Speaker Rail"},
{ "IHFOUTL", "NULL", "Speaker Left Playback"}, { "IHFOUTL", NULL, "Speaker Left Playback"},
{ "IHFOUTR", "NULL", "Speaker Right Playback"}, { "IHFOUTR", NULL, "Speaker Right Playback"},
{ "Speaker Left Playback", NULL, "Speaker Left Filter"}, { "Speaker Left Playback", NULL, "Speaker Left Filter"},
{ "Speaker Right Playback", NULL, "Speaker Right Filter"}, { "Speaker Right Playback", NULL, "Speaker Right Filter"},
{ "Speaker Left Filter", NULL, "IHFDAC Left"}, { "Speaker Left Filter", NULL, "IHFDAC Left"},
......
...@@ -281,7 +281,7 @@ static int tas5086_get_deemph(struct snd_kcontrol *kcontrol, ...@@ -281,7 +281,7 @@ static int tas5086_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
ucontrol->value.enumerated.item[0] = priv->deemph; ucontrol->value.integer.value[0] = priv->deemph;
return 0; return 0;
} }
...@@ -292,7 +292,7 @@ static int tas5086_put_deemph(struct snd_kcontrol *kcontrol, ...@@ -292,7 +292,7 @@ static int tas5086_put_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
priv->deemph = ucontrol->value.enumerated.item[0]; priv->deemph = ucontrol->value.integer.value[0];
return tas5086_set_deemph(codec); return tas5086_set_deemph(codec);
} }
......
...@@ -610,7 +610,7 @@ static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol, ...@@ -610,7 +610,7 @@ static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
ucontrol->value.enumerated.item[0] = wm2000->anc_active; ucontrol->value.integer.value[0] = wm2000->anc_active;
return 0; return 0;
} }
...@@ -620,7 +620,7 @@ static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol, ...@@ -620,7 +620,7 @@ static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
{ {
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
int anc_active = ucontrol->value.enumerated.item[0]; int anc_active = ucontrol->value.integer.value[0];
int ret; int ret;
if (anc_active > 1) if (anc_active > 1)
...@@ -643,7 +643,7 @@ static int wm2000_speaker_get(struct snd_kcontrol *kcontrol, ...@@ -643,7 +643,7 @@ static int wm2000_speaker_get(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
ucontrol->value.enumerated.item[0] = wm2000->spk_ena; ucontrol->value.integer.value[0] = wm2000->spk_ena;
return 0; return 0;
} }
...@@ -653,7 +653,7 @@ static int wm2000_speaker_put(struct snd_kcontrol *kcontrol, ...@@ -653,7 +653,7 @@ static int wm2000_speaker_put(struct snd_kcontrol *kcontrol,
{ {
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
int val = ucontrol->value.enumerated.item[0]; int val = ucontrol->value.integer.value[0];
int ret; int ret;
if (val > 1) if (val > 1)
......
...@@ -125,7 +125,7 @@ static int wm8731_get_deemph(struct snd_kcontrol *kcontrol, ...@@ -125,7 +125,7 @@ static int wm8731_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
ucontrol->value.enumerated.item[0] = wm8731->deemph; ucontrol->value.integer.value[0] = wm8731->deemph;
return 0; return 0;
} }
...@@ -135,7 +135,7 @@ static int wm8731_put_deemph(struct snd_kcontrol *kcontrol, ...@@ -135,7 +135,7 @@ static int wm8731_put_deemph(struct snd_kcontrol *kcontrol,
{ {
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
int deemph = ucontrol->value.enumerated.item[0]; int deemph = ucontrol->value.integer.value[0];
int ret = 0; int ret = 0;
if (deemph > 1) if (deemph > 1)
......
...@@ -442,7 +442,7 @@ static int wm8903_get_deemph(struct snd_kcontrol *kcontrol, ...@@ -442,7 +442,7 @@ static int wm8903_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
ucontrol->value.enumerated.item[0] = wm8903->deemph; ucontrol->value.integer.value[0] = wm8903->deemph;
return 0; return 0;
} }
...@@ -452,7 +452,7 @@ static int wm8903_put_deemph(struct snd_kcontrol *kcontrol, ...@@ -452,7 +452,7 @@ static int wm8903_put_deemph(struct snd_kcontrol *kcontrol,
{ {
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
int deemph = ucontrol->value.enumerated.item[0]; int deemph = ucontrol->value.integer.value[0];
int ret = 0; int ret = 0;
if (deemph > 1) if (deemph > 1)
......
...@@ -525,7 +525,7 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol, ...@@ -525,7 +525,7 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
ucontrol->value.enumerated.item[0] = wm8904->deemph; ucontrol->value.integer.value[0] = wm8904->deemph;
return 0; return 0;
} }
...@@ -534,7 +534,7 @@ static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, ...@@ -534,7 +534,7 @@ static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
{ {
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
int deemph = ucontrol->value.enumerated.item[0]; int deemph = ucontrol->value.integer.value[0];
if (deemph > 1) if (deemph > 1)
return -EINVAL; return -EINVAL;
......
...@@ -393,7 +393,7 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol, ...@@ -393,7 +393,7 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
ucontrol->value.enumerated.item[0] = wm8955->deemph; ucontrol->value.integer.value[0] = wm8955->deemph;
return 0; return 0;
} }
...@@ -402,7 +402,7 @@ static int wm8955_put_deemph(struct snd_kcontrol *kcontrol, ...@@ -402,7 +402,7 @@ static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
{ {
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
int deemph = ucontrol->value.enumerated.item[0]; int deemph = ucontrol->value.integer.value[0];
if (deemph > 1) if (deemph > 1)
return -EINVAL; return -EINVAL;
......
...@@ -184,7 +184,7 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol, ...@@ -184,7 +184,7 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
ucontrol->value.enumerated.item[0] = wm8960->deemph; ucontrol->value.integer.value[0] = wm8960->deemph;
return 0; return 0;
} }
...@@ -193,7 +193,7 @@ static int wm8960_put_deemph(struct snd_kcontrol *kcontrol, ...@@ -193,7 +193,7 @@ static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
{ {
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
int deemph = ucontrol->value.enumerated.item[0]; int deemph = ucontrol->value.integer.value[0];
if (deemph > 1) if (deemph > 1)
return -EINVAL; return -EINVAL;
......
...@@ -180,7 +180,7 @@ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol, ...@@ -180,7 +180,7 @@ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
unsigned int val = ucontrol->value.enumerated.item[0]; unsigned int val = ucontrol->value.integer.value[0];
struct soc_mixer_control *mc = struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value; (struct soc_mixer_control *)kcontrol->private_value;
unsigned int mixer, mask, shift, old; unsigned int mixer, mask, shift, old;
...@@ -193,7 +193,7 @@ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol, ...@@ -193,7 +193,7 @@ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol,
mutex_lock(&wm9712->lock); mutex_lock(&wm9712->lock);
old = wm9712->hp_mixer[mixer]; old = wm9712->hp_mixer[mixer];
if (ucontrol->value.enumerated.item[0]) if (ucontrol->value.integer.value[0])
wm9712->hp_mixer[mixer] |= mask; wm9712->hp_mixer[mixer] |= mask;
else else
wm9712->hp_mixer[mixer] &= ~mask; wm9712->hp_mixer[mixer] &= ~mask;
...@@ -231,7 +231,7 @@ static int wm9712_hp_mixer_get(struct snd_kcontrol *kcontrol, ...@@ -231,7 +231,7 @@ static int wm9712_hp_mixer_get(struct snd_kcontrol *kcontrol,
mixer = mc->shift >> 8; mixer = mc->shift >> 8;
shift = mc->shift & 0xff; shift = mc->shift & 0xff;
ucontrol->value.enumerated.item[0] = ucontrol->value.integer.value[0] =
(wm9712->hp_mixer[mixer] >> shift) & 1; (wm9712->hp_mixer[mixer] >> shift) & 1;
return 0; return 0;
......
...@@ -255,7 +255,7 @@ static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol, ...@@ -255,7 +255,7 @@ static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
unsigned int val = ucontrol->value.enumerated.item[0]; unsigned int val = ucontrol->value.integer.value[0];
struct soc_mixer_control *mc = struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value; (struct soc_mixer_control *)kcontrol->private_value;
unsigned int mixer, mask, shift, old; unsigned int mixer, mask, shift, old;
...@@ -268,7 +268,7 @@ static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol, ...@@ -268,7 +268,7 @@ static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol,
mutex_lock(&wm9713->lock); mutex_lock(&wm9713->lock);
old = wm9713->hp_mixer[mixer]; old = wm9713->hp_mixer[mixer];
if (ucontrol->value.enumerated.item[0]) if (ucontrol->value.integer.value[0])
wm9713->hp_mixer[mixer] |= mask; wm9713->hp_mixer[mixer] |= mask;
else else
wm9713->hp_mixer[mixer] &= ~mask; wm9713->hp_mixer[mixer] &= ~mask;
...@@ -306,7 +306,7 @@ static int wm9713_hp_mixer_get(struct snd_kcontrol *kcontrol, ...@@ -306,7 +306,7 @@ static int wm9713_hp_mixer_get(struct snd_kcontrol *kcontrol,
mixer = mc->shift >> 8; mixer = mc->shift >> 8;
shift = mc->shift & 0xff; shift = mc->shift & 0xff;
ucontrol->value.enumerated.item[0] = ucontrol->value.integer.value[0] =
(wm9713->hp_mixer[mixer] >> shift) & 1; (wm9713->hp_mixer[mixer] >> shift) & 1;
return 0; return 0;
......
...@@ -603,7 +603,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, ...@@ -603,7 +603,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
factor = (div2 + 1) * (7 * psr + 1) * 2; factor = (div2 + 1) * (7 * psr + 1) * 2;
for (i = 0; i < 255; i++) { for (i = 0; i < 255; i++) {
tmprate = freq * factor * (i + 2); tmprate = freq * factor * (i + 1);
if (baudclk_is_used) if (baudclk_is_used)
clkrate = clk_get_rate(ssi_private->baudclk); clkrate = clk_get_rate(ssi_private->baudclk);
...@@ -1227,7 +1227,7 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev, ...@@ -1227,7 +1227,7 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + CCSR_SSI_STX0; ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + CCSR_SSI_STX0;
ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + CCSR_SSI_SRX0; ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + CCSR_SSI_SRX0;
ret = !of_property_read_u32_array(np, "dmas", dmas, 4); ret = of_property_read_u32_array(np, "dmas", dmas, 4);
if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) { if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
ssi_private->use_dual_fifo = true; ssi_private->use_dual_fifo = true;
/* When using dual fifo mode, we need to keep watermark /* When using dual fifo mode, we need to keep watermark
......
...@@ -207,9 +207,6 @@ static int hsw_parse_fw_image(struct sst_fw *sst_fw) ...@@ -207,9 +207,6 @@ static int hsw_parse_fw_image(struct sst_fw *sst_fw)
module = (void *)module + sizeof(*module) + module->mod_size; module = (void *)module + sizeof(*module) + module->mod_size;
} }
/* allocate scratch mem regions */
sst_block_alloc_scratch(dsp);
return 0; return 0;
} }
......
...@@ -1732,6 +1732,7 @@ static void sst_hsw_drop_all(struct sst_hsw *hsw) ...@@ -1732,6 +1732,7 @@ static void sst_hsw_drop_all(struct sst_hsw *hsw)
int sst_hsw_dsp_load(struct sst_hsw *hsw) int sst_hsw_dsp_load(struct sst_hsw *hsw)
{ {
struct sst_dsp *dsp = hsw->dsp; struct sst_dsp *dsp = hsw->dsp;
struct sst_fw *sst_fw, *t;
int ret; int ret;
dev_dbg(hsw->dev, "loading audio DSP...."); dev_dbg(hsw->dev, "loading audio DSP....");
...@@ -1748,12 +1749,17 @@ int sst_hsw_dsp_load(struct sst_hsw *hsw) ...@@ -1748,12 +1749,17 @@ int sst_hsw_dsp_load(struct sst_hsw *hsw)
return ret; return ret;
} }
ret = sst_fw_reload(hsw->sst_fw); list_for_each_entry_safe_reverse(sst_fw, t, &dsp->fw_list, list) {
if (ret < 0) { ret = sst_fw_reload(sst_fw);
dev_err(hsw->dev, "error: SST FW reload failed\n"); if (ret < 0) {
sst_dsp_dma_put_channel(dsp); dev_err(hsw->dev, "error: SST FW reload failed\n");
return -ENOMEM; sst_dsp_dma_put_channel(dsp);
return -ENOMEM;
}
} }
ret = sst_block_alloc_scratch(hsw->dsp);
if (ret < 0)
return -EINVAL;
sst_dsp_dma_put_channel(dsp); sst_dsp_dma_put_channel(dsp);
return 0; return 0;
...@@ -1809,12 +1815,17 @@ int sst_hsw_dsp_runtime_suspend(struct sst_hsw *hsw) ...@@ -1809,12 +1815,17 @@ int sst_hsw_dsp_runtime_suspend(struct sst_hsw *hsw)
int sst_hsw_dsp_runtime_sleep(struct sst_hsw *hsw) int sst_hsw_dsp_runtime_sleep(struct sst_hsw *hsw)
{ {
sst_fw_unload(hsw->sst_fw); struct sst_fw *sst_fw, *t;
sst_block_free_scratch(hsw->dsp); struct sst_dsp *dsp = hsw->dsp;
list_for_each_entry_safe(sst_fw, t, &dsp->fw_list, list) {
sst_fw_unload(sst_fw);
}
sst_block_free_scratch(dsp);
hsw->boot_complete = false; hsw->boot_complete = false;
sst_dsp_sleep(hsw->dsp); sst_dsp_sleep(dsp);
return 0; return 0;
} }
...@@ -1943,6 +1954,11 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata) ...@@ -1943,6 +1954,11 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
goto fw_err; goto fw_err;
} }
/* allocate scratch mem regions */
ret = sst_block_alloc_scratch(hsw->dsp);
if (ret < 0)
goto boot_err;
/* wait for DSP boot completion */ /* wait for DSP boot completion */
sst_dsp_boot(hsw->dsp); sst_dsp_boot(hsw->dsp);
ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete, ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete,
......
...@@ -347,6 +347,8 @@ static ssize_t codec_list_read_file(struct file *file, char __user *user_buf, ...@@ -347,6 +347,8 @@ static ssize_t codec_list_read_file(struct file *file, char __user *user_buf,
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
mutex_lock(&client_mutex);
list_for_each_entry(codec, &codec_list, list) { list_for_each_entry(codec, &codec_list, list) {
len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
codec->component.name); codec->component.name);
...@@ -358,6 +360,8 @@ static ssize_t codec_list_read_file(struct file *file, char __user *user_buf, ...@@ -358,6 +360,8 @@ static ssize_t codec_list_read_file(struct file *file, char __user *user_buf,
} }
} }
mutex_unlock(&client_mutex);
if (ret >= 0) if (ret >= 0)
ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
...@@ -382,6 +386,8 @@ static ssize_t dai_list_read_file(struct file *file, char __user *user_buf, ...@@ -382,6 +386,8 @@ static ssize_t dai_list_read_file(struct file *file, char __user *user_buf,
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
mutex_lock(&client_mutex);
list_for_each_entry(component, &component_list, list) { list_for_each_entry(component, &component_list, list) {
list_for_each_entry(dai, &component->dai_list, list) { list_for_each_entry(dai, &component->dai_list, list) {
len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
...@@ -395,6 +401,8 @@ static ssize_t dai_list_read_file(struct file *file, char __user *user_buf, ...@@ -395,6 +401,8 @@ static ssize_t dai_list_read_file(struct file *file, char __user *user_buf,
} }
} }
mutex_unlock(&client_mutex);
ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
kfree(buf); kfree(buf);
...@@ -418,6 +426,8 @@ static ssize_t platform_list_read_file(struct file *file, ...@@ -418,6 +426,8 @@ static ssize_t platform_list_read_file(struct file *file,
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
mutex_lock(&client_mutex);
list_for_each_entry(platform, &platform_list, list) { list_for_each_entry(platform, &platform_list, list) {
len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
platform->component.name); platform->component.name);
...@@ -429,6 +439,8 @@ static ssize_t platform_list_read_file(struct file *file, ...@@ -429,6 +439,8 @@ static ssize_t platform_list_read_file(struct file *file,
} }
} }
mutex_unlock(&client_mutex);
ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
kfree(buf); kfree(buf);
...@@ -836,6 +848,8 @@ static struct snd_soc_component *soc_find_component( ...@@ -836,6 +848,8 @@ static struct snd_soc_component *soc_find_component(
{ {
struct snd_soc_component *component; struct snd_soc_component *component;
lockdep_assert_held(&client_mutex);
list_for_each_entry(component, &component_list, list) { list_for_each_entry(component, &component_list, list) {
if (of_node) { if (of_node) {
if (component->dev->of_node == of_node) if (component->dev->of_node == of_node)
...@@ -854,6 +868,8 @@ static struct snd_soc_dai *snd_soc_find_dai( ...@@ -854,6 +868,8 @@ static struct snd_soc_dai *snd_soc_find_dai(
struct snd_soc_component *component; struct snd_soc_component *component;
struct snd_soc_dai *dai; struct snd_soc_dai *dai;
lockdep_assert_held(&client_mutex);
/* Find CPU DAI from registered DAIs*/ /* Find CPU DAI from registered DAIs*/
list_for_each_entry(component, &component_list, list) { list_for_each_entry(component, &component_list, list) {
if (dlc->of_node && component->dev->of_node != dlc->of_node) if (dlc->of_node && component->dev->of_node != dlc->of_node)
...@@ -1508,6 +1524,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) ...@@ -1508,6 +1524,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
struct snd_soc_codec *codec; struct snd_soc_codec *codec;
int ret, i, order; int ret, i, order;
mutex_lock(&client_mutex);
mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT); mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);
/* bind DAIs */ /* bind DAIs */
...@@ -1662,6 +1679,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) ...@@ -1662,6 +1679,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
card->instantiated = 1; card->instantiated = 1;
snd_soc_dapm_sync(&card->dapm); snd_soc_dapm_sync(&card->dapm);
mutex_unlock(&card->mutex); mutex_unlock(&card->mutex);
mutex_unlock(&client_mutex);
return 0; return 0;
...@@ -1680,6 +1698,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) ...@@ -1680,6 +1698,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
base_error: base_error:
mutex_unlock(&card->mutex); mutex_unlock(&card->mutex);
mutex_unlock(&client_mutex);
return ret; return ret;
} }
...@@ -2713,13 +2732,6 @@ static void snd_soc_component_del_unlocked(struct snd_soc_component *component) ...@@ -2713,13 +2732,6 @@ static void snd_soc_component_del_unlocked(struct snd_soc_component *component)
list_del(&component->list); list_del(&component->list);
} }
static void snd_soc_component_del(struct snd_soc_component *component)
{
mutex_lock(&client_mutex);
snd_soc_component_del_unlocked(component);
mutex_unlock(&client_mutex);
}
int snd_soc_register_component(struct device *dev, int snd_soc_register_component(struct device *dev,
const struct snd_soc_component_driver *cmpnt_drv, const struct snd_soc_component_driver *cmpnt_drv,
struct snd_soc_dai_driver *dai_drv, struct snd_soc_dai_driver *dai_drv,
...@@ -2767,14 +2779,17 @@ void snd_soc_unregister_component(struct device *dev) ...@@ -2767,14 +2779,17 @@ void snd_soc_unregister_component(struct device *dev)
{ {
struct snd_soc_component *cmpnt; struct snd_soc_component *cmpnt;
mutex_lock(&client_mutex);
list_for_each_entry(cmpnt, &component_list, list) { list_for_each_entry(cmpnt, &component_list, list) {
if (dev == cmpnt->dev && cmpnt->registered_as_component) if (dev == cmpnt->dev && cmpnt->registered_as_component)
goto found; goto found;
} }
mutex_unlock(&client_mutex);
return; return;
found: found:
snd_soc_component_del(cmpnt); snd_soc_component_del_unlocked(cmpnt);
mutex_unlock(&client_mutex);
snd_soc_component_cleanup(cmpnt); snd_soc_component_cleanup(cmpnt);
kfree(cmpnt); kfree(cmpnt);
} }
...@@ -2882,10 +2897,14 @@ struct snd_soc_platform *snd_soc_lookup_platform(struct device *dev) ...@@ -2882,10 +2897,14 @@ struct snd_soc_platform *snd_soc_lookup_platform(struct device *dev)
{ {
struct snd_soc_platform *platform; struct snd_soc_platform *platform;
mutex_lock(&client_mutex);
list_for_each_entry(platform, &platform_list, list) { list_for_each_entry(platform, &platform_list, list) {
if (dev == platform->dev) if (dev == platform->dev) {
mutex_unlock(&client_mutex);
return platform; return platform;
}
} }
mutex_unlock(&client_mutex);
return NULL; return NULL;
} }
...@@ -3090,15 +3109,15 @@ void snd_soc_unregister_codec(struct device *dev) ...@@ -3090,15 +3109,15 @@ void snd_soc_unregister_codec(struct device *dev)
{ {
struct snd_soc_codec *codec; struct snd_soc_codec *codec;
mutex_lock(&client_mutex);
list_for_each_entry(codec, &codec_list, list) { list_for_each_entry(codec, &codec_list, list) {
if (dev == codec->dev) if (dev == codec->dev)
goto found; goto found;
} }
mutex_unlock(&client_mutex);
return; return;
found: found:
mutex_lock(&client_mutex);
list_del(&codec->list); list_del(&codec->list);
snd_soc_component_del_unlocked(&codec->component); snd_soc_component_del_unlocked(&codec->component);
mutex_unlock(&client_mutex); mutex_unlock(&client_mutex);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册