Commit d2255c01 authored by Takashi Iwai's avatar Takashi Iwai

Merge tag 'asoc-fix-ac97-v3.19-rc7' of...

Merge tag 'asoc-fix-ac97-v3.19-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: AC'97 fixes

These are rather too large for this late in the release cycle but
they're clear, well understood and have been tested to fix a regression
which was introduced for v3.19.  The details are all in Lars' changelog
and they've been cooking in -next for a while, to a large extent out
of conservatism about the size.
parents deb08737 f8d71be5
...@@ -498,6 +498,7 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg, ...@@ -498,6 +498,7 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
unsigned int mask, unsigned int value); unsigned int mask, unsigned int value);
#ifdef CONFIG_SND_SOC_AC97_BUS #ifdef CONFIG_SND_SOC_AC97_BUS
struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec);
struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec); struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec);
void snd_soc_free_ac97_codec(struct snd_ac97 *ac97); void snd_soc_free_ac97_codec(struct snd_ac97 *ac97);
......
...@@ -344,23 +344,27 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec) ...@@ -344,23 +344,27 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
struct snd_ac97 *ac97; struct snd_ac97 *ac97;
int ret = 0; int ret = 0;
ac97 = snd_soc_new_ac97_codec(codec); ac97 = snd_soc_alloc_ac97_codec(codec);
if (IS_ERR(ac97)) { if (IS_ERR(ac97)) {
ret = PTR_ERR(ac97); ret = PTR_ERR(ac97);
dev_err(codec->dev, "Failed to register AC97 codec\n"); dev_err(codec->dev, "Failed to register AC97 codec\n");
return ret; return ret;
} }
snd_soc_codec_set_drvdata(codec, ac97);
ret = wm9705_reset(codec); ret = wm9705_reset(codec);
if (ret) if (ret)
goto reset_err; goto err_put_device;
ret = device_add(&ac97->dev);
if (ret)
goto err_put_device;
snd_soc_codec_set_drvdata(codec, ac97);
return 0; return 0;
reset_err: err_put_device:
snd_soc_free_ac97_codec(ac97); put_device(&ac97->dev);
return ret; return ret;
} }
......
...@@ -666,7 +666,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) ...@@ -666,7 +666,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
int ret = 0; int ret = 0;
wm9712->ac97 = snd_soc_new_ac97_codec(codec); wm9712->ac97 = snd_soc_alloc_ac97_codec(codec);
if (IS_ERR(wm9712->ac97)) { if (IS_ERR(wm9712->ac97)) {
ret = PTR_ERR(wm9712->ac97); ret = PTR_ERR(wm9712->ac97);
dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret); dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret);
...@@ -675,15 +675,19 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) ...@@ -675,15 +675,19 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
ret = wm9712_reset(codec, 0); ret = wm9712_reset(codec, 0);
if (ret < 0) if (ret < 0)
goto reset_err; goto err_put_device;
ret = device_add(&wm9712->ac97->dev);
if (ret)
goto err_put_device;
/* set alc mux to none */ /* set alc mux to none */
ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000);
return 0; return 0;
reset_err: err_put_device:
snd_soc_free_ac97_codec(wm9712->ac97); put_device(&wm9712->ac97->dev);
return ret; return ret;
} }
......
...@@ -1225,7 +1225,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) ...@@ -1225,7 +1225,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
int ret = 0, reg; int ret = 0, reg;
wm9713->ac97 = snd_soc_new_ac97_codec(codec); wm9713->ac97 = snd_soc_alloc_ac97_codec(codec);
if (IS_ERR(wm9713->ac97)) if (IS_ERR(wm9713->ac97))
return PTR_ERR(wm9713->ac97); return PTR_ERR(wm9713->ac97);
...@@ -1234,7 +1234,11 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) ...@@ -1234,7 +1234,11 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
wm9713_reset(codec, 0); wm9713_reset(codec, 0);
ret = wm9713_reset(codec, 1); ret = wm9713_reset(codec, 1);
if (ret < 0) if (ret < 0)
goto reset_err; goto err_put_device;
ret = device_add(&wm9713->ac97->dev);
if (ret)
goto err_put_device;
/* unmute the adc - move to kcontrol */ /* unmute the adc - move to kcontrol */
reg = ac97_read(codec, AC97_CD) & 0x7fff; reg = ac97_read(codec, AC97_CD) & 0x7fff;
...@@ -1242,8 +1246,8 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) ...@@ -1242,8 +1246,8 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
return 0; return 0;
reset_err: err_put_device:
snd_soc_free_ac97_codec(wm9713->ac97); put_device(&wm9713->ac97->dev);
return ret; return ret;
} }
......
...@@ -48,15 +48,18 @@ static void soc_ac97_device_release(struct device *dev) ...@@ -48,15 +48,18 @@ static void soc_ac97_device_release(struct device *dev)
} }
/** /**
* snd_soc_new_ac97_codec - initailise AC97 device * snd_soc_alloc_ac97_codec() - Allocate new a AC'97 device
* @codec: audio codec * @codec: The CODEC for which to create the AC'97 device
* *
* Initialises AC97 codec resources for use by ad-hoc devices only. * Allocated a new snd_ac97 device and intializes it, but does not yet register
* it. The caller is responsible to either call device_add(&ac97->dev) to
* register the device, or to call put_device(&ac97->dev) to free the device.
*
* Returns: A snd_ac97 device or a PTR_ERR in case of an error.
*/ */
struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec) struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec)
{ {
struct snd_ac97 *ac97; struct snd_ac97 *ac97;
int ret;
ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL); ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
if (ac97 == NULL) if (ac97 == NULL)
...@@ -73,7 +76,28 @@ struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec) ...@@ -73,7 +76,28 @@ struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec)
codec->component.card->snd_card->number, 0, codec->component.card->snd_card->number, 0,
codec->component.name); codec->component.name);
ret = device_register(&ac97->dev); device_initialize(&ac97->dev);
return ac97;
}
EXPORT_SYMBOL(snd_soc_alloc_ac97_codec);
/**
* snd_soc_new_ac97_codec - initailise AC97 device
* @codec: audio codec
*
* Initialises AC97 codec resources for use by ad-hoc devices only.
*/
struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec)
{
struct snd_ac97 *ac97;
int ret;
ac97 = snd_soc_alloc_ac97_codec(codec);
if (IS_ERR(ac97))
return ac97;
ret = device_add(&ac97->dev);
if (ret) { if (ret) {
put_device(&ac97->dev); put_device(&ac97->dev);
return ERR_PTR(ret); return ERR_PTR(ret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment