aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/component.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/component.c')
-rw-r--r--drivers/base/component.c158
1 files changed, 121 insertions, 37 deletions
diff --git a/drivers/base/component.c b/drivers/base/component.c
index 1624c2a892a5..7dbc41cccd58 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -47,6 +47,7 @@ struct component;
47struct component_match_array { 47struct component_match_array {
48 void *data; 48 void *data;
49 int (*compare)(struct device *, void *); 49 int (*compare)(struct device *, void *);
50 int (*compare_typed)(struct device *, int, void *);
50 void (*release)(struct device *, void *); 51 void (*release)(struct device *, void *);
51 struct component *component; 52 struct component *component;
52 bool duplicate; 53 bool duplicate;
@@ -74,6 +75,7 @@ struct component {
74 bool bound; 75 bool bound;
75 76
76 const struct component_ops *ops; 77 const struct component_ops *ops;
78 int subcomponent;
77 struct device *dev; 79 struct device *dev;
78}; 80};
79 81
@@ -158,7 +160,7 @@ static struct master *__master_find(struct device *dev,
158} 160}
159 161
160static struct component *find_component(struct master *master, 162static struct component *find_component(struct master *master,
161 int (*compare)(struct device *, void *), void *compare_data) 163 struct component_match_array *mc)
162{ 164{
163 struct component *c; 165 struct component *c;
164 166
@@ -166,7 +168,11 @@ static struct component *find_component(struct master *master,
166 if (c->master && c->master != master) 168 if (c->master && c->master != master)
167 continue; 169 continue;
168 170
169 if (compare(c->dev, compare_data)) 171 if (mc->compare && mc->compare(c->dev, mc->data))
172 return c;
173
174 if (mc->compare_typed &&
175 mc->compare_typed(c->dev, c->subcomponent, mc->data))
170 return c; 176 return c;
171 } 177 }
172 178
@@ -192,7 +198,7 @@ static int find_components(struct master *master)
192 if (match->compare[i].component) 198 if (match->compare[i].component)
193 continue; 199 continue;
194 200
195 c = find_component(master, mc->compare, mc->data); 201 c = find_component(master, mc);
196 if (!c) { 202 if (!c) {
197 ret = -ENXIO; 203 ret = -ENXIO;
198 break; 204 break;
@@ -327,29 +333,12 @@ static int component_match_realloc(struct device *dev,
327 return 0; 333 return 0;
328} 334}
329 335
330/** 336static void __component_match_add(struct device *master,
331 * component_match_add_release - add a component match with release callback
332 * @master: device with the aggregate driver
333 * @matchptr: pointer to the list of component matches
334 * @release: release function for @compare_data
335 * @compare: compare function to match against all components
336 * @compare_data: opaque pointer passed to the @compare function
337 *
338 * Adds a new component match to the list stored in @matchptr, which the @master
339 * aggregate driver needs to function. The list of component matches pointed to
340 * by @matchptr must be initialized to NULL before adding the first match.
341 *
342 * The allocated match list in @matchptr is automatically released using devm
343 * actions, where upon @release will be called to free any references held by
344 * @compare_data, e.g. when @compare_data is a &device_node that must be
345 * released with of_node_put().
346 *
347 * See also component_match_add().
348 */
349void component_match_add_release(struct device *master,
350 struct component_match **matchptr, 337 struct component_match **matchptr,
351 void (*release)(struct device *, void *), 338 void (*release)(struct device *, void *),
352 int (*compare)(struct device *, void *), void *compare_data) 339 int (*compare)(struct device *, void *),
340 int (*compare_typed)(struct device *, int, void *),
341 void *compare_data)
353{ 342{
354 struct component_match *match = *matchptr; 343 struct component_match *match = *matchptr;
355 344
@@ -381,13 +370,69 @@ void component_match_add_release(struct device *master,
381 } 370 }
382 371
383 match->compare[match->num].compare = compare; 372 match->compare[match->num].compare = compare;
373 match->compare[match->num].compare_typed = compare_typed;
384 match->compare[match->num].release = release; 374 match->compare[match->num].release = release;
385 match->compare[match->num].data = compare_data; 375 match->compare[match->num].data = compare_data;
386 match->compare[match->num].component = NULL; 376 match->compare[match->num].component = NULL;
387 match->num++; 377 match->num++;
388} 378}
379
380/**
381 * component_match_add_release - add a component match with release callback
382 * @master: device with the aggregate driver
383 * @matchptr: pointer to the list of component matches
384 * @release: release function for @compare_data
385 * @compare: compare function to match against all components
386 * @compare_data: opaque pointer passed to the @compare function
387 *
388 * Adds a new component match to the list stored in @matchptr, which the @master
389 * aggregate driver needs to function. The list of component matches pointed to
390 * by @matchptr must be initialized to NULL before adding the first match. This
391 * only matches against components added with component_add().
392 *
393 * The allocated match list in @matchptr is automatically released using devm
394 * actions, where upon @release will be called to free any references held by
395 * @compare_data, e.g. when @compare_data is a &device_node that must be
396 * released with of_node_put().
397 *
398 * See also component_match_add() and component_match_add_typed().
399 */
400void component_match_add_release(struct device *master,
401 struct component_match **matchptr,
402 void (*release)(struct device *, void *),
403 int (*compare)(struct device *, void *), void *compare_data)
404{
405 __component_match_add(master, matchptr, release, compare, NULL,
406 compare_data);
407}
389EXPORT_SYMBOL(component_match_add_release); 408EXPORT_SYMBOL(component_match_add_release);
390 409
410/**
411 * component_match_add_typed - add a compent match for a typed component
412 * @master: device with the aggregate driver
413 * @matchptr: pointer to the list of component matches
414 * @compare_typed: compare function to match against all typed components
415 * @compare_data: opaque pointer passed to the @compare function
416 *
417 * Adds a new component match to the list stored in @matchptr, which the @master
418 * aggregate driver needs to function. The list of component matches pointed to
419 * by @matchptr must be initialized to NULL before adding the first match. This
420 * only matches against components added with component_add_typed().
421 *
422 * The allocated match list in @matchptr is automatically released using devm
423 * actions.
424 *
425 * See also component_match_add_release() and component_match_add_typed().
426 */
427void component_match_add_typed(struct device *master,
428 struct component_match **matchptr,
429 int (*compare_typed)(struct device *, int, void *), void *compare_data)
430{
431 __component_match_add(master, matchptr, NULL, NULL, compare_typed,
432 compare_data);
433}
434EXPORT_SYMBOL(component_match_add_typed);
435
391static void free_master(struct master *master) 436static void free_master(struct master *master)
392{ 437{
393 struct component_match *match = master->match; 438 struct component_match *match = master->match;
@@ -616,19 +661,8 @@ int component_bind_all(struct device *master_dev, void *data)
616} 661}
617EXPORT_SYMBOL_GPL(component_bind_all); 662EXPORT_SYMBOL_GPL(component_bind_all);
618 663
619/** 664static int __component_add(struct device *dev, const struct component_ops *ops,
620 * component_add - register a component 665 int subcomponent)
621 * @dev: component device
622 * @ops: component callbacks
623 *
624 * Register a new component for @dev. Functions in @ops will be called when the
625 * aggregate driver is ready to bind the overall driver by calling
626 * component_bind_all(). See also &struct component_ops.
627 *
628 * The component needs to be unregistered at driver unload/disconnect by calling
629 * component_del().
630 */
631int component_add(struct device *dev, const struct component_ops *ops)
632{ 666{
633 struct component *component; 667 struct component *component;
634 int ret; 668 int ret;
@@ -639,6 +673,7 @@ int component_add(struct device *dev, const struct component_ops *ops)
639 673
640 component->ops = ops; 674 component->ops = ops;
641 component->dev = dev; 675 component->dev = dev;
676 component->subcomponent = subcomponent;
642 677
643 dev_dbg(dev, "adding component (ops %ps)\n", ops); 678 dev_dbg(dev, "adding component (ops %ps)\n", ops);
644 679
@@ -657,6 +692,55 @@ int component_add(struct device *dev, const struct component_ops *ops)
657 692
658 return ret < 0 ? ret : 0; 693 return ret < 0 ? ret : 0;
659} 694}
695
696/**
697 * component_add_typed - register a component
698 * @dev: component device
699 * @ops: component callbacks
700 * @subcomponent: nonzero identifier for subcomponents
701 *
702 * Register a new component for @dev. Functions in @ops will be call when the
703 * aggregate driver is ready to bind the overall driver by calling
704 * component_bind_all(). See also &struct component_ops.
705 *
706 * @subcomponent must be nonzero and is used to differentiate between multiple
707 * components registerd on the same device @dev. These components are match
708 * using component_match_add_typed().
709 *
710 * The component needs to be unregistered at driver unload/disconnect by
711 * calling component_del().
712 *
713 * See also component_add().
714 */
715int component_add_typed(struct device *dev, const struct component_ops *ops,
716 int subcomponent)
717{
718 if (WARN_ON(subcomponent == 0))
719 return -EINVAL;
720
721 return __component_add(dev, ops, subcomponent);
722}
723EXPORT_SYMBOL_GPL(component_add_typed);
724
725/**
726 * component_add - register a component
727 * @dev: component device
728 * @ops: component callbacks
729 *
730 * Register a new component for @dev. Functions in @ops will be called when the
731 * aggregate driver is ready to bind the overall driver by calling
732 * component_bind_all(). See also &struct component_ops.
733 *
734 * The component needs to be unregistered at driver unload/disconnect by
735 * calling component_del().
736 *
737 * See also component_add_typed() for a variant that allows multipled different
738 * components on the same device.
739 */
740int component_add(struct device *dev, const struct component_ops *ops)
741{
742 return __component_add(dev, ops, 0);
743}
660EXPORT_SYMBOL_GPL(component_add); 744EXPORT_SYMBOL_GPL(component_add);
661 745
662/** 746/**