aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-01-30 06:27:43 -0500
committerTakashi Iwai <tiwai@suse.de>2015-02-06 03:56:33 -0500
commit6bbc7fed849597ec35ffdcaf677910dd11d71d08 (patch)
tree570560b9981f146249c09fbcd8bde9cca8f3fc64
parent4227de2a7e5f0ff6a58e919a9c4f2bb06e882f48 (diff)
ALSA: Add a helper to add a new attribute group to card
For assigning sysfs entries for a card device from the driver, introduce a new helper function, snd_card_add_dev_attr(). In this way, we can avoid the possible race between the device registration and the sysfs addition / removal. The driver can pass a new attribute group to add freely. This has to be called before snd_card_register(). Currently, up to two extra groups can be added. More than that, it'll return an error. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--include/sound/core.h3
-rw-r--r--sound/core/init.c31
2 files changed, 28 insertions, 6 deletions
diff --git a/include/sound/core.h b/include/sound/core.h
index 58882bfacdd7..da5748289968 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -132,6 +132,7 @@ struct snd_card {
132 struct completion *release_completion; 132 struct completion *release_completion;
133 struct device *dev; /* device assigned to this card */ 133 struct device *dev; /* device assigned to this card */
134 struct device card_dev; /* cardX object for sysfs */ 134 struct device card_dev; /* cardX object for sysfs */
135 const struct attribute_group *dev_groups[4]; /* assigned sysfs attr */
135 bool registered; /* card_dev is registered? */ 136 bool registered; /* card_dev is registered? */
136 137
137#ifdef CONFIG_PM 138#ifdef CONFIG_PM
@@ -262,6 +263,8 @@ void snd_card_set_id(struct snd_card *card, const char *id);
262int snd_card_register(struct snd_card *card); 263int snd_card_register(struct snd_card *card);
263int snd_card_info_init(void); 264int snd_card_info_init(void);
264int snd_card_info_done(void); 265int snd_card_info_done(void);
266int snd_card_add_dev_attr(struct snd_card *card,
267 const struct attribute_group *group);
265int snd_component_add(struct snd_card *card, const char *component); 268int snd_component_add(struct snd_card *card, const char *component);
266int snd_card_file_add(struct snd_card *card, struct file *file); 269int snd_card_file_add(struct snd_card *card, struct file *file);
267int snd_card_file_remove(struct snd_card *card, struct file *file); 270int snd_card_file_remove(struct snd_card *card, struct file *file);
diff --git a/sound/core/init.c b/sound/core/init.c
index 96194599e82e..35419054821c 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -181,7 +181,7 @@ void snd_device_initialize(struct device *dev, struct snd_card *card)
181EXPORT_SYMBOL_GPL(snd_device_initialize); 181EXPORT_SYMBOL_GPL(snd_device_initialize);
182 182
183static int snd_card_do_free(struct snd_card *card); 183static int snd_card_do_free(struct snd_card *card);
184static const struct attribute_group *card_dev_attr_groups[]; 184static const struct attribute_group card_dev_attr_group;
185 185
186static void release_card_device(struct device *dev) 186static void release_card_device(struct device *dev)
187{ 187{
@@ -269,7 +269,8 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
269 card->card_dev.parent = parent; 269 card->card_dev.parent = parent;
270 card->card_dev.class = sound_class; 270 card->card_dev.class = sound_class;
271 card->card_dev.release = release_card_device; 271 card->card_dev.release = release_card_device;
272 card->card_dev.groups = card_dev_attr_groups; 272 card->card_dev.groups = card->dev_groups;
273 card->dev_groups[0] = &card_dev_attr_group;
273 err = kobject_set_name(&card->card_dev.kobj, "card%d", idx); 274 err = kobject_set_name(&card->card_dev.kobj, "card%d", idx);
274 if (err < 0) 275 if (err < 0)
275 goto __error; 276 goto __error;
@@ -700,14 +701,32 @@ static struct attribute *card_dev_attrs[] = {
700 NULL 701 NULL
701}; 702};
702 703
703static struct attribute_group card_dev_attr_group = { 704static const struct attribute_group card_dev_attr_group = {
704 .attrs = card_dev_attrs, 705 .attrs = card_dev_attrs,
705}; 706};
706 707
707static const struct attribute_group *card_dev_attr_groups[] = { 708/**
708 &card_dev_attr_group, 709 * snd_card_add_dev_attr - Append a new sysfs attribute group to card
709 NULL 710 * @card: card instance
711 * @group: attribute group to append
712 */
713int snd_card_add_dev_attr(struct snd_card *card,
714 const struct attribute_group *group)
715{
716 int i;
717
718 /* loop for (arraysize-1) here to keep NULL at the last entry */
719 for (i = 0; i < ARRAY_SIZE(card->dev_groups) - 1; i++) {
720 if (!card->dev_groups[i]) {
721 card->dev_groups[i] = group;
722 return 0;
723 }
724 }
725
726 dev_err(card->dev, "Too many groups assigned\n");
727 return -ENOSPC;
710}; 728};
729EXPORT_SYMBOL_GPL(snd_card_add_dev_attr);
711 730
712/** 731/**
713 * snd_card_register - register the soundcard 732 * snd_card_register - register the soundcard