Lines Matching +full:resource +full:- +full:id
1 // SPDX-License-Identifier: GPL-2.0
3 * drivers/base/devres.c - device resource management
31 * the alignment of a 64-bit integer.
40 void *id; member
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
153 * @name: Name of the resource
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
177 * @dev: Device to iterate resource from
181 * @fn: Function to be called for each matched resource.
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
236 * @dev: Device to add resource to
237 * @res: Resource to register
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
274 * @dev: Device to lookup resource from
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
339 * @dev: Device to find resource from
346 * match all. If found, the resource is removed atomically and
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
374 * @dev: Device to find resource from
381 * match all. If found, the resource is removed atomically and freed.
383 * Note that the release function for the resource will not be called,
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
407 * @dev: Device to find resource from
414 * match all. If found, the resource is removed atomically, the
415 * release function called and the resource freed.
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()
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()
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
542 * @id: Separator ID
545 * Open a new devres group for @dev with @id. For @id, using a
547 * recommended. If @id is NULL, address-wise unique ID is created.
550 * ID of the new group, NULL on failure.
552 void *devres_open_group(struct device *dev, void *id, gfp_t gfp) in devres_open_group() argument
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()
568 if (id) 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()
579 /* Find devres group with ID @id. If @id is NULL, look for the latest. */
580 static struct devres_group *find_group(struct device *dev, void *id) in find_group() argument
584 list_for_each_entry_reverse(node, &dev->devres_head, entry) { in find_group()
587 if (node->release != &group_open_release) in find_group()
592 if (id) { in find_group()
593 if (grp->id == id) in find_group()
595 } else if (list_empty(&grp->node[1].entry)) in find_group()
603 * devres_close_group - Close a devres group
605 * @id: ID of target group, can be NULL
607 * Close the group identified by @id. If @id is NULL, the latest open
610 void devres_close_group(struct device *dev, void *id) in devres_close_group() argument
615 spin_lock_irqsave(&dev->devres_lock, flags); in devres_close_group()
617 grp = find_group(dev, id); in devres_close_group()
619 add_dr(dev, &grp->node[1]); in devres_close_group()
623 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_close_group()
628 * devres_remove_group - Remove a devres group
630 * @id: ID of target group, can be NULL
632 * Remove the group identified by @id. If @id is NULL, the latest
636 void devres_remove_group(struct device *dev, void *id) in devres_remove_group() argument
641 spin_lock_irqsave(&dev->devres_lock, flags); in devres_remove_group()
643 grp = find_group(dev, id); in devres_remove_group()
645 list_del_init(&grp->node[0].entry); in devres_remove_group()
646 list_del_init(&grp->node[1].entry); in devres_remove_group()
647 devres_log(dev, &grp->node[0], "REM"); in devres_remove_group()
651 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_remove_group()
658 * devres_release_group - Release resources in a devres group
660 * @id: ID of target group, can be NULL
662 * Release all resources in the group identified by @id. If @id is
667 * The number of released non-group resources.
669 int devres_release_group(struct device *dev, void *id) in devres_release_group() argument
676 spin_lock_irqsave(&dev->devres_lock, flags); in devres_release_group()
678 grp = find_group(dev, id); in devres_release_group()
680 struct list_head *first = &grp->node[0].entry; in devres_release_group()
681 struct list_head *end = &dev->devres_head; in devres_release_group()
683 if (!list_empty(&grp->node[1].entry)) in devres_release_group()
684 end = grp->node[1].entry.next; in devres_release_group()
687 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_release_group()
692 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_release_group()
714 return devres->action == target->action && in devm_action_match()
715 devres->data == target->data; in devm_action_match()
722 devres->action(devres->data); in devm_action_release()
726 * __devm_add_action() - add a custom action to list of managed resources
730 * @name: Name of the resource (for debugging purposes)
733 * it gets executed as part of standard resource unwinding.
742 return -ENOMEM; in __devm_add_action()
744 devres->data = data; in __devm_add_action()
745 devres->action = action; in __devm_add_action()
753 * devm_remove_action() - removes previously added custom action
774 * devm_release_action() - release previously added custom action
810 * devm_kmalloc - Resource-managed kmalloc
838 set_node_dbginfo(&dr->node, "devm_kzalloc_release", size); in devm_kmalloc()
839 devres_add(dev, dr->data); in devm_kmalloc()
840 return dr->data; in devm_kmalloc()
845 * devm_krealloc - Resource-managed krealloc()
846 * @dev: Device to re-allocate memory for
847 * @ptr: Pointer to the memory chunk to re-allocate
855 * change the order in which the release callback for the re-alloc'ed devres
892 * allocated previously - just return the same pointer. in devm_krealloc()
911 * modifications but not the resource itself. in devm_krealloc()
913 spin_lock_irqsave(&dev->devres_lock, flags); in devm_krealloc()
917 spin_unlock_irqrestore(&dev->devres_lock, flags); in devm_krealloc()
923 replace_dr(dev, &old_dr->node, &new_dr->node); in devm_krealloc()
925 spin_unlock_irqrestore(&dev->devres_lock, flags); in devm_krealloc()
931 memcpy(new_dr->data, old_dr->data, in devm_krealloc()
932 total_old_size - offsetof(struct devres, data)); in devm_krealloc()
934 * Same for releasing the old devres - it's now been removed from the in devm_krealloc()
935 * list. This is also the reason why we must not use devm_kfree() - the in devm_krealloc()
940 return new_dr->data; in devm_krealloc()
945 * devm_kstrdup - Allocate resource managed space and
971 * devm_kstrdup_const - resource managed conditional string duplication
993 * devm_kvasprintf - Allocate resource managed space and format a string
998 * @fmt: The printf()-style format string
1025 * devm_kasprintf - Allocate resource managed space and format a string
1030 * @fmt: The printf()-style format string
1049 * devm_kfree - Resource-managed kfree
1073 * devm_kmemdup - Resource-managed kmemdup
1079 * Duplicate region of a memory using resource managed kmalloc
1103 return devres->addr == target->addr; in devm_pages_match()
1110 free_pages(devres->addr, devres->order); in devm_pages_release()
1114 * devm_get_free_pages - Resource-managed __get_free_pages
1144 devres->addr = addr; in devm_get_free_pages()
1145 devres->order = order; in devm_get_free_pages()
1153 * devm_free_pages - Resource-managed free_pages
1181 return *(void **)devr->data == p; in devm_percpu_match()
1185 * __devm_alloc_percpu - Resource-managed alloc_percpu
1186 * @dev: Device to allocate per-cpu memory for
1187 * @size: Size of per-cpu memory to allocate
1188 * @align: Alignment of per-cpu memory to allocate
1190 * Managed alloc_percpu. Per-cpu memory allocated with this function is
1221 * devm_free_percpu - Resource-managed free_percpu
1223 * @pdata: Per-cpu memory to free