Lines Matching +full:parent +full:- +full:locked
1 // SPDX-License-Identifier: GPL-2.0-or-later
37 /* locked for registering/using */
47 /* return non-zero if the given index is reserved for the given
56 if (!module || !*module->name || !slots[idx]) in module_slot_match()
59 s1 = module->name; in module_slot_match()
71 if (c1 == '-') in module_slot_match()
73 if (c2 == '-') in module_slot_match()
95 * @mask == -1 == 0xffffffff means: take any free slot up to 32
123 * snd_device_initialize - Initialize struct device for sound devices
131 dev->parent = &card->card_dev; in snd_device_initialize()
132 dev->class = sound_class; in snd_device_initialize()
133 dev->release = default_release; in snd_device_initialize()
137 static int snd_card_init(struct snd_card *card, struct device *parent,
149 * snd_card_new - create and initialize a soundcard structure
150 * @parent: the parent device object
151 * @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
163 int snd_card_new(struct device *parent, int idx, const char *xid, in snd_card_new() argument
171 return -EINVAL; in snd_card_new()
178 return -ENOMEM; in snd_card_new()
180 err = snd_card_init(card, parent, idx, xid, module, extra_size); in snd_card_new()
197 * snd_devm_card_new - managed snd_card object creation
198 * @parent: the parent device object
199 * @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
213 int snd_devm_card_new(struct device *parent, int idx, const char *xid, in snd_devm_card_new() argument
224 return -ENOMEM; in snd_devm_card_new()
225 card->managed = true; in snd_devm_card_new()
226 err = snd_card_init(card, parent, idx, xid, module, extra_size); in snd_devm_card_new()
232 devres_add(parent, card); in snd_devm_card_new()
238 static int snd_card_init(struct snd_card *card, struct device *parent, in snd_card_init() argument
248 card->private_data = (char *)card + sizeof(struct snd_card); in snd_card_init()
250 strscpy(card->id, xid, sizeof(card->id)); in snd_card_init()
253 if (idx < 0) /* first check the matching module-name slot */ in snd_card_init()
258 err = -ENODEV; in snd_card_init()
261 err = -EBUSY; /* invalid */ in snd_card_init()
263 err = -ENODEV; in snd_card_init()
266 dev_err(parent, "cannot find the slot for index %d (range 0-%i), error: %d\n", in snd_card_init()
267 idx, snd_ecards_limit - 1, err); in snd_card_init()
274 card->dev = parent; in snd_card_init()
275 card->number = idx; in snd_card_init()
278 card->module = module; in snd_card_init()
280 INIT_LIST_HEAD(&card->devices); in snd_card_init()
281 init_rwsem(&card->controls_rwsem); in snd_card_init()
282 rwlock_init(&card->ctl_files_rwlock); in snd_card_init()
283 INIT_LIST_HEAD(&card->controls); in snd_card_init()
284 INIT_LIST_HEAD(&card->ctl_files); in snd_card_init()
285 spin_lock_init(&card->files_lock); in snd_card_init()
286 INIT_LIST_HEAD(&card->files_list); in snd_card_init()
287 mutex_init(&card->memory_mutex); in snd_card_init()
289 init_waitqueue_head(&card->power_sleep); in snd_card_init()
290 init_waitqueue_head(&card->power_ref_sleep); in snd_card_init()
291 atomic_set(&card->power_ref, 0); in snd_card_init()
293 init_waitqueue_head(&card->remove_sleep); in snd_card_init()
294 card->sync_irq = -1; in snd_card_init()
296 device_initialize(&card->card_dev); in snd_card_init()
297 card->card_dev.parent = parent; in snd_card_init()
298 card->card_dev.class = sound_class; in snd_card_init()
299 card->card_dev.release = release_card_device; in snd_card_init()
300 card->card_dev.groups = card->dev_groups; in snd_card_init()
301 card->dev_groups[0] = &card_dev_attr_group; in snd_card_init()
302 err = kobject_set_name(&card->card_dev.kobj, "card%d", idx); in snd_card_init()
306 snprintf(card->irq_descr, sizeof(card->irq_descr), "%s:%s", in snd_card_init()
307 dev_driver_string(card->dev), dev_name(&card->card_dev)); in snd_card_init()
313 dev_err(parent, "unable to register control minors\n"); in snd_card_init()
318 dev_err(parent, "unable to create card info\n"); in snd_card_init()
324 card->debugfs_root = debugfs_create_dir(name, sound_debugfs_root); in snd_card_init()
331 put_device(&card->card_dev); in snd_card_init()
336 * snd_card_ref - Get the card object from the index
349 get_device(&card->card_dev); in snd_card_ref()
355 /* return non-zero if a card is already locked */
358 int locked; in snd_card_locked() local
361 locked = test_bit(card, snd_cards_lock); in snd_card_locked()
363 return locked; in snd_card_locked()
368 return -ENODEV; in snd_disconnect_llseek()
374 return -ENODEV; in snd_disconnect_read()
380 return -ENODEV; in snd_disconnect_write()
389 if (_df->file == file) { in snd_disconnect_release()
391 list_del_init(&df->shutdown_list); in snd_disconnect_release()
398 if ((file->f_flags & FASYNC) && df->disconnected_f_op->fasync) in snd_disconnect_release()
399 df->disconnected_f_op->fasync(-1, file, 0); in snd_disconnect_release()
400 return df->disconnected_f_op->release(inode, file); in snd_disconnect_release()
414 return -ENODEV; in snd_disconnect_ioctl()
419 return -ENODEV; in snd_disconnect_mmap()
424 return -ENODEV; in snd_disconnect_fasync()
444 * snd_card_disconnect - disconnect all APIs from the file-operations (user space)
447 * Disconnects all APIs from the file-operations (user space).
451 * Note: The current implementation replaces all active file->f_op with special
459 return -EINVAL; in snd_card_disconnect()
461 spin_lock(&card->files_lock); in snd_card_disconnect()
462 if (card->shutdown) { in snd_card_disconnect()
463 spin_unlock(&card->files_lock); in snd_card_disconnect()
466 card->shutdown = 1; in snd_card_disconnect()
468 /* replace file->f_op with special dummy operations */ in snd_card_disconnect()
469 list_for_each_entry(mfile, &card->files_list, list) { in snd_card_disconnect()
472 mfile->disconnected_f_op = mfile->file->f_op; in snd_card_disconnect()
475 list_add(&mfile->shutdown_list, &shutdown_files); in snd_card_disconnect()
478 mfile->file->f_op = &snd_shutdown_f_ops; in snd_card_disconnect()
479 fops_get(mfile->file->f_op); in snd_card_disconnect()
481 spin_unlock(&card->files_lock); in snd_card_disconnect()
494 if (card->sync_irq > 0) in snd_card_disconnect()
495 synchronize_irq(card->sync_irq); in snd_card_disconnect()
498 if (card->registered) { in snd_card_disconnect()
499 device_del(&card->card_dev); in snd_card_disconnect()
500 card->registered = false; in snd_card_disconnect()
505 snd_cards[card->number] = NULL; in snd_card_disconnect()
506 clear_bit(card->number, snd_cards_lock); in snd_card_disconnect()
510 wake_up(&card->power_sleep); in snd_card_disconnect()
518 * snd_card_disconnect_sync - disconnect card and wait until files get closed
523 * It assures that all accesses from user-space finished so that the driver
532 dev_err(card->dev, in snd_card_disconnect_sync()
538 spin_lock_irq(&card->files_lock); in snd_card_disconnect_sync()
539 wait_event_lock_irq(card->remove_sleep, in snd_card_disconnect_sync()
540 list_empty(&card->files_list), in snd_card_disconnect_sync()
541 card->files_lock); in snd_card_disconnect_sync()
542 spin_unlock_irq(&card->files_lock); in snd_card_disconnect_sync()
548 card->releasing = true; in snd_card_do_free()
554 if (card->private_free) in snd_card_do_free()
555 card->private_free(card); in snd_card_do_free()
557 dev_warn(card->dev, "unable to free card info\n"); in snd_card_do_free()
561 debugfs_remove(card->debugfs_root); in snd_card_do_free()
562 card->debugfs_root = NULL; in snd_card_do_free()
564 if (card->release_completion) in snd_card_do_free()
565 complete(card->release_completion); in snd_card_do_free()
566 if (!card->managed) in snd_card_do_free()
572 * snd_card_free_when_closed - Disconnect the card, free it later eventually
585 put_device(&card->card_dev); in snd_card_free_when_closed()
591 * snd_card_free - frees given soundcard structure
610 * we need to avoid double-free. Moreover, the release via devres in snd_card_free()
614 if (card->releasing) in snd_card_free()
617 card->release_completion = &released; in snd_card_free()
649 !strcmp(snd_cards[i]->id, id)) in card_id_ok()
655 /* copy to card->id only with valid letters from nid */
659 char *id = card->id; in copy_valid_id_string()
665 while (*nid && (size_t)(id - card->id) < sizeof(card->id) - 1) { in copy_valid_id_string()
673 /* Set card->id from the given string
684 id = card->id; in snd_card_set_id_no_lock()
707 if (len + sfxlen >= sizeof(card->id)) in snd_card_set_id_no_lock()
708 spos = id + sizeof(card->id) - sfxlen - 1; in snd_card_set_id_no_lock()
719 dev_err(card->dev, "unable to set card id (%s)\n", id); in snd_card_set_id_no_lock()
720 if (card->proc_root->name) in snd_card_set_id_no_lock()
721 strscpy(card->id, card->proc_root->name, sizeof(card->id)); in snd_card_set_id_no_lock()
725 * snd_card_set_id - set card identification name
734 /* check if user specified own card->id */ in snd_card_set_id()
735 if (card->id[0] != '\0') in snd_card_set_id()
747 return scnprintf(buf, PAGE_SIZE, "%s\n", card->id); in id_show()
754 char buf1[sizeof(card->id)]; in id_store()
755 size_t copy = count > sizeof(card->id) - 1 ? in id_store()
756 sizeof(card->id) - 1 : count; in id_store()
762 if (!isalnum(c) && c != '_' && c != '-') in id_store()
763 return -EINVAL; in id_store()
770 return -EEXIST; in id_store()
772 strcpy(card->id, buf1); in id_store()
785 return scnprintf(buf, PAGE_SIZE, "%i\n", card->number); in number_show()
801 * snd_card_add_dev_attr - Append a new sysfs attribute group to card
810 /* loop for (arraysize-1) here to keep NULL at the last entry */ in snd_card_add_dev_attr()
811 for (i = 0; i < ARRAY_SIZE(card->dev_groups) - 1; i++) { in snd_card_add_dev_attr()
812 if (!card->dev_groups[i]) { in snd_card_add_dev_attr()
813 card->dev_groups[i] = group; in snd_card_add_dev_attr()
818 dev_err(card->dev, "Too many groups assigned\n"); in snd_card_add_dev_attr()
819 return -ENOSPC; in snd_card_add_dev_attr()
829 * snd_card_register - register the soundcard
844 return -EINVAL; in snd_card_register()
846 if (!card->registered) { in snd_card_register()
847 err = device_add(&card->card_dev); in snd_card_register()
850 card->registered = true; in snd_card_register()
852 if (card->managed) in snd_card_register()
853 devm_remove_action(card->dev, trigger_card_free, card); in snd_card_register()
856 if (card->managed) { in snd_card_register()
857 err = devm_add_action(card->dev, trigger_card_free, card); in snd_card_register()
866 if (snd_cards[card->number]) { in snd_card_register()
871 if (*card->id) { in snd_card_register()
873 char tmpid[sizeof(card->id)]; in snd_card_register()
874 memcpy(tmpid, card->id, sizeof(card->id)); in snd_card_register()
879 src = *card->shortname ? card->shortname : card->longname; in snd_card_register()
883 snd_cards[card->number] = card; in snd_card_register()
909 snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n", in snd_card_info_read()
911 card->id, in snd_card_info_read()
912 card->driver, in snd_card_info_read()
913 card->shortname); in snd_card_info_read()
915 card->longname); in snd_card_info_read()
920 snd_iprintf(buffer, "--- no soundcards ---\n"); in snd_card_info_read()
934 snd_iprintf(buffer, "%s\n", card->longname); in snd_card_info_read_oss()
939 snd_iprintf(buffer, "--- no soundcards ---\n"); in snd_card_info_read_oss()
957 idx, card->module->name); in snd_card_module_info_read()
969 return -ENOMEM; in snd_card_info_init()
970 entry->c.text.read = snd_card_info_read; in snd_card_info_init()
972 return -ENOMEM; /* freed in error path */ in snd_card_info_init()
977 return -ENOMEM; in snd_card_info_init()
978 entry->c.text.read = snd_card_module_info_read; in snd_card_info_init()
980 return -ENOMEM; /* freed in error path */ in snd_card_info_init()
988 * snd_component_add - add a component string
993 * The component can be referred from the alsa-lib.
1003 ptr = strstr(card->components, component); in snd_component_add()
1008 if (strlen(card->components) + 1 + len + 1 > sizeof(card->components)) { in snd_component_add()
1010 return -ENOMEM; in snd_component_add()
1012 if (card->components[0] != '\0') in snd_component_add()
1013 strcat(card->components, " "); in snd_component_add()
1014 strcat(card->components, component); in snd_component_add()
1020 * snd_card_file_add - add the file to the file list of the card
1024 * This function adds the file to the file linked-list of the card.
1025 * This linked-list is used to keep tracking the connection state,
1036 return -ENOMEM; in snd_card_file_add()
1037 mfile->file = file; in snd_card_file_add()
1038 mfile->disconnected_f_op = NULL; in snd_card_file_add()
1039 INIT_LIST_HEAD(&mfile->shutdown_list); in snd_card_file_add()
1040 spin_lock(&card->files_lock); in snd_card_file_add()
1041 if (card->shutdown) { in snd_card_file_add()
1042 spin_unlock(&card->files_lock); in snd_card_file_add()
1044 return -ENODEV; in snd_card_file_add()
1046 list_add(&mfile->list, &card->files_list); in snd_card_file_add()
1047 get_device(&card->card_dev); in snd_card_file_add()
1048 spin_unlock(&card->files_lock); in snd_card_file_add()
1054 * snd_card_file_remove - remove the file from the file list
1070 spin_lock(&card->files_lock); in snd_card_file_remove()
1071 list_for_each_entry(mfile, &card->files_list, list) { in snd_card_file_remove()
1072 if (mfile->file == file) { in snd_card_file_remove()
1073 list_del(&mfile->list); in snd_card_file_remove()
1075 list_del(&mfile->shutdown_list); in snd_card_file_remove()
1077 if (mfile->disconnected_f_op) in snd_card_file_remove()
1078 fops_put(mfile->disconnected_f_op); in snd_card_file_remove()
1083 if (list_empty(&card->files_list)) in snd_card_file_remove()
1084 wake_up_all(&card->remove_sleep); in snd_card_file_remove()
1085 spin_unlock(&card->files_lock); in snd_card_file_remove()
1087 dev_err(card->dev, "card file remove problem (%p)\n", file); in snd_card_file_remove()
1088 return -ENOENT; in snd_card_file_remove()
1091 put_device(&card->card_dev); in snd_card_file_remove()
1098 * snd_power_ref_and_wait - wait until the card gets powered up
1103 * The refcount is down again while sleeping until power-up, hence this
1122 add_wait_queue(&card->power_sleep, &wait); in snd_power_ref_and_wait()
1124 if (card->shutdown) { in snd_power_ref_and_wait()
1125 result = -ENODEV; in snd_power_ref_and_wait()
1135 remove_wait_queue(&card->power_sleep, &wait); in snd_power_ref_and_wait()
1141 * snd_power_wait - wait until the card gets powered up (old form)