From: Liam Girdwood <lrg@slimlogic.co.uk>
To: axel.lin@gmail.com
Cc: alsa-devel@alsa-project.org, Takashi Iwai <tiwai@suse.de>,
Mark Brown <broonie@opensource.wolfsonmicro.com>,
linux-kernel <linux-kernel@vger.kernel.org>,
Tejun Heo <tj@kernel.org>,
Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Subject: Re: [PATCH 7/12] wm8940: fix resource reclaim in wm8940_register error path
Date: Thu, 15 Jul 2010 09:54:37 +0100 [thread overview]
Message-ID: <1279184077.3072.21.camel@odin> (raw)
In-Reply-To: <AANLkTil_buBStfVy_L9iTgPrxosmSRFhNU1MbaXWJfMx@mail.gmail.com>
On Thu, 2010-07-15 at 15:42 +0800, Axel Lin wrote:
>
> I agree that it is good to release resources at the same level,
> where they have been acquired.
> But I prefer to follow the maintainer/author's coding style.
>
> For the changes in other drivers, I'd like to see Liam and Mark's comments.
> Or if the driver maintainers request it, I can fix it.
Fwiw, the soon to be merged ASoC multi-component branch simplifies the
codec probe() and remove() as follows (e.g. from I2C and SPI WM8750
codec) :-
static int wm8750_probe(struct snd_soc_codec *codec)
{
struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
int reg, ret;
codec->control_data = wm8750->control_data;
ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type);
if (ret < 0) {
printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret);
return ret;
}
ret = wm8750_reset(codec);
if (ret < 0) {
printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
return ret;
}
/* charge output caps */
wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
snd_soc_add_controls(codec, wm8750_snd_controls,
ARRAY_SIZE(wm8750_snd_controls));
wm8750_add_widgets(codec);
return ret;
}
static int wm8750_remove(struct snd_soc_codec *codec)
{
wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
#if defined(CONFIG_SPI_MASTER)
static int __devinit wm8750_spi_probe(struct spi_device *spi)
{
struct wm8750_priv *wm8750;
int ret;
wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
if (wm8750 == NULL)
return -ENOMEM;
wm8750->control_data = spi;
wm8750->control_type = SND_SOC_SPI;
spi_set_drvdata(spi, wm8750);
ret = snd_soc_register_codec(&spi->dev, spi->chip_select,
&soc_codec_dev_wm8750, &wm8750_dai, 1);
if (ret < 0)
kfree(wm8750);
return ret;
}
static int __devexit wm8750_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev, spi->chip_select);
kfree(spi_get_drvdata(spi));
return 0;
}
static struct spi_driver wm8750_spi_driver = {
.driver = {
.name = "wm8750 SPI Codec",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = wm8750_spi_probe,
.remove = __devexit_p(wm8750_spi_remove),
};
#endif /* CONFIG_SPI_MASTER */
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int wm8750_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8750_priv *wm8750;
int ret;
wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
if (wm8750 == NULL)
return -ENOMEM;
i2c_set_clientdata(i2c, wm8750);
wm8750->control_data = i2c;
wm8750->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev, i2c->addr,
&soc_codec_dev_wm8750, &wm8750_dai, 1);
if (ret < 0)
kfree(wm8750);
return ret;
}
static __devexit int wm8750_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev, client->addr);
kfree(i2c_get_clientdata(client));
return 0;
}
static const struct i2c_device_id wm8750_i2c_id[] = {
{ "wm8750", 0 },
{ "wm8987", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
static struct i2c_driver wm8750_i2c_driver = {
.driver = {
.name = "wm8750 I2C Codec",
.owner = THIS_MODULE,
},
.probe = wm8750_i2c_probe,
.remove = __devexit_p(wm8750_i2c_remove),
.id_table = wm8750_i2c_id,
};
#endif
static int __init wm8750_modinit(void)
{
int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8750_i2c_driver);
if (ret != 0) {
printk(KERN_ERR "Failed to register wm8750 I2C driver: %d\n",
ret);
}
#endif
#if defined(CONFIG_SPI_MASTER)
ret = spi_register_driver(&wm8750_spi_driver);
if (ret != 0) {
printk(KERN_ERR "Failed to register wm8750 SPI driver: %d\n",
ret);
}
#endif
return ret;
}
module_init(wm8750_modinit);
static void __exit wm8750_exit(void)
{
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&wm8750_i2c_driver);
#endif
#if defined(CONFIG_SPI_MASTER)
spi_unregister_driver(&wm8750_spi_driver);
#endif
}
module_exit(wm8750_exit);
So while this patch series is useful (from a minor bug fix pov), it will
be overwritten shortly in the ASoC multi-component merge. Probably
delaying the multi-component merge too (since the changes are in the
same place).
Can we hold off this series for a week or two. I have one more update
for multi-component and if we don't have multi-component upstreamed in
that time frame we can apply this series.
Thanks
Liam
--
Freelance Developer, SlimLogic Ltd
ASoC and Voltage Regulator Maintainer.
http://www.slimlogic.co.uk
WARNING: multiple messages have this Message-ID (diff)
From: Liam Girdwood <lrg@slimlogic.co.uk>
To: axel.lin@gmail.com
Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>,
linux-kernel <linux-kernel@vger.kernel.org>,
Mark Brown <broonie@opensource.wolfsonmicro.com>,
Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>,
Tejun Heo <tj@kernel.org>,
alsa-devel@alsa-project.org
Subject: Re: [PATCH 7/12] wm8940: fix resource reclaim in wm8940_register error path
Date: Thu, 15 Jul 2010 09:54:37 +0100 [thread overview]
Message-ID: <1279184077.3072.21.camel@odin> (raw)
In-Reply-To: <AANLkTil_buBStfVy_L9iTgPrxosmSRFhNU1MbaXWJfMx@mail.gmail.com>
On Thu, 2010-07-15 at 15:42 +0800, Axel Lin wrote:
>
> I agree that it is good to release resources at the same level,
> where they have been acquired.
> But I prefer to follow the maintainer/author's coding style.
>
> For the changes in other drivers, I'd like to see Liam and Mark's comments.
> Or if the driver maintainers request it, I can fix it.
Fwiw, the soon to be merged ASoC multi-component branch simplifies the
codec probe() and remove() as follows (e.g. from I2C and SPI WM8750
codec) :-
static int wm8750_probe(struct snd_soc_codec *codec)
{
struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
int reg, ret;
codec->control_data = wm8750->control_data;
ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type);
if (ret < 0) {
printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret);
return ret;
}
ret = wm8750_reset(codec);
if (ret < 0) {
printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
return ret;
}
/* charge output caps */
wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
snd_soc_add_controls(codec, wm8750_snd_controls,
ARRAY_SIZE(wm8750_snd_controls));
wm8750_add_widgets(codec);
return ret;
}
static int wm8750_remove(struct snd_soc_codec *codec)
{
wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
#if defined(CONFIG_SPI_MASTER)
static int __devinit wm8750_spi_probe(struct spi_device *spi)
{
struct wm8750_priv *wm8750;
int ret;
wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
if (wm8750 == NULL)
return -ENOMEM;
wm8750->control_data = spi;
wm8750->control_type = SND_SOC_SPI;
spi_set_drvdata(spi, wm8750);
ret = snd_soc_register_codec(&spi->dev, spi->chip_select,
&soc_codec_dev_wm8750, &wm8750_dai, 1);
if (ret < 0)
kfree(wm8750);
return ret;
}
static int __devexit wm8750_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev, spi->chip_select);
kfree(spi_get_drvdata(spi));
return 0;
}
static struct spi_driver wm8750_spi_driver = {
.driver = {
.name = "wm8750 SPI Codec",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = wm8750_spi_probe,
.remove = __devexit_p(wm8750_spi_remove),
};
#endif /* CONFIG_SPI_MASTER */
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int wm8750_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8750_priv *wm8750;
int ret;
wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
if (wm8750 == NULL)
return -ENOMEM;
i2c_set_clientdata(i2c, wm8750);
wm8750->control_data = i2c;
wm8750->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev, i2c->addr,
&soc_codec_dev_wm8750, &wm8750_dai, 1);
if (ret < 0)
kfree(wm8750);
return ret;
}
static __devexit int wm8750_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev, client->addr);
kfree(i2c_get_clientdata(client));
return 0;
}
static const struct i2c_device_id wm8750_i2c_id[] = {
{ "wm8750", 0 },
{ "wm8987", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
static struct i2c_driver wm8750_i2c_driver = {
.driver = {
.name = "wm8750 I2C Codec",
.owner = THIS_MODULE,
},
.probe = wm8750_i2c_probe,
.remove = __devexit_p(wm8750_i2c_remove),
.id_table = wm8750_i2c_id,
};
#endif
static int __init wm8750_modinit(void)
{
int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8750_i2c_driver);
if (ret != 0) {
printk(KERN_ERR "Failed to register wm8750 I2C driver: %d\n",
ret);
}
#endif
#if defined(CONFIG_SPI_MASTER)
ret = spi_register_driver(&wm8750_spi_driver);
if (ret != 0) {
printk(KERN_ERR "Failed to register wm8750 SPI driver: %d\n",
ret);
}
#endif
return ret;
}
module_init(wm8750_modinit);
static void __exit wm8750_exit(void)
{
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&wm8750_i2c_driver);
#endif
#if defined(CONFIG_SPI_MASTER)
spi_unregister_driver(&wm8750_spi_driver);
#endif
}
module_exit(wm8750_exit);
So while this patch series is useful (from a minor bug fix pov), it will
be overwritten shortly in the ASoC multi-component merge. Probably
delaying the multi-component merge too (since the changes are in the
same place).
Can we hold off this series for a week or two. I have one more update
for multi-component and if we don't have multi-component upstreamed in
that time frame we can apply this series.
Thanks
Liam
--
Freelance Developer, SlimLogic Ltd
ASoC and Voltage Regulator Maintainer.
http://www.slimlogic.co.uk
next prev parent reply other threads:[~2010-07-15 8:54 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-15 2:49 [PATCH 0/12] sound/alsa/soc/codec: fix memory leak and resource relaim in error path Axel Lin
2010-07-15 2:50 ` [PATCH 1/12] ad1836: fix a memory leak if another ad1836 is registered Axel Lin
2010-07-20 10:31 ` Barry Song
2010-07-20 10:31 ` Barry Song
2010-07-15 2:52 ` [PATCH 2/12] ak4642: fix a memory leak if failed to initialise AK4642 Axel Lin
2010-07-15 5:53 ` Kuninori Morimoto
2010-07-15 5:53 ` Kuninori Morimoto
2010-07-15 6:19 ` Axel Lin
2010-07-15 6:19 ` Axel Lin
2010-07-15 6:29 ` Kuninori Morimoto
2010-07-15 6:29 ` Kuninori Morimoto
2010-07-15 2:53 ` [PATCH 3/12] da7210: fix a memory leak if failed to initialise da7210 audio codec Axel Lin
2010-07-15 2:56 ` [PATCH 4/12] wm8523: fix resource reclaim in wm8523_register error path Axel Lin
2010-07-15 2:57 ` [PATCH 5/12] wm8711: fix a memory leak if another WM8711 is registered Axel Lin
2010-07-15 2:59 ` [PATCH 6/12] wm8904: fix resource reclaim in wm8904_register error path Axel Lin
2010-07-15 3:01 ` [PATCH 7/12] wm8940: fix resource reclaim in wm8940_register " Axel Lin
2010-07-15 7:04 ` Guennadi Liakhovetski
2010-07-15 7:04 ` Guennadi Liakhovetski
2010-07-15 7:42 ` Axel Lin
2010-07-15 7:42 ` Axel Lin
2010-07-15 7:59 ` Guennadi Liakhovetski
2010-07-15 7:59 ` Guennadi Liakhovetski
2010-07-15 8:54 ` Liam Girdwood [this message]
2010-07-15 8:54 ` Liam Girdwood
2010-07-15 7:48 ` [PATCH v2 7/12] wm8940: fix a memory leak if wm8940_register return error Axel Lin
2010-07-15 3:03 ` [PATCH 8/12] wm8955: fix resource reclaim in wm8955_register error path Axel Lin
2010-07-15 3:06 ` [PATCH 9/12] wm8961: fix resource reclaim in wm8961_register " Axel Lin
2010-07-15 3:07 ` [PATCH 10/12] wm8974: fix a memory leak if another WM8974 is registered Axel Lin
2010-07-15 3:08 ` [PATCH 11/12] wm8978: fix a memory leak if another WM8978 " Axel Lin
2010-07-15 8:37 ` [PATCH v2 " Axel Lin
2010-07-15 8:53 ` Guennadi Liakhovetski
2010-07-15 8:53 ` Guennadi Liakhovetski
2010-07-15 3:11 ` [PATCH 12/12] wm9081: fix resource reclaim in wm9081_register error path Axel Lin
2010-07-15 8:59 ` [PATCH 0/12] sound/alsa/soc/codec: fix memory leak and resource relaim in " Mark Brown
2010-07-15 8:59 ` Mark Brown
2010-07-19 1:41 ` Axel Lin
2010-07-19 1:41 ` Axel Lin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1279184077.3072.21.camel@odin \
--to=lrg@slimlogic.co.uk \
--cc=alsa-devel@alsa-project.org \
--cc=axel.lin@gmail.com \
--cc=broonie@opensource.wolfsonmicro.com \
--cc=g.liakhovetski@gmx.de \
--cc=linux-kernel@vger.kernel.org \
--cc=tiwai@suse.de \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.