Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Takashi Iwai <tiwai@suse.de>

+112 -103
+1 -2
include/sound/core.h
··· 248 248 249 249 int snd_unregister_device(int type, struct snd_card *card, int dev); 250 250 void *snd_lookup_minor_data(unsigned int minor, int type); 251 - int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev, 252 - struct device_attribute *attr); 251 + struct device *snd_get_device(int type, struct snd_card *card, int dev); 253 252 254 253 #ifdef CONFIG_SND_OSSEMUL 255 254 int snd_register_oss_device(int type, struct snd_card *card, int dev,
+1
include/sound/hwdep.h
··· 68 68 wait_queue_head_t open_wait; 69 69 void *private_data; 70 70 void (*private_free) (struct snd_hwdep *hwdep); 71 + const struct attribute_group **groups; 71 72 72 73 struct mutex open_mutex; 73 74 int used; /* reference counter */
+14
sound/core/hwdep.c
··· 436 436 mutex_unlock(&register_mutex); 437 437 return err; 438 438 } 439 + 440 + if (hwdep->groups) { 441 + struct device *d = snd_get_device(SNDRV_DEVICE_TYPE_HWDEP, 442 + hwdep->card, hwdep->device); 443 + if (d) { 444 + err = sysfs_create_groups(&d->kobj, hwdep->groups); 445 + if (err < 0) 446 + dev_warn(card->dev, 447 + "hwdep %d:%d: cannot create sysfs groups\n", 448 + card->number, hwdep->device); 449 + put_device(d); 450 + } 451 + } 452 + 439 453 #ifdef CONFIG_SND_OSSEMUL 440 454 hwdep->ossreg = 0; 441 455 if (hwdep->oss_type >= 0) {
+26 -4
sound/core/pcm.c
··· 1018 1018 return snprintf(buf, PAGE_SIZE, "%s\n", str); 1019 1019 } 1020 1020 1021 - static struct device_attribute pcm_attrs = 1022 - __ATTR(pcm_class, S_IRUGO, show_pcm_class, NULL); 1021 + static DEVICE_ATTR(pcm_class, S_IRUGO, show_pcm_class, NULL); 1022 + static struct attribute *pcm_dev_attrs[] = { 1023 + &dev_attr_pcm_class.attr, 1024 + NULL 1025 + }; 1026 + 1027 + static struct attribute_group pcm_dev_attr_group = { 1028 + .attrs = pcm_dev_attrs, 1029 + }; 1030 + 1031 + static const struct attribute_group *pcm_dev_attr_groups[] = { 1032 + &pcm_dev_attr_group, 1033 + NULL 1034 + }; 1023 1035 1024 1036 static int snd_pcm_dev_register(struct snd_device *device) 1025 1037 { ··· 1081 1069 mutex_unlock(&register_mutex); 1082 1070 return err; 1083 1071 } 1084 - snd_add_device_sysfs_file(devtype, pcm->card, pcm->device, 1085 - &pcm_attrs); 1072 + 1073 + dev = snd_get_device(devtype, pcm->card, pcm->device); 1074 + if (dev) { 1075 + err = sysfs_create_groups(&dev->kobj, 1076 + pcm_dev_attr_groups); 1077 + if (err < 0) 1078 + dev_warn(dev, 1079 + "pcm %d:%d: cannot create sysfs groups\n", 1080 + pcm->card->number, pcm->device); 1081 + put_device(dev); 1082 + } 1083 + 1086 1084 for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) 1087 1085 snd_pcm_timer_init(substream); 1088 1086 }
+13 -10
sound/core/sound.c
··· 355 355 356 356 EXPORT_SYMBOL(snd_unregister_device); 357 357 358 - int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev, 359 - struct device_attribute *attr) 358 + /* get the assigned device to the given type and device number; 359 + * the caller needs to release it via put_device() after using it 360 + */ 361 + struct device *snd_get_device(int type, struct snd_card *card, int dev) 360 362 { 361 - int minor, ret = -EINVAL; 362 - struct device *d; 363 + int minor; 364 + struct device *d = NULL; 363 365 364 366 mutex_lock(&sound_mutex); 365 367 minor = find_snd_minor(type, card, dev); 366 - if (minor >= 0 && (d = snd_minors[minor]->dev) != NULL) 367 - ret = device_create_file(d, attr); 368 + if (minor >= 0) { 369 + d = snd_minors[minor]->dev; 370 + if (d) 371 + get_device(d); 372 + } 368 373 mutex_unlock(&sound_mutex); 369 - return ret; 370 - 374 + return d; 371 375 } 372 - 373 - EXPORT_SYMBOL(snd_add_device_sysfs_file); 376 + EXPORT_SYMBOL(snd_get_device); 374 377 375 378 #ifdef CONFIG_PROC_FS 376 379 /*
-16
sound/pci/hda/hda_codec.c
··· 852 852 return snd_hda_bus_free(bus); 853 853 } 854 854 855 - #ifdef CONFIG_SND_HDA_HWDEP 856 - static int snd_hda_bus_dev_register(struct snd_device *device) 857 - { 858 - struct hda_bus *bus = device->device_data; 859 - struct hda_codec *codec; 860 - list_for_each_entry(codec, &bus->codec_list, list) { 861 - snd_hda_hwdep_add_sysfs(codec); 862 - snd_hda_hwdep_add_power_sysfs(codec); 863 - } 864 - return 0; 865 - } 866 - #else 867 - #define snd_hda_bus_dev_register NULL 868 - #endif 869 - 870 855 /** 871 856 * snd_hda_bus_new - create a HDA bus 872 857 * @card: the card entry ··· 867 882 struct hda_bus *bus; 868 883 int err; 869 884 static struct snd_device_ops dev_ops = { 870 - .dev_register = snd_hda_bus_dev_register, 871 885 .dev_free = snd_hda_bus_dev_free, 872 886 }; 873 887
+57 -53
sound/pci/hda/hda_hwdep.c
··· 124 124 clear_hwdep_elements(hwdep->private_data); 125 125 } 126 126 127 + static const struct attribute_group *snd_hda_dev_attr_groups[]; 128 + 127 129 int snd_hda_create_hwdep(struct hda_codec *codec) 128 130 { 129 131 char hwname[16]; ··· 142 140 hwdep->private_data = codec; 143 141 hwdep->private_free = hwdep_free; 144 142 hwdep->exclusive = 1; 143 + hwdep->groups = snd_hda_dev_attr_groups; 145 144 146 145 hwdep->ops.open = hda_hwdep_open; 147 146 hwdep->ops.ioctl = hda_hwdep_ioctl; ··· 179 176 return sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_off_acct)); 180 177 } 181 178 182 - static struct device_attribute power_attrs[] = { 183 - __ATTR_RO(power_on_acct), 184 - __ATTR_RO(power_off_acct), 185 - }; 186 - 187 - int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec) 188 - { 189 - struct snd_hwdep *hwdep = codec->hwdep; 190 - int i; 191 - 192 - for (i = 0; i < ARRAY_SIZE(power_attrs); i++) 193 - snd_add_device_sysfs_file(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, 194 - hwdep->device, &power_attrs[i]); 195 - return 0; 196 - } 179 + static DEVICE_ATTR_RO(power_on_acct); 180 + static DEVICE_ATTR_RO(power_off_acct); 197 181 #endif /* CONFIG_PM */ 198 182 199 183 #ifdef CONFIG_SND_HDA_RECONFIG ··· 558 568 return count; 559 569 } 560 570 561 - #define CODEC_ATTR_RW(type) \ 562 - __ATTR(type, 0644, type##_show, type##_store) 563 - #define CODEC_ATTR_RO(type) \ 564 - __ATTR_RO(type) 565 - #define CODEC_ATTR_WO(type) \ 566 - __ATTR(type, 0200, NULL, type##_store) 567 - 568 - static struct device_attribute codec_attrs[] = { 569 - CODEC_ATTR_RW(vendor_id), 570 - CODEC_ATTR_RW(subsystem_id), 571 - CODEC_ATTR_RW(revision_id), 572 - CODEC_ATTR_RO(afg), 573 - CODEC_ATTR_RO(mfg), 574 - CODEC_ATTR_RW(vendor_name), 575 - CODEC_ATTR_RW(chip_name), 576 - CODEC_ATTR_RW(modelname), 577 - CODEC_ATTR_RW(init_verbs), 578 - CODEC_ATTR_RW(hints), 579 - CODEC_ATTR_RO(init_pin_configs), 580 - CODEC_ATTR_RW(user_pin_configs), 581 - CODEC_ATTR_RO(driver_pin_configs), 582 - CODEC_ATTR_WO(reconfig), 583 - CODEC_ATTR_WO(clear), 584 - }; 585 - 586 - /* 587 - * create sysfs files on hwdep directory 588 - */ 589 - int snd_hda_hwdep_add_sysfs(struct hda_codec *codec) 590 - { 591 - struct snd_hwdep *hwdep = codec->hwdep; 592 - int i; 593 - 594 - for (i = 0; i < ARRAY_SIZE(codec_attrs); i++) 595 - snd_add_device_sysfs_file(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, 596 - hwdep->device, &codec_attrs[i]); 597 - return 0; 598 - } 571 + static DEVICE_ATTR_RW(vendor_id); 572 + static DEVICE_ATTR_RW(subsystem_id); 573 + static DEVICE_ATTR_RW(revision_id); 574 + static DEVICE_ATTR_RO(afg); 575 + static DEVICE_ATTR_RO(mfg); 576 + static DEVICE_ATTR_RW(vendor_name); 577 + static DEVICE_ATTR_RW(chip_name); 578 + static DEVICE_ATTR_RW(modelname); 579 + static DEVICE_ATTR_RW(init_verbs); 580 + static DEVICE_ATTR_RW(hints); 581 + static DEVICE_ATTR_RO(init_pin_configs); 582 + static DEVICE_ATTR_RW(user_pin_configs); 583 + static DEVICE_ATTR_RO(driver_pin_configs); 584 + static DEVICE_ATTR_WO(reconfig); 585 + static DEVICE_ATTR_WO(clear); 599 586 600 587 /* 601 588 * Look for hint string ··· 851 884 } 852 885 EXPORT_SYMBOL_GPL(snd_hda_load_patch); 853 886 #endif /* CONFIG_SND_HDA_PATCH_LOADER */ 887 + 888 + /* 889 + * sysfs entries 890 + */ 891 + static struct attribute *hda_dev_attrs[] = { 892 + #ifdef CONFIG_PM 893 + &dev_attr_power_on_acct.attr, 894 + &dev_attr_power_off_acct.attr, 895 + #endif 896 + #ifdef CONFIG_SND_HDA_RECONFIG 897 + &dev_attr_vendor_id.attr, 898 + &dev_attr_subsystem_id.attr, 899 + &dev_attr_revision_id.attr, 900 + &dev_attr_afg.attr, 901 + &dev_attr_mfg.attr, 902 + &dev_attr_vendor_name.attr, 903 + &dev_attr_chip_name.attr, 904 + &dev_attr_modelname.attr, 905 + &dev_attr_init_verbs.attr, 906 + &dev_attr_hints.attr, 907 + &dev_attr_init_pin_configs.attr, 908 + &dev_attr_user_pin_configs.attr, 909 + &dev_attr_driver_pin_configs.attr, 910 + &dev_attr_reconfig.attr, 911 + &dev_attr_clear.attr, 912 + #endif 913 + NULL 914 + }; 915 + 916 + static struct attribute_group hda_dev_attr_group = { 917 + .attrs = hda_dev_attrs, 918 + }; 919 + 920 + static const struct attribute_group *snd_hda_dev_attr_groups[] = { 921 + &hda_dev_attr_group, 922 + NULL 923 + };
-18
sound/pci/hda/hda_local.h
··· 597 597 static inline int snd_hda_create_hwdep(struct hda_codec *codec) { return 0; } 598 598 #endif 599 599 600 - #if defined(CONFIG_PM) && defined(CONFIG_SND_HDA_HWDEP) 601 - int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec); 602 - #else 603 - static inline int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec) 604 - { 605 - return 0; 606 - } 607 - #endif 608 - 609 - #ifdef CONFIG_SND_HDA_RECONFIG 610 - int snd_hda_hwdep_add_sysfs(struct hda_codec *codec); 611 - #else 612 - static inline int snd_hda_hwdep_add_sysfs(struct hda_codec *codec) 613 - { 614 - return 0; 615 - } 616 - #endif 617 - 618 600 #ifdef CONFIG_SND_HDA_RECONFIG 619 601 const char *snd_hda_get_hint(struct hda_codec *codec, const char *key); 620 602 int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key);