diff options
-rw-r--r-- | drivers/base/devres.c | 42 | ||||
-rw-r--r-- | include/linux/device.h | 4 |
2 files changed, 46 insertions, 0 deletions
diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 2360adb7a58f..8731979d668a 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c | |||
@@ -144,6 +144,48 @@ EXPORT_SYMBOL_GPL(devres_alloc); | |||
144 | #endif | 144 | #endif |
145 | 145 | ||
146 | /** | 146 | /** |
147 | * devres_for_each_res - Resource iterator | ||
148 | * @dev: Device to iterate resource from | ||
149 | * @release: Look for resources associated with this release function | ||
150 | * @match: Match function (optional) | ||
151 | * @match_data: Data for the match function | ||
152 | * @fn: Function to be called for each matched resource. | ||
153 | * @data: Data for @fn, the 3rd parameter of @fn | ||
154 | * | ||
155 | * Call @fn for each devres of @dev which is associated with @release | ||
156 | * and for which @match returns 1. | ||
157 | * | ||
158 | * RETURNS: | ||
159 | * void | ||
160 | */ | ||
161 | void devres_for_each_res(struct device *dev, dr_release_t release, | ||
162 | dr_match_t match, void *match_data, | ||
163 | void (*fn)(struct device *, void *, void *), | ||
164 | void *data) | ||
165 | { | ||
166 | struct devres_node *node; | ||
167 | struct devres_node *tmp; | ||
168 | unsigned long flags; | ||
169 | |||
170 | if (!fn) | ||
171 | return; | ||
172 | |||
173 | spin_lock_irqsave(&dev->devres_lock, flags); | ||
174 | list_for_each_entry_safe_reverse(node, tmp, | ||
175 | &dev->devres_head, entry) { | ||
176 | struct devres *dr = container_of(node, struct devres, node); | ||
177 | |||
178 | if (node->release != release) | ||
179 | continue; | ||
180 | if (match && !match(dev, dr->data, match_data)) | ||
181 | continue; | ||
182 | fn(dev, dr->data, data); | ||
183 | } | ||
184 | spin_unlock_irqrestore(&dev->devres_lock, flags); | ||
185 | } | ||
186 | EXPORT_SYMBOL_GPL(devres_for_each_res); | ||
187 | |||
188 | /** | ||
147 | * devres_free - Free device resource data | 189 | * devres_free - Free device resource data |
148 | * @res: Pointer to devres data to free | 190 | * @res: Pointer to devres data to free |
149 | * | 191 | * |
diff --git a/include/linux/device.h b/include/linux/device.h index 52a5f15a2223..ecd900663726 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -536,6 +536,10 @@ extern void *__devres_alloc(dr_release_t release, size_t size, gfp_t gfp, | |||
536 | #else | 536 | #else |
537 | extern void *devres_alloc(dr_release_t release, size_t size, gfp_t gfp); | 537 | extern void *devres_alloc(dr_release_t release, size_t size, gfp_t gfp); |
538 | #endif | 538 | #endif |
539 | extern void devres_for_each_res(struct device *dev, dr_release_t release, | ||
540 | dr_match_t match, void *match_data, | ||
541 | void (*fn)(struct device *, void *, void *), | ||
542 | void *data); | ||
539 | extern void devres_free(void *res); | 543 | extern void devres_free(void *res); |
540 | extern void devres_add(struct device *dev, void *res); | 544 | extern void devres_add(struct device *dev, void *res); |
541 | extern void *devres_find(struct device *dev, dr_release_t release, | 545 | extern void *devres_find(struct device *dev, dr_release_t release, |