Commit caa751ba authored by Takashi Iwai's avatar Takashi Iwai

ALSA: Create sysfs attribute files via groups

Instead of calling each time device_create_file(), create the groups
of sysfs attribute files at once in a normal way.  Add a new helper
function, snd_get_device(), to return the associated device object,
so that we can handle the sysfs addition locally.

Since the sysfs file addition is done differently now,
snd_add_device_sysfs_file() helper function is removed.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent d01a838c
...@@ -248,8 +248,7 @@ static inline int snd_register_device(int type, struct snd_card *card, int dev, ...@@ -248,8 +248,7 @@ static inline int snd_register_device(int type, struct snd_card *card, int dev,
int snd_unregister_device(int type, struct snd_card *card, int dev); int snd_unregister_device(int type, struct snd_card *card, int dev);
void *snd_lookup_minor_data(unsigned int minor, int type); void *snd_lookup_minor_data(unsigned int minor, int type);
int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev, struct device *snd_get_device(int type, struct snd_card *card, int dev);
struct device_attribute *attr);
#ifdef CONFIG_SND_OSSEMUL #ifdef CONFIG_SND_OSSEMUL
int snd_register_oss_device(int type, struct snd_card *card, int dev, int snd_register_oss_device(int type, struct snd_card *card, int dev,
......
...@@ -68,6 +68,7 @@ struct snd_hwdep { ...@@ -68,6 +68,7 @@ struct snd_hwdep {
wait_queue_head_t open_wait; wait_queue_head_t open_wait;
void *private_data; void *private_data;
void (*private_free) (struct snd_hwdep *hwdep); void (*private_free) (struct snd_hwdep *hwdep);
const struct attribute_group **groups;
struct mutex open_mutex; struct mutex open_mutex;
int used; /* reference counter */ int used; /* reference counter */
......
...@@ -436,6 +436,20 @@ static int snd_hwdep_dev_register(struct snd_device *device) ...@@ -436,6 +436,20 @@ static int snd_hwdep_dev_register(struct snd_device *device)
mutex_unlock(&register_mutex); mutex_unlock(&register_mutex);
return err; return err;
} }
if (hwdep->groups) {
struct device *d = snd_get_device(SNDRV_DEVICE_TYPE_HWDEP,
hwdep->card, hwdep->device);
if (d) {
err = sysfs_create_groups(&d->kobj, hwdep->groups);
if (err < 0)
dev_warn(card->dev,
"hwdep %d:%d: cannot create sysfs groups\n",
card->number, hwdep->device);
put_device(d);
}
}
#ifdef CONFIG_SND_OSSEMUL #ifdef CONFIG_SND_OSSEMUL
hwdep->ossreg = 0; hwdep->ossreg = 0;
if (hwdep->oss_type >= 0) { if (hwdep->oss_type >= 0) {
......
...@@ -1018,8 +1018,20 @@ static ssize_t show_pcm_class(struct device *dev, ...@@ -1018,8 +1018,20 @@ static ssize_t show_pcm_class(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%s\n", str); return snprintf(buf, PAGE_SIZE, "%s\n", str);
} }
static struct device_attribute pcm_attrs = static DEVICE_ATTR(pcm_class, S_IRUGO, show_pcm_class, NULL);
__ATTR(pcm_class, S_IRUGO, show_pcm_class, NULL); static struct attribute *pcm_dev_attrs[] = {
&dev_attr_pcm_class.attr,
NULL
};
static struct attribute_group pcm_dev_attr_group = {
.attrs = pcm_dev_attrs,
};
static const struct attribute_group *pcm_dev_attr_groups[] = {
&pcm_dev_attr_group,
NULL
};
static int snd_pcm_dev_register(struct snd_device *device) static int snd_pcm_dev_register(struct snd_device *device)
{ {
...@@ -1069,8 +1081,18 @@ static int snd_pcm_dev_register(struct snd_device *device) ...@@ -1069,8 +1081,18 @@ static int snd_pcm_dev_register(struct snd_device *device)
mutex_unlock(&register_mutex); mutex_unlock(&register_mutex);
return err; return err;
} }
snd_add_device_sysfs_file(devtype, pcm->card, pcm->device,
&pcm_attrs); dev = snd_get_device(devtype, pcm->card, pcm->device);
if (dev) {
err = sysfs_create_groups(&dev->kobj,
pcm_dev_attr_groups);
if (err < 0)
dev_warn(dev,
"pcm %d:%d: cannot create sysfs groups\n",
pcm->card->number, pcm->device);
put_device(dev);
}
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
snd_pcm_timer_init(substream); snd_pcm_timer_init(substream);
} }
......
...@@ -355,22 +355,25 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) ...@@ -355,22 +355,25 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
EXPORT_SYMBOL(snd_unregister_device); EXPORT_SYMBOL(snd_unregister_device);
int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev, /* get the assigned device to the given type and device number;
struct device_attribute *attr) * the caller needs to release it via put_device() after using it
*/
struct device *snd_get_device(int type, struct snd_card *card, int dev)
{ {
int minor, ret = -EINVAL; int minor;
struct device *d; struct device *d = NULL;
mutex_lock(&sound_mutex); mutex_lock(&sound_mutex);
minor = find_snd_minor(type, card, dev); minor = find_snd_minor(type, card, dev);
if (minor >= 0 && (d = snd_minors[minor]->dev) != NULL) if (minor >= 0) {
ret = device_create_file(d, attr); d = snd_minors[minor]->dev;
if (d)
get_device(d);
}
mutex_unlock(&sound_mutex); mutex_unlock(&sound_mutex);
return ret; return d;
} }
EXPORT_SYMBOL(snd_get_device);
EXPORT_SYMBOL(snd_add_device_sysfs_file);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
/* /*
......
...@@ -852,21 +852,6 @@ static int snd_hda_bus_dev_free(struct snd_device *device) ...@@ -852,21 +852,6 @@ static int snd_hda_bus_dev_free(struct snd_device *device)
return snd_hda_bus_free(bus); return snd_hda_bus_free(bus);
} }
#ifdef CONFIG_SND_HDA_HWDEP
static int snd_hda_bus_dev_register(struct snd_device *device)
{
struct hda_bus *bus = device->device_data;
struct hda_codec *codec;
list_for_each_entry(codec, &bus->codec_list, list) {
snd_hda_hwdep_add_sysfs(codec);
snd_hda_hwdep_add_power_sysfs(codec);
}
return 0;
}
#else
#define snd_hda_bus_dev_register NULL
#endif
/** /**
* snd_hda_bus_new - create a HDA bus * snd_hda_bus_new - create a HDA bus
* @card: the card entry * @card: the card entry
...@@ -882,7 +867,6 @@ int snd_hda_bus_new(struct snd_card *card, ...@@ -882,7 +867,6 @@ int snd_hda_bus_new(struct snd_card *card,
struct hda_bus *bus; struct hda_bus *bus;
int err; int err;
static struct snd_device_ops dev_ops = { static struct snd_device_ops dev_ops = {
.dev_register = snd_hda_bus_dev_register,
.dev_free = snd_hda_bus_dev_free, .dev_free = snd_hda_bus_dev_free,
}; };
......
...@@ -124,6 +124,8 @@ static void hwdep_free(struct snd_hwdep *hwdep) ...@@ -124,6 +124,8 @@ static void hwdep_free(struct snd_hwdep *hwdep)
clear_hwdep_elements(hwdep->private_data); clear_hwdep_elements(hwdep->private_data);
} }
static const struct attribute_group *snd_hda_dev_attr_groups[];
int snd_hda_create_hwdep(struct hda_codec *codec) int snd_hda_create_hwdep(struct hda_codec *codec)
{ {
char hwname[16]; char hwname[16];
...@@ -140,6 +142,7 @@ int snd_hda_create_hwdep(struct hda_codec *codec) ...@@ -140,6 +142,7 @@ int snd_hda_create_hwdep(struct hda_codec *codec)
hwdep->private_data = codec; hwdep->private_data = codec;
hwdep->private_free = hwdep_free; hwdep->private_free = hwdep_free;
hwdep->exclusive = 1; hwdep->exclusive = 1;
hwdep->groups = snd_hda_dev_attr_groups;
hwdep->ops.open = hda_hwdep_open; hwdep->ops.open = hda_hwdep_open;
hwdep->ops.ioctl = hda_hwdep_ioctl; hwdep->ops.ioctl = hda_hwdep_ioctl;
...@@ -176,21 +179,8 @@ static ssize_t power_off_acct_show(struct device *dev, ...@@ -176,21 +179,8 @@ static ssize_t power_off_acct_show(struct device *dev,
return sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_off_acct)); return sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_off_acct));
} }
static struct device_attribute power_attrs[] = { static DEVICE_ATTR_RO(power_on_acct);
__ATTR_RO(power_on_acct), static DEVICE_ATTR_RO(power_off_acct);
__ATTR_RO(power_off_acct),
};
int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec)
{
struct snd_hwdep *hwdep = codec->hwdep;
int i;
for (i = 0; i < ARRAY_SIZE(power_attrs); i++)
snd_add_device_sysfs_file(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card,
hwdep->device, &power_attrs[i]);
return 0;
}
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
#ifdef CONFIG_SND_HDA_RECONFIG #ifdef CONFIG_SND_HDA_RECONFIG
...@@ -568,44 +558,21 @@ static ssize_t user_pin_configs_store(struct device *dev, ...@@ -568,44 +558,21 @@ static ssize_t user_pin_configs_store(struct device *dev,
return count; return count;
} }
#define CODEC_ATTR_RW(type) \ static DEVICE_ATTR_RW(vendor_id);
__ATTR(type, 0644, type##_show, type##_store) static DEVICE_ATTR_RW(subsystem_id);
#define CODEC_ATTR_RO(type) \ static DEVICE_ATTR_RW(revision_id);
__ATTR_RO(type) static DEVICE_ATTR_RO(afg);
#define CODEC_ATTR_WO(type) \ static DEVICE_ATTR_RO(mfg);
__ATTR(type, 0200, NULL, type##_store) static DEVICE_ATTR_RW(vendor_name);
static DEVICE_ATTR_RW(chip_name);
static struct device_attribute codec_attrs[] = { static DEVICE_ATTR_RW(modelname);
CODEC_ATTR_RW(vendor_id), static DEVICE_ATTR_RW(init_verbs);
CODEC_ATTR_RW(subsystem_id), static DEVICE_ATTR_RW(hints);
CODEC_ATTR_RW(revision_id), static DEVICE_ATTR_RO(init_pin_configs);
CODEC_ATTR_RO(afg), static DEVICE_ATTR_RW(user_pin_configs);
CODEC_ATTR_RO(mfg), static DEVICE_ATTR_RO(driver_pin_configs);
CODEC_ATTR_RW(vendor_name), static DEVICE_ATTR_WO(reconfig);
CODEC_ATTR_RW(chip_name), static DEVICE_ATTR_WO(clear);
CODEC_ATTR_RW(modelname),
CODEC_ATTR_RW(init_verbs),
CODEC_ATTR_RW(hints),
CODEC_ATTR_RO(init_pin_configs),
CODEC_ATTR_RW(user_pin_configs),
CODEC_ATTR_RO(driver_pin_configs),
CODEC_ATTR_WO(reconfig),
CODEC_ATTR_WO(clear),
};
/*
* create sysfs files on hwdep directory
*/
int snd_hda_hwdep_add_sysfs(struct hda_codec *codec)
{
struct snd_hwdep *hwdep = codec->hwdep;
int i;
for (i = 0; i < ARRAY_SIZE(codec_attrs); i++)
snd_add_device_sysfs_file(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card,
hwdep->device, &codec_attrs[i]);
return 0;
}
/* /*
* Look for hint string * Look for hint string
...@@ -884,3 +851,40 @@ int snd_hda_load_patch(struct hda_bus *bus, size_t fw_size, const void *fw_buf) ...@@ -884,3 +851,40 @@ int snd_hda_load_patch(struct hda_bus *bus, size_t fw_size, const void *fw_buf)
} }
EXPORT_SYMBOL_GPL(snd_hda_load_patch); EXPORT_SYMBOL_GPL(snd_hda_load_patch);
#endif /* CONFIG_SND_HDA_PATCH_LOADER */ #endif /* CONFIG_SND_HDA_PATCH_LOADER */
/*
* sysfs entries
*/
static struct attribute *hda_dev_attrs[] = {
#ifdef CONFIG_PM
&dev_attr_power_on_acct.attr,
&dev_attr_power_off_acct.attr,
#endif
#ifdef CONFIG_SND_HDA_RECONFIG
&dev_attr_vendor_id.attr,
&dev_attr_subsystem_id.attr,
&dev_attr_revision_id.attr,
&dev_attr_afg.attr,
&dev_attr_mfg.attr,
&dev_attr_vendor_name.attr,
&dev_attr_chip_name.attr,
&dev_attr_modelname.attr,
&dev_attr_init_verbs.attr,
&dev_attr_hints.attr,
&dev_attr_init_pin_configs.attr,
&dev_attr_user_pin_configs.attr,
&dev_attr_driver_pin_configs.attr,
&dev_attr_reconfig.attr,
&dev_attr_clear.attr,
#endif
NULL
};
static struct attribute_group hda_dev_attr_group = {
.attrs = hda_dev_attrs,
};
static const struct attribute_group *snd_hda_dev_attr_groups[] = {
&hda_dev_attr_group,
NULL
};
...@@ -597,24 +597,6 @@ int snd_hda_create_hwdep(struct hda_codec *codec); ...@@ -597,24 +597,6 @@ int snd_hda_create_hwdep(struct hda_codec *codec);
static inline int snd_hda_create_hwdep(struct hda_codec *codec) { return 0; } static inline int snd_hda_create_hwdep(struct hda_codec *codec) { return 0; }
#endif #endif
#if defined(CONFIG_PM) && defined(CONFIG_SND_HDA_HWDEP)
int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec);
#else
static inline int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec)
{
return 0;
}
#endif
#ifdef CONFIG_SND_HDA_RECONFIG
int snd_hda_hwdep_add_sysfs(struct hda_codec *codec);
#else
static inline int snd_hda_hwdep_add_sysfs(struct hda_codec *codec)
{
return 0;
}
#endif
#ifdef CONFIG_SND_HDA_RECONFIG #ifdef CONFIG_SND_HDA_RECONFIG
const char *snd_hda_get_hint(struct hda_codec *codec, const char *key); const char *snd_hda_get_hint(struct hda_codec *codec, const char *key);
int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key); int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key);
......
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