1 // SPDX-License-Identifier: GPL-2.0
3 * Componentized device handling.
5 * This is work in progress. We gather up the component devices into a list,
6 * and bind them when instructed. At the moment, we're specific to the DRM
7 * subsystem, and only handles one master device, but this doesn't have to be
10 #include <linux/component.h>
11 #include <linux/device.h>
12 #include <linux/kref.h>
13 #include <linux/list.h>
14 #include <linux/module.h>
15 #include <linux/mutex.h>
16 #include <linux/slab.h>
17 #include <linux/debugfs.h>
21 struct component_match_array
{
23 int (*compare
)(struct device
*, void *);
24 void (*release
)(struct device
*, void *);
25 struct component
*component
;
29 struct component_match
{
32 struct component_match_array
*compare
;
36 struct list_head node
;
39 const struct component_master_ops
*ops
;
41 struct component_match
*match
;
42 struct dentry
*dentry
;
46 struct list_head node
;
47 struct master
*master
;
50 const struct component_ops
*ops
;
54 static DEFINE_MUTEX(component_mutex
);
55 static LIST_HEAD(component_list
);
56 static LIST_HEAD(masters
);
58 #ifdef CONFIG_DEBUG_FS
60 static struct dentry
*component_debugfs_dir
;
62 static int component_devices_show(struct seq_file
*s
, void *data
)
64 struct master
*m
= s
->private;
65 struct component_match
*match
= m
->match
;
68 mutex_lock(&component_mutex
);
69 seq_printf(s
, "%-40s %20s\n", "master name", "status");
70 seq_puts(s
, "-------------------------------------------------------------\n");
71 seq_printf(s
, "%-40s %20s\n\n",
72 dev_name(m
->dev
), m
->bound
? "bound" : "not bound");
74 seq_printf(s
, "%-40s %20s\n", "device name", "status");
75 seq_puts(s
, "-------------------------------------------------------------\n");
76 for (i
= 0; i
< match
->num
; i
++) {
77 struct component
*component
= match
->compare
[i
].component
;
79 seq_printf(s
, "%-40s %20s\n",
80 component
? dev_name(component
->dev
) : "(unknown)",
81 component
? (component
->bound
? "bound" : "not bound") : "not registered");
83 mutex_unlock(&component_mutex
);
88 static int component_devices_open(struct inode
*inode
, struct file
*file
)
90 return single_open(file
, component_devices_show
, inode
->i_private
);
93 static const struct file_operations component_devices_fops
= {
94 .open
= component_devices_open
,
97 .release
= single_release
,
100 static int __init
component_debug_init(void)
102 component_debugfs_dir
= debugfs_create_dir("device_component", NULL
);
107 core_initcall(component_debug_init
);
109 static void component_master_debugfs_add(struct master
*m
)
111 m
->dentry
= debugfs_create_file(dev_name(m
->dev
), 0444,
112 component_debugfs_dir
,
113 m
, &component_devices_fops
);
116 static void component_master_debugfs_del(struct master
*m
)
118 debugfs_remove(m
->dentry
);
124 static void component_master_debugfs_add(struct master
*m
)
127 static void component_master_debugfs_del(struct master
*m
)
132 static struct master
*__master_find(struct device
*dev
,
133 const struct component_master_ops
*ops
)
137 list_for_each_entry(m
, &masters
, node
)
138 if (m
->dev
== dev
&& (!ops
|| m
->ops
== ops
))
144 static struct component
*find_component(struct master
*master
,
145 int (*compare
)(struct device
*, void *), void *compare_data
)
149 list_for_each_entry(c
, &component_list
, node
) {
150 if (c
->master
&& c
->master
!= master
)
153 if (compare(c
->dev
, compare_data
))
160 static int find_components(struct master
*master
)
162 struct component_match
*match
= master
->match
;
167 * Scan the array of match functions and attach
168 * any components which are found to this master.
170 for (i
= 0; i
< match
->num
; i
++) {
171 struct component_match_array
*mc
= &match
->compare
[i
];
174 dev_dbg(master
->dev
, "Looking for component %zu\n", i
);
176 if (match
->compare
[i
].component
)
179 c
= find_component(master
, mc
->compare
, mc
->data
);
185 dev_dbg(master
->dev
, "found component %s, duplicate %u\n", dev_name(c
->dev
), !!c
->master
);
187 /* Attach this component to the master */
188 match
->compare
[i
].duplicate
= !!c
->master
;
189 match
->compare
[i
].component
= c
;
195 /* Detach component from associated master */
196 static void remove_component(struct master
*master
, struct component
*c
)
200 /* Detach the component from this master. */
201 for (i
= 0; i
< master
->match
->num
; i
++)
202 if (master
->match
->compare
[i
].component
== c
)
203 master
->match
->compare
[i
].component
= NULL
;
207 * Try to bring up a master. If component is NULL, we're interested in
208 * this master, otherwise it's a component which must be present to try
209 * and bring up the master.
211 * Returns 1 for successful bringup, 0 if not ready, or -ve errno.
213 static int try_to_bring_up_master(struct master
*master
,
214 struct component
*component
)
218 dev_dbg(master
->dev
, "trying to bring up master\n");
220 if (find_components(master
)) {
221 dev_dbg(master
->dev
, "master has incomplete components\n");
225 if (component
&& component
->master
!= master
) {
226 dev_dbg(master
->dev
, "master is not for this component (%s)\n",
227 dev_name(component
->dev
));
231 if (!devres_open_group(master
->dev
, NULL
, GFP_KERNEL
))
234 /* Found all components */
235 ret
= master
->ops
->bind(master
->dev
);
237 devres_release_group(master
->dev
, NULL
);
238 if (ret
!= -EPROBE_DEFER
)
239 dev_info(master
->dev
, "master bind failed: %d\n", ret
);
243 master
->bound
= true;
247 static int try_to_bring_up_masters(struct component
*component
)
252 list_for_each_entry(m
, &masters
, node
) {
254 ret
= try_to_bring_up_master(m
, component
);
263 static void take_down_master(struct master
*master
)
266 master
->ops
->unbind(master
->dev
);
267 devres_release_group(master
->dev
, NULL
);
268 master
->bound
= false;
272 static void component_match_release(struct device
*master
,
273 struct component_match
*match
)
277 for (i
= 0; i
< match
->num
; i
++) {
278 struct component_match_array
*mc
= &match
->compare
[i
];
281 mc
->release(master
, mc
->data
);
284 kfree(match
->compare
);
287 static void devm_component_match_release(struct device
*dev
, void *res
)
289 component_match_release(dev
, res
);
292 static int component_match_realloc(struct device
*dev
,
293 struct component_match
*match
, size_t num
)
295 struct component_match_array
*new;
297 if (match
->alloc
== num
)
300 new = kmalloc_array(num
, sizeof(*new), GFP_KERNEL
);
304 if (match
->compare
) {
305 memcpy(new, match
->compare
, sizeof(*new) *
306 min(match
->num
, num
));
307 kfree(match
->compare
);
309 match
->compare
= new;
316 * Add a component to be matched, with a release function.
318 * The match array is first created or extended if necessary.
320 void component_match_add_release(struct device
*master
,
321 struct component_match
**matchptr
,
322 void (*release
)(struct device
*, void *),
323 int (*compare
)(struct device
*, void *), void *compare_data
)
325 struct component_match
*match
= *matchptr
;
331 match
= devres_alloc(devm_component_match_release
,
332 sizeof(*match
), GFP_KERNEL
);
334 *matchptr
= ERR_PTR(-ENOMEM
);
338 devres_add(master
, match
);
343 if (match
->num
== match
->alloc
) {
344 size_t new_size
= match
->alloc
+ 16;
347 ret
= component_match_realloc(master
, match
, new_size
);
349 *matchptr
= ERR_PTR(ret
);
354 match
->compare
[match
->num
].compare
= compare
;
355 match
->compare
[match
->num
].release
= release
;
356 match
->compare
[match
->num
].data
= compare_data
;
357 match
->compare
[match
->num
].component
= NULL
;
360 EXPORT_SYMBOL(component_match_add_release
);
362 static void free_master(struct master
*master
)
364 struct component_match
*match
= master
->match
;
367 component_master_debugfs_del(master
);
368 list_del(&master
->node
);
371 for (i
= 0; i
< match
->num
; i
++) {
372 struct component
*c
= match
->compare
[i
].component
;
381 int component_master_add_with_match(struct device
*dev
,
382 const struct component_master_ops
*ops
,
383 struct component_match
*match
)
385 struct master
*master
;
388 /* Reallocate the match array for its true size */
389 ret
= component_match_realloc(dev
, match
, match
->num
);
393 master
= kzalloc(sizeof(*master
), GFP_KERNEL
);
399 master
->match
= match
;
401 component_master_debugfs_add(master
);
402 /* Add to the list of available masters. */
403 mutex_lock(&component_mutex
);
404 list_add(&master
->node
, &masters
);
406 ret
= try_to_bring_up_master(master
, NULL
);
411 mutex_unlock(&component_mutex
);
413 return ret
< 0 ? ret
: 0;
415 EXPORT_SYMBOL_GPL(component_master_add_with_match
);
417 void component_master_del(struct device
*dev
,
418 const struct component_master_ops
*ops
)
420 struct master
*master
;
422 mutex_lock(&component_mutex
);
423 master
= __master_find(dev
, ops
);
425 take_down_master(master
);
428 mutex_unlock(&component_mutex
);
430 EXPORT_SYMBOL_GPL(component_master_del
);
432 static void component_unbind(struct component
*component
,
433 struct master
*master
, void *data
)
435 WARN_ON(!component
->bound
);
437 component
->ops
->unbind(component
->dev
, master
->dev
, data
);
438 component
->bound
= false;
440 /* Release all resources claimed in the binding of this component */
441 devres_release_group(component
->dev
, component
);
444 void component_unbind_all(struct device
*master_dev
, void *data
)
446 struct master
*master
;
450 WARN_ON(!mutex_is_locked(&component_mutex
));
452 master
= __master_find(master_dev
, NULL
);
456 /* Unbind components in reverse order */
457 for (i
= master
->match
->num
; i
--; )
458 if (!master
->match
->compare
[i
].duplicate
) {
459 c
= master
->match
->compare
[i
].component
;
460 component_unbind(c
, master
, data
);
463 EXPORT_SYMBOL_GPL(component_unbind_all
);
465 static int component_bind(struct component
*component
, struct master
*master
,
471 * Each component initialises inside its own devres group.
472 * This allows us to roll-back a failed component without
473 * affecting anything else.
475 if (!devres_open_group(master
->dev
, NULL
, GFP_KERNEL
))
479 * Also open a group for the device itself: this allows us
480 * to release the resources claimed against the sub-device
481 * at the appropriate moment.
483 if (!devres_open_group(component
->dev
, component
, GFP_KERNEL
)) {
484 devres_release_group(master
->dev
, NULL
);
488 dev_dbg(master
->dev
, "binding %s (ops %ps)\n",
489 dev_name(component
->dev
), component
->ops
);
491 ret
= component
->ops
->bind(component
->dev
, master
->dev
, data
);
493 component
->bound
= true;
496 * Close the component device's group so that resources
497 * allocated in the binding are encapsulated for removal
498 * at unbind. Remove the group on the DRM device as we
499 * can clean those resources up independently.
501 devres_close_group(component
->dev
, NULL
);
502 devres_remove_group(master
->dev
, NULL
);
504 dev_info(master
->dev
, "bound %s (ops %ps)\n",
505 dev_name(component
->dev
), component
->ops
);
507 devres_release_group(component
->dev
, NULL
);
508 devres_release_group(master
->dev
, NULL
);
510 if (ret
!= -EPROBE_DEFER
)
511 dev_err(master
->dev
, "failed to bind %s (ops %ps): %d\n",
512 dev_name(component
->dev
), component
->ops
, ret
);
518 int component_bind_all(struct device
*master_dev
, void *data
)
520 struct master
*master
;
525 WARN_ON(!mutex_is_locked(&component_mutex
));
527 master
= __master_find(master_dev
, NULL
);
531 /* Bind components in match order */
532 for (i
= 0; i
< master
->match
->num
; i
++)
533 if (!master
->match
->compare
[i
].duplicate
) {
534 c
= master
->match
->compare
[i
].component
;
535 ret
= component_bind(c
, master
, data
);
542 if (!master
->match
->compare
[i
- 1].duplicate
) {
543 c
= master
->match
->compare
[i
- 1].component
;
544 component_unbind(c
, master
, data
);
550 EXPORT_SYMBOL_GPL(component_bind_all
);
552 int component_add(struct device
*dev
, const struct component_ops
*ops
)
554 struct component
*component
;
557 component
= kzalloc(sizeof(*component
), GFP_KERNEL
);
561 component
->ops
= ops
;
562 component
->dev
= dev
;
564 dev_dbg(dev
, "adding component (ops %ps)\n", ops
);
566 mutex_lock(&component_mutex
);
567 list_add_tail(&component
->node
, &component_list
);
569 ret
= try_to_bring_up_masters(component
);
571 if (component
->master
)
572 remove_component(component
->master
, component
);
573 list_del(&component
->node
);
577 mutex_unlock(&component_mutex
);
579 return ret
< 0 ? ret
: 0;
581 EXPORT_SYMBOL_GPL(component_add
);
583 void component_del(struct device
*dev
, const struct component_ops
*ops
)
585 struct component
*c
, *component
= NULL
;
587 mutex_lock(&component_mutex
);
588 list_for_each_entry(c
, &component_list
, node
)
589 if (c
->dev
== dev
&& c
->ops
== ops
) {
595 if (component
&& component
->master
) {
596 take_down_master(component
->master
);
597 remove_component(component
->master
, component
);
600 mutex_unlock(&component_mutex
);
605 EXPORT_SYMBOL_GPL(component_del
);
607 MODULE_LICENSE("GPL v2");