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()
571 spin_lock_irqsave(&dev->devres_lock, flags); in devres_open_group()
572 add_dr(dev, &grp->node[0]); in devres_open_group()
573 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_open_group()
574 return grp->id; in devres_open_group()
578 /* Find devres group with ID @id. If @id is NULL, look for the latest. */
579 static struct devres_group * find_group(struct device *dev, void *id) in find_group() argument
583 list_for_each_entry_reverse(node, &dev->devres_head, entry) { in find_group()
586 if (node->release != &group_open_release) in find_group()
591 if (id) { in find_group()
592 if (grp->id == id) in find_group()
594 } else if (list_empty(&grp->node[1].entry)) in find_group()
602 * devres_close_group - Close a devres group
604 * @id: ID of target group, can be NULL
606 * Close the group identified by @id. If @id is NULL, the latest open
609 void devres_close_group(struct device *dev, void *id) in devres_close_group() argument
614 spin_lock_irqsave(&dev->devres_lock, flags); in devres_close_group()
616 grp = find_group(dev, id); in devres_close_group()
618 add_dr(dev, &grp->node[1]); in devres_close_group()
622 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_close_group()
627 * devres_remove_group - Remove a devres group
629 * @id: ID of target group, can be NULL
631 * Remove the group identified by @id. If @id is NULL, the latest
635 void devres_remove_group(struct device *dev, void *id) in devres_remove_group() argument
640 spin_lock_irqsave(&dev->devres_lock, flags); in devres_remove_group()
642 grp = find_group(dev, id); in devres_remove_group()
644 list_del_init(&grp->node[0].entry); in devres_remove_group()
645 list_del_init(&grp->node[1].entry); in devres_remove_group()
646 devres_log(dev, &grp->node[0], "REM"); in devres_remove_group()
650 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_remove_group()
657 * devres_release_group - Release resources in a devres group
659 * @id: ID of target group, can be NULL
661 * Release all resources in the group identified by @id. If @id is
666 * The number of released non-group resources.
668 int devres_release_group(struct device *dev, void *id) in devres_release_group() argument
675 spin_lock_irqsave(&dev->devres_lock, flags); in devres_release_group()
677 grp = find_group(dev, id); in devres_release_group()
679 struct list_head *first = &grp->node[0].entry; in devres_release_group()
680 struct list_head *end = &dev->devres_head; in devres_release_group()
682 if (!list_empty(&grp->node[1].entry)) in devres_release_group()
683 end = grp->node[1].entry.next; in devres_release_group()
686 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_release_group()
691 spin_unlock_irqrestore(&dev->devres_lock, flags); in devres_release_group()
713 return devres->action == target->action && in devm_action_match()
714 devres->data == target->data; in devm_action_match()
721 devres->action(devres->data); in devm_action_release()
725 * __devm_add_action() - add a custom action to list of managed resources
729 * @name: Name of the resource (for debugging purposes)
732 * it gets executed as part of standard resource unwinding.
741 return -ENOMEM; in __devm_add_action()
743 devres->data = data; in __devm_add_action()
744 devres->action = action; in __devm_add_action()
752 * devm_remove_action() - removes previously added custom action
773 * devm_release_action() - release previously added custom action
809 * devm_kmalloc - Resource-managed kmalloc
837 set_node_dbginfo(&dr->node, "devm_kzalloc_release", size); in devm_kmalloc()
838 devres_add(dev, dr->data); in devm_kmalloc()
839 return dr->data; in devm_kmalloc()
844 * devm_krealloc - Resource-managed krealloc()
845 * @dev: Device to re-allocate memory for
846 * @ptr: Pointer to the memory chunk to re-allocate
854 * change the order in which the release callback for the re-alloc'ed devres
891 * allocated previously - just return the same pointer. in devm_krealloc()
907 * modifications but not the resource itself. in devm_krealloc()
909 spin_lock_irqsave(&dev->devres_lock, flags); in devm_krealloc()
913 spin_unlock_irqrestore(&dev->devres_lock, flags); in devm_krealloc()
919 replace_dr(dev, &old_dr->node, &new_dr->node); in devm_krealloc()
921 spin_unlock_irqrestore(&dev->devres_lock, flags); in devm_krealloc()
927 memcpy(new_dr->data, old_dr->data, in devm_krealloc()
928 total_old_size - offsetof(struct devres, data)); in devm_krealloc()
930 * Same for releasing the old devres - it's now been removed from the in devm_krealloc()
931 * list. This is also the reason why we must not use devm_kfree() - the in devm_krealloc()
936 return new_dr->data; in devm_krealloc()
941 * devm_kstrdup - Allocate resource managed space and
967 * devm_kstrdup_const - resource managed conditional string duplication
989 * devm_kvasprintf - Allocate resource managed space and format a string
994 * @fmt: The printf()-style format string
1021 * devm_kasprintf - Allocate resource managed space and format a string
1026 * @fmt: The printf()-style format string
1045 * devm_kfree - Resource-managed kfree
1069 * devm_kmemdup - Resource-managed kmemdup
1075 * Duplicate region of a memory using resource managed kmalloc
1099 return devres->addr == target->addr; in devm_pages_match()
1106 free_pages(devres->addr, devres->order); in devm_pages_release()
1110 * devm_get_free_pages - Resource-managed __get_free_pages
1140 devres->addr = addr; in devm_get_free_pages()
1141 devres->order = order; in devm_get_free_pages()
1149 * devm_free_pages - Resource-managed free_pages
1177 return *(void **)devr->data == p; in devm_percpu_match()
1181 * __devm_alloc_percpu - Resource-managed alloc_percpu
1182 * @dev: Device to allocate per-cpu memory for
1183 * @size: Size of per-cpu memory to allocate
1184 * @align: Alignment of per-cpu memory to allocate
1186 * Managed alloc_percpu. Per-cpu memory allocated with this function is
1217 * devm_free_percpu - Resource-managed free_percpu
1219 * @pdata: Per-cpu memory to free