Lines Matching +full:- +full:grp
1 // SPDX-License-Identifier: GPL-2.0
3 * drivers/base/devres.c - device resource management
31 * the alignment of a 64-bit integer.
42 /* -- 8 pointers */
48 node->name = name; in set_node_dbginfo()
49 node->size = size; in set_node_dbginfo()
61 op, node, node->name, node->size); in devres_dbg()
70 trace_devres_log(dev, op, node, node->name, node->size); in devres_log()
90 if (node->release == &group_open_release) in node_to_group()
92 if (node->release == &group_close_release) in node_to_group()
99 /* We must catch any near-SIZE_MAX cases that could overflow. */ in check_dr_size()
127 INIT_LIST_HEAD(&dr->node.entry); in alloc_dr()
128 dr->node.release = release; in alloc_dr()
135 BUG_ON(!list_empty(&node->entry)); in add_dr()
136 list_add_tail(&node->entry, &dev->devres_head); in add_dr()
143 BUG_ON(!list_empty(&new->entry)); in replace_dr()
144 list_replace(&old->entry, &new->entry); in replace_dr()
148 * __devres_alloc_node - Allocate device resource data
170 set_node_dbginfo(&dr->node, name, size); in __devres_alloc_node()
171 return dr->data; in __devres_alloc_node()
176 * devres_for_each_res - Resource iterator
202 spin_lock_irqsave(&dev->devres_lock, flags); in devres_for_each_res()
204 &dev->devres_head, entry) { in devres_for_each_res()
207 if (node->release != release) in devres_for_each_res()
209 if (match && !match(dev, dr->data, match_data)) in devres_for_each_res()
211 fn(dev, dr->data, data); in devres_for_each_res()
213 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_for_each_res()
218 * devres_free - Free device resource data
228 BUG_ON(!list_empty(&dr->node.entry)); in devres_free()
235 * devres_add - Register device resource
248 spin_lock_irqsave(&dev->devres_lock, flags); in devres_add()
249 add_dr(dev, &dr->node); in devres_add()
250 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_add()
259 list_for_each_entry_reverse(node, &dev->devres_head, entry) { in find_dr()
262 if (node->release != release) in find_dr()
264 if (match && !match(dev, dr->data, match_data)) in find_dr()
273 * devres_find - Find device resource
292 spin_lock_irqsave(&dev->devres_lock, flags); in devres_find()
294 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_find()
297 return dr->data; in devres_find()
303 * devres_get - Find devres, if non-existent, add one atomically
323 spin_lock_irqsave(&dev->devres_lock, flags); in devres_get()
324 dr = find_dr(dev, new_dr->node.release, match, match_data); in devres_get()
326 add_dr(dev, &new_dr->node); in devres_get()
330 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_get()
333 return dr->data; in devres_get()
338 * devres_remove - Find a device resource and remove it
358 spin_lock_irqsave(&dev->devres_lock, flags); in devres_remove()
361 list_del_init(&dr->node.entry); in devres_remove()
362 devres_log(dev, &dr->node, "REM"); in devres_remove()
364 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_remove()
367 return dr->data; in devres_remove()
373 * devres_destroy - Find a device resource and destroy it
384 * only the devres-allocated data will be freed. The caller becomes
388 * 0 if devres is found and freed, -ENOENT if not found.
397 return -ENOENT; in devres_destroy()
406 * devres_release - Find a device resource and destroy it, calling release
418 * 0 if devres is found and freed, -ENOENT if not found.
427 return -ENOENT; in devres_release()
442 /* First pass - move normal devres entries to @todo and clear in remove_nodes()
447 struct devres_group *grp; in remove_nodes() local
449 grp = node_to_group(node); in remove_nodes()
450 if (grp) { in remove_nodes()
452 grp->color = 0; in remove_nodes()
456 if (&node->entry == first) in remove_nodes()
457 first = first->next; in remove_nodes()
458 list_move_tail(&node->entry, todo); in remove_nodes()
466 /* Second pass - Scan groups and color them. A group gets in remove_nodes()
474 struct devres_group *grp; in remove_nodes() local
476 grp = node_to_group(node); in remove_nodes()
477 BUG_ON(!grp || list_empty(&grp->node[0].entry)); in remove_nodes()
479 grp->color++; in remove_nodes()
480 if (list_empty(&grp->node[1].entry)) in remove_nodes()
481 grp->color++; in remove_nodes()
483 BUG_ON(grp->color <= 0 || grp->color > 2); in remove_nodes()
484 if (grp->color == 2) { in remove_nodes()
488 list_move_tail(&grp->node[0].entry, todo); in remove_nodes()
489 list_del_init(&grp->node[1].entry); in remove_nodes()
504 devres_log(dev, &dr->node, "REL"); in release_nodes()
505 dr->node.release(dev, dr->data); in release_nodes()
511 * devres_release_all - Release all managed resources
524 if (WARN_ON(dev->devres_head.next == NULL)) in devres_release_all()
525 return -ENODEV; in devres_release_all()
528 if (list_empty(&dev->devres_head)) in devres_release_all()
531 spin_lock_irqsave(&dev->devres_lock, flags); in devres_release_all()
532 cnt = remove_nodes(dev, dev->devres_head.next, &dev->devres_head, &todo); in devres_release_all()
533 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_release_all()
540 * devres_open_group - Open a new devres group
547 * recommended. If @id is NULL, address-wise unique ID is created.
554 struct devres_group *grp; in devres_open_group() local
557 grp = kmalloc(sizeof(*grp), gfp); in devres_open_group()
558 if (unlikely(!grp)) in devres_open_group()
561 grp->node[0].release = &group_open_release; in devres_open_group()
562 grp->node[1].release = &group_close_release; in devres_open_group()
563 INIT_LIST_HEAD(&grp->node[0].entry); in devres_open_group()
564 INIT_LIST_HEAD(&grp->node[1].entry); in devres_open_group()
565 set_node_dbginfo(&grp->node[0], "grp<", 0); in devres_open_group()
566 set_node_dbginfo(&grp->node[1], "grp>", 0); in devres_open_group()
567 grp->id = grp; in devres_open_group()
569 grp->id = id; in devres_open_group()
570 grp->color = 0; in devres_open_group()
572 spin_lock_irqsave(&dev->devres_lock, flags); in devres_open_group()
573 add_dr(dev, &grp->node[0]); in devres_open_group()
574 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_open_group()
575 return grp->id; in devres_open_group()
587 list_for_each_entry_reverse(node, &dev->devres_head, entry) { in find_group()
588 struct devres_group *grp; in find_group() local
590 if (node->release != &group_open_release) in find_group()
593 grp = container_of(node, struct devres_group, node[0]); in find_group()
596 if (grp->id == id) in find_group()
597 return grp; in find_group()
598 } else if (list_empty(&grp->node[1].entry)) in find_group()
599 return grp; in find_group()
606 * devres_close_group - Close a devres group
615 struct devres_group *grp; in devres_close_group() local
618 spin_lock_irqsave(&dev->devres_lock, flags); in devres_close_group()
620 grp = find_group(dev, id); in devres_close_group()
621 if (grp) in devres_close_group()
622 add_dr(dev, &grp->node[1]); in devres_close_group()
626 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_close_group()
631 * devres_remove_group - Remove a devres group
641 struct devres_group *grp; in devres_remove_group() local
644 spin_lock_irqsave(&dev->devres_lock, flags); in devres_remove_group()
646 grp = find_group(dev, id); in devres_remove_group()
647 if (grp) { in devres_remove_group()
648 list_del_init(&grp->node[0].entry); in devres_remove_group()
649 list_del_init(&grp->node[1].entry); in devres_remove_group()
650 devres_log(dev, &grp->node[0], "REM"); in devres_remove_group()
654 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_remove_group()
656 kfree(grp); in devres_remove_group()
661 * devres_release_group - Release resources in a devres group
670 * The number of released non-group resources.
674 struct devres_group *grp; in devres_release_group() local
679 spin_lock_irqsave(&dev->devres_lock, flags); in devres_release_group()
681 grp = find_group(dev, id); in devres_release_group()
682 if (grp) { in devres_release_group()
683 struct list_head *first = &grp->node[0].entry; in devres_release_group()
684 struct list_head *end = &dev->devres_head; in devres_release_group()
686 if (!list_empty(&grp->node[1].entry)) in devres_release_group()
687 end = grp->node[1].entry.next; in devres_release_group()
690 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_release_group()
693 } else if (list_empty(&dev->devres_head)) { in devres_release_group()
697 * being released - don't touch and don't warn. in devres_release_group()
699 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_release_group()
702 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_release_group()
724 return devres->action == target->action && in devm_action_match()
725 devres->data == target->data; in devm_action_match()
732 devres->action(devres->data); in devm_action_release()
736 * __devm_add_action() - add a custom action to list of managed resources
752 return -ENOMEM; in __devm_add_action()
754 devres->data = data; in __devm_add_action()
755 devres->action = action; in __devm_add_action()
774 * devm_remove_action_nowarn() - removes previously added custom action
791 * Returns: 0 on success, -ENOENT if no entry could have been found.
808 * devm_release_action() - release previously added custom action
844 * devm_kmalloc - Resource-managed kmalloc
872 set_node_dbginfo(&dr->node, "devm_kzalloc_release", size); in devm_kmalloc()
873 devres_add(dev, dr->data); in devm_kmalloc()
874 return dr->data; in devm_kmalloc()
879 * devm_krealloc - Resource-managed krealloc()
880 * @dev: Device to re-allocate memory for
881 * @ptr: Pointer to the memory chunk to re-allocate
889 * change the order in which the release callback for the re-alloc'ed devres
926 * allocated previously - just return the same pointer. in devm_krealloc()
947 spin_lock_irqsave(&dev->devres_lock, flags); in devm_krealloc()
951 spin_unlock_irqrestore(&dev->devres_lock, flags); in devm_krealloc()
957 replace_dr(dev, &old_dr->node, &new_dr->node); in devm_krealloc()
959 spin_unlock_irqrestore(&dev->devres_lock, flags); in devm_krealloc()
965 memcpy(new_dr->data, old_dr->data, in devm_krealloc()
966 total_old_size - offsetof(struct devres, data)); in devm_krealloc()
968 * Same for releasing the old devres - it's now been removed from the in devm_krealloc()
969 * list. This is also the reason why we must not use devm_kfree() - the in devm_krealloc()
974 return new_dr->data; in devm_krealloc()
979 * devm_kstrdup - Allocate resource managed space and
998 * devm_kstrdup_const - resource managed conditional string duplication
1020 * devm_kvasprintf - Allocate resource managed space and format a string
1025 * @fmt: The printf()-style format string
1052 * devm_kasprintf - Allocate resource managed space and format a string
1057 * @fmt: The printf()-style format string
1076 * devm_kfree - Resource-managed kfree
1100 * devm_kmemdup - Resource-managed kmemdup
1130 return devres->addr == target->addr; in devm_pages_match()
1137 free_pages(devres->addr, devres->order); in devm_pages_release()
1141 * devm_get_free_pages - Resource-managed __get_free_pages
1171 devres->addr = addr; in devm_get_free_pages()
1172 devres->order = order; in devm_get_free_pages()
1180 * devm_free_pages - Resource-managed free_pages
1208 return *(void **)devr->data == p; in devm_percpu_match()
1212 * __devm_alloc_percpu - Resource-managed alloc_percpu
1213 * @dev: Device to allocate per-cpu memory for
1214 * @size: Size of per-cpu memory to allocate
1215 * @align: Alignment of per-cpu memory to allocate
1217 * Managed alloc_percpu. Per-cpu memory allocated with this function is
1248 * devm_free_percpu - Resource-managed free_percpu
1250 * @pdata: Per-cpu memory to free