ASoC: Dynamically allocate the rtd device for a non-empty release()
The device model needs a release() function so it can free devices when they become dereferenced. Do that for rtds. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
parent
e4e9e05409
commit
36ae1a96c4
|
@ -847,7 +847,7 @@ struct snd_soc_card {
|
||||||
|
|
||||||
/* SoC machine DAI configuration, glues a codec and cpu DAI together */
|
/* SoC machine DAI configuration, glues a codec and cpu DAI together */
|
||||||
struct snd_soc_pcm_runtime {
|
struct snd_soc_pcm_runtime {
|
||||||
struct device dev;
|
struct device *dev;
|
||||||
struct snd_soc_card *card;
|
struct snd_soc_card *card;
|
||||||
struct snd_soc_dai_link *dai_link;
|
struct snd_soc_dai_link *dai_link;
|
||||||
struct mutex pcm_mutex;
|
struct mutex pcm_mutex;
|
||||||
|
@ -933,12 +933,12 @@ static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platfo
|
||||||
static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd,
|
static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
dev_set_drvdata(&rtd->dev, data);
|
dev_set_drvdata(rtd->dev, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd)
|
static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd)
|
||||||
{
|
{
|
||||||
return dev_get_drvdata(&rtd->dev);
|
return dev_get_drvdata(rtd->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
|
static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
|
||||||
|
|
|
@ -169,8 +169,7 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf,
|
||||||
static ssize_t codec_reg_show(struct device *dev,
|
static ssize_t codec_reg_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct snd_soc_pcm_runtime *rtd =
|
struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
|
||||||
container_of(dev, struct snd_soc_pcm_runtime, dev);
|
|
||||||
|
|
||||||
return soc_codec_reg_show(rtd->codec, buf, PAGE_SIZE, 0);
|
return soc_codec_reg_show(rtd->codec, buf, PAGE_SIZE, 0);
|
||||||
}
|
}
|
||||||
|
@ -180,8 +179,7 @@ static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
|
||||||
static ssize_t pmdown_time_show(struct device *dev,
|
static ssize_t pmdown_time_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct snd_soc_pcm_runtime *rtd =
|
struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
|
||||||
container_of(dev, struct snd_soc_pcm_runtime, dev);
|
|
||||||
|
|
||||||
return sprintf(buf, "%ld\n", rtd->pmdown_time);
|
return sprintf(buf, "%ld\n", rtd->pmdown_time);
|
||||||
}
|
}
|
||||||
|
@ -190,8 +188,7 @@ static ssize_t pmdown_time_set(struct device *dev,
|
||||||
struct device_attribute *attr,
|
struct device_attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
struct snd_soc_pcm_runtime *rtd =
|
struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
|
||||||
container_of(dev, struct snd_soc_pcm_runtime, dev);
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &rtd->pmdown_time);
|
ret = strict_strtol(buf, 10, &rtd->pmdown_time);
|
||||||
|
@ -884,9 +881,9 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
|
||||||
|
|
||||||
/* unregister the rtd device */
|
/* unregister the rtd device */
|
||||||
if (rtd->dev_registered) {
|
if (rtd->dev_registered) {
|
||||||
device_remove_file(&rtd->dev, &dev_attr_pmdown_time);
|
device_remove_file(rtd->dev, &dev_attr_pmdown_time);
|
||||||
device_remove_file(&rtd->dev, &dev_attr_codec_reg);
|
device_remove_file(rtd->dev, &dev_attr_codec_reg);
|
||||||
device_unregister(&rtd->dev);
|
device_unregister(rtd->dev);
|
||||||
rtd->dev_registered = 0;
|
rtd->dev_registered = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1061,7 +1058,10 @@ err_probe:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtd_release(struct device *dev) {}
|
static void rtd_release(struct device *dev)
|
||||||
|
{
|
||||||
|
kfree(dev);
|
||||||
|
}
|
||||||
|
|
||||||
static int soc_post_component_init(struct snd_soc_card *card,
|
static int soc_post_component_init(struct snd_soc_card *card,
|
||||||
struct snd_soc_codec *codec,
|
struct snd_soc_codec *codec,
|
||||||
|
@ -1104,11 +1104,17 @@ static int soc_post_component_init(struct snd_soc_card *card,
|
||||||
|
|
||||||
/* register the rtd device */
|
/* register the rtd device */
|
||||||
rtd->codec = codec;
|
rtd->codec = codec;
|
||||||
rtd->dev.parent = card->dev;
|
|
||||||
rtd->dev.release = rtd_release;
|
rtd->dev = kzalloc(sizeof(struct device), GFP_KERNEL);
|
||||||
rtd->dev.init_name = name;
|
if (!rtd->dev)
|
||||||
|
return -ENOMEM;
|
||||||
|
device_initialize(rtd->dev);
|
||||||
|
rtd->dev->parent = card->dev;
|
||||||
|
rtd->dev->release = rtd_release;
|
||||||
|
rtd->dev->init_name = name;
|
||||||
|
dev_set_drvdata(rtd->dev, rtd);
|
||||||
mutex_init(&rtd->pcm_mutex);
|
mutex_init(&rtd->pcm_mutex);
|
||||||
ret = device_register(&rtd->dev);
|
ret = device_add(rtd->dev);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(card->dev,
|
dev_err(card->dev,
|
||||||
"asoc: failed to register runtime device: %d\n", ret);
|
"asoc: failed to register runtime device: %d\n", ret);
|
||||||
|
@ -1117,14 +1123,14 @@ static int soc_post_component_init(struct snd_soc_card *card,
|
||||||
rtd->dev_registered = 1;
|
rtd->dev_registered = 1;
|
||||||
|
|
||||||
/* add DAPM sysfs entries for this codec */
|
/* add DAPM sysfs entries for this codec */
|
||||||
ret = snd_soc_dapm_sys_add(&rtd->dev);
|
ret = snd_soc_dapm_sys_add(rtd->dev);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
dev_err(codec->dev,
|
dev_err(codec->dev,
|
||||||
"asoc: failed to add codec dapm sysfs entries: %d\n",
|
"asoc: failed to add codec dapm sysfs entries: %d\n",
|
||||||
ret);
|
ret);
|
||||||
|
|
||||||
/* add codec sysfs entries */
|
/* add codec sysfs entries */
|
||||||
ret = device_create_file(&rtd->dev, &dev_attr_codec_reg);
|
ret = device_create_file(rtd->dev, &dev_attr_codec_reg);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
dev_err(codec->dev,
|
dev_err(codec->dev,
|
||||||
"asoc: failed to add codec sysfs files: %d\n", ret);
|
"asoc: failed to add codec sysfs files: %d\n", ret);
|
||||||
|
@ -1213,7 +1219,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = device_create_file(&rtd->dev, &dev_attr_pmdown_time);
|
ret = device_create_file(rtd->dev, &dev_attr_pmdown_time);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n");
|
printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n");
|
||||||
|
|
||||||
|
@ -1311,8 +1317,8 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
|
||||||
|
|
||||||
/* unregister the rtd device */
|
/* unregister the rtd device */
|
||||||
if (rtd->dev_registered) {
|
if (rtd->dev_registered) {
|
||||||
device_remove_file(&rtd->dev, &dev_attr_codec_reg);
|
device_remove_file(rtd->dev, &dev_attr_codec_reg);
|
||||||
device_unregister(&rtd->dev);
|
device_del(rtd->dev);
|
||||||
rtd->dev_registered = 0;
|
rtd->dev_registered = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1738,8 +1738,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
|
||||||
static ssize_t dapm_widget_show(struct device *dev,
|
static ssize_t dapm_widget_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct snd_soc_pcm_runtime *rtd =
|
struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
|
||||||
container_of(dev, struct snd_soc_pcm_runtime, dev);
|
|
||||||
struct snd_soc_codec *codec =rtd->codec;
|
struct snd_soc_codec *codec =rtd->codec;
|
||||||
struct snd_soc_dapm_widget *w;
|
struct snd_soc_dapm_widget *w;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
Loading…
Reference in New Issue