Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6bbc7fed authored by Takashi Iwai's avatar Takashi Iwai
Browse files

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: default avatarTakashi Iwai <tiwai@suse.de>
parent 4227de2a
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -132,6 +132,7 @@ struct snd_card {
	struct completion *release_completion;
	struct completion *release_completion;
	struct device *dev;		/* device assigned to this card */
	struct device *dev;		/* device assigned to this card */
	struct device card_dev;		/* cardX object for sysfs */
	struct device card_dev;		/* cardX object for sysfs */
	const struct attribute_group *dev_groups[4]; /* assigned sysfs attr */
	bool registered;		/* card_dev is registered? */
	bool registered;		/* card_dev is registered? */


#ifdef CONFIG_PM
#ifdef CONFIG_PM
@@ -262,6 +263,8 @@ void snd_card_set_id(struct snd_card *card, const char *id);
int snd_card_register(struct snd_card *card);
int snd_card_register(struct snd_card *card);
int snd_card_info_init(void);
int snd_card_info_init(void);
int snd_card_info_done(void);
int snd_card_info_done(void);
int snd_card_add_dev_attr(struct snd_card *card,
			  const struct attribute_group *group);
int snd_component_add(struct snd_card *card, const char *component);
int snd_component_add(struct snd_card *card, const char *component);
int snd_card_file_add(struct snd_card *card, struct file *file);
int snd_card_file_add(struct snd_card *card, struct file *file);
int snd_card_file_remove(struct snd_card *card, struct file *file);
int snd_card_file_remove(struct snd_card *card, struct file *file);
+25 −6
Original line number Original line Diff line number Diff line
@@ -181,7 +181,7 @@ void snd_device_initialize(struct device *dev, struct snd_card *card)
EXPORT_SYMBOL_GPL(snd_device_initialize);
EXPORT_SYMBOL_GPL(snd_device_initialize);


static int snd_card_do_free(struct snd_card *card);
static int snd_card_do_free(struct snd_card *card);
static const struct attribute_group *card_dev_attr_groups[];
static const struct attribute_group card_dev_attr_group;


static void release_card_device(struct device *dev)
static void release_card_device(struct device *dev)
{
{
@@ -269,7 +269,8 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
	card->card_dev.parent = parent;
	card->card_dev.parent = parent;
	card->card_dev.class = sound_class;
	card->card_dev.class = sound_class;
	card->card_dev.release = release_card_device;
	card->card_dev.release = release_card_device;
	card->card_dev.groups = card_dev_attr_groups;
	card->card_dev.groups = card->dev_groups;
	card->dev_groups[0] = &card_dev_attr_group;
	err = kobject_set_name(&card->card_dev.kobj, "card%d", idx);
	err = kobject_set_name(&card->card_dev.kobj, "card%d", idx);
	if (err < 0)
	if (err < 0)
		goto __error;
		goto __error;
@@ -700,14 +701,32 @@ static struct attribute *card_dev_attrs[] = {
	NULL
	NULL
};
};


static struct attribute_group card_dev_attr_group = {
static const struct attribute_group card_dev_attr_group = {
	.attrs	= card_dev_attrs,
	.attrs	= card_dev_attrs,
};
};


static const struct attribute_group *card_dev_attr_groups[] = {
/**
	&card_dev_attr_group,
 * snd_card_add_dev_attr - Append a new sysfs attribute group to card
	NULL
 * @card: card instance
 * @group: attribute group to append
 */
int snd_card_add_dev_attr(struct snd_card *card,
			  const struct attribute_group *group)
{
	int i;

	/* loop for (arraysize-1) here to keep NULL at the last entry */
	for (i = 0; i < ARRAY_SIZE(card->dev_groups) - 1; i++) {
		if (!card->dev_groups[i]) {
			card->dev_groups[i] = group;
			return 0;
		}
	}

	dev_err(card->dev, "Too many groups assigned\n");
	return -ENOSPC;
};
};
EXPORT_SYMBOL_GPL(snd_card_add_dev_attr);


/**
/**
 *  snd_card_register - register the soundcard
 *  snd_card_register - register the soundcard