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 device
*d
= (struct device
*)match
->compare
[i
].data
;
79 seq_printf(s
, "%-40s %20s\n", dev_name(d
),
80 match
->compare
[i
].component
?
81 "registered" : "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 dev_info(master
->dev
, "master bind failed: %d\n", ret
);
242 master
->bound
= true;
246 static int try_to_bring_up_masters(struct component
*component
)
251 list_for_each_entry(m
, &masters
, node
) {
253 ret
= try_to_bring_up_master(m
, component
);
262 static void take_down_master(struct master
*master
)
265 master
->ops
->unbind(master
->dev
);
266 devres_release_group(master
->dev
, NULL
);
267 master
->bound
= false;
271 static void component_match_release(struct device
*master
,
272 struct component_match
*match
)
276 for (i
= 0; i
< match
->num
; i
++) {
277 struct component_match_array
*mc
= &match
->compare
[i
];
280 mc
->release(master
, mc
->data
);
283 kfree(match
->compare
);
286 static void devm_component_match_release(struct device
*dev
, void *res
)
288 component_match_release(dev
, res
);
291 static int component_match_realloc(struct device
*dev
,
292 struct component_match
*match
, size_t num
)
294 struct component_match_array
*new;
296 if (match
->alloc
== num
)
299 new = kmalloc_array(num
, sizeof(*new), GFP_KERNEL
);
303 if (match
->compare
) {
304 memcpy(new, match
->compare
, sizeof(*new) *
305 min(match
->num
, num
));
306 kfree(match
->compare
);
308 match
->compare
= new;
315 * Add a component to be matched, with a release function.
317 * The match array is first created or extended if necessary.
319 void component_match_add_release(struct device
*master
,
320 struct component_match
**matchptr
,
321 void (*release
)(struct device
*, void *),
322 int (*compare
)(struct device
*, void *), void *compare_data
)
324 struct component_match
*match
= *matchptr
;
330 match
= devres_alloc(devm_component_match_release
,
331 sizeof(*match
), GFP_KERNEL
);
333 *matchptr
= ERR_PTR(-ENOMEM
);
337 devres_add(master
, match
);
342 if (match
->num
== match
->alloc
) {
343 size_t new_size
= match
->alloc
+ 16;
346 ret
= component_match_realloc(master
, match
, new_size
);
348 *matchptr
= ERR_PTR(ret
);
353 match
->compare
[match
->num
].compare
= compare
;
354 match
->compare
[match
->num
].release
= release
;
355 match
->compare
[match
->num
].data
= compare_data
;
356 match
->compare
[match
->num
].component
= NULL
;
359 EXPORT_SYMBOL(component_match_add_release
);
361 static void free_master(struct master
*master
)
363 struct component_match
*match
= master
->match
;
366 component_master_debugfs_del(master
);
367 list_del(&master
->node
);
370 for (i
= 0; i
< match
->num
; i
++) {
371 struct component
*c
= match
->compare
[i
].component
;
380 int component_master_add_with_match(struct device
*dev
,
381 const struct component_master_ops
*ops
,
382 struct component_match
*match
)
384 struct master
*master
;
387 /* Reallocate the match array for its true size */
388 ret
= component_match_realloc(dev
, match
, match
->num
);
392 master
= kzalloc(sizeof(*master
), GFP_KERNEL
);
398 master
->match
= match
;
400 component_master_debugfs_add(master
);
401 /* Add to the list of available masters. */
402 mutex_lock(&component_mutex
);
403 list_add(&master
->node
, &masters
);
405 ret
= try_to_bring_up_master(master
, NULL
);
410 mutex_unlock(&component_mutex
);
412 return ret
< 0 ? ret
: 0;
414 EXPORT_SYMBOL_GPL(component_master_add_with_match
);
416 void component_master_del(struct device
*dev
,
417 const struct component_master_ops
*ops
)
419 struct master
*master
;
421 mutex_lock(&component_mutex
);
422 master
= __master_find(dev
, ops
);
424 take_down_master(master
);
427 mutex_unlock(&component_mutex
);
429 EXPORT_SYMBOL_GPL(component_master_del
);
431 static void component_unbind(struct component
*component
,
432 struct master
*master
, void *data
)
434 WARN_ON(!component
->bound
);
436 component
->ops
->unbind(component
->dev
, master
->dev
, data
);
437 component
->bound
= false;
439 /* Release all resources claimed in the binding of this component */
440 devres_release_group(component
->dev
, component
);
443 void component_unbind_all(struct device
*master_dev
, void *data
)
445 struct master
*master
;
449 WARN_ON(!mutex_is_locked(&component_mutex
));
451 master
= __master_find(master_dev
, NULL
);
455 /* Unbind components in reverse order */
456 for (i
= master
->match
->num
; i
--; )
457 if (!master
->match
->compare
[i
].duplicate
) {
458 c
= master
->match
->compare
[i
].component
;
459 component_unbind(c
, master
, data
);
462 EXPORT_SYMBOL_GPL(component_unbind_all
);
464 static int component_bind(struct component
*component
, struct master
*master
,
470 * Each component initialises inside its own devres group.
471 * This allows us to roll-back a failed component without
472 * affecting anything else.
474 if (!devres_open_group(master
->dev
, NULL
, GFP_KERNEL
))
478 * Also open a group for the device itself: this allows us
479 * to release the resources claimed against the sub-device
480 * at the appropriate moment.
482 if (!devres_open_group(component
->dev
, component
, GFP_KERNEL
)) {
483 devres_release_group(master
->dev
, NULL
);
487 dev_dbg(master
->dev
, "binding %s (ops %ps)\n",
488 dev_name(component
->dev
), component
->ops
);
490 ret
= component
->ops
->bind(component
->dev
, master
->dev
, data
);
492 component
->bound
= true;
495 * Close the component device's group so that resources
496 * allocated in the binding are encapsulated for removal
497 * at unbind. Remove the group on the DRM device as we
498 * can clean those resources up independently.
500 devres_close_group(component
->dev
, NULL
);
501 devres_remove_group(master
->dev
, NULL
);
503 dev_info(master
->dev
, "bound %s (ops %ps)\n",
504 dev_name(component
->dev
), component
->ops
);
506 devres_release_group(component
->dev
, NULL
);
507 devres_release_group(master
->dev
, NULL
);
509 dev_err(master
->dev
, "failed to bind %s (ops %ps): %d\n",
510 dev_name(component
->dev
), component
->ops
, ret
);
516 int component_bind_all(struct device
*master_dev
, void *data
)
518 struct master
*master
;
523 WARN_ON(!mutex_is_locked(&component_mutex
));
525 master
= __master_find(master_dev
, NULL
);
529 /* Bind components in match order */
530 for (i
= 0; i
< master
->match
->num
; i
++)
531 if (!master
->match
->compare
[i
].duplicate
) {
532 c
= master
->match
->compare
[i
].component
;
533 ret
= component_bind(c
, master
, data
);
540 if (!master
->match
->compare
[i
].duplicate
) {
541 c
= master
->match
->compare
[i
].component
;
542 component_unbind(c
, master
, data
);
548 EXPORT_SYMBOL_GPL(component_bind_all
);
550 int component_add(struct device
*dev
, const struct component_ops
*ops
)
552 struct component
*component
;
555 component
= kzalloc(sizeof(*component
), GFP_KERNEL
);
559 component
->ops
= ops
;
560 component
->dev
= dev
;
562 dev_dbg(dev
, "adding component (ops %ps)\n", ops
);
564 mutex_lock(&component_mutex
);
565 list_add_tail(&component
->node
, &component_list
);
567 ret
= try_to_bring_up_masters(component
);
569 if (component
->master
)
570 remove_component(component
->master
, component
);
571 list_del(&component
->node
);
575 mutex_unlock(&component_mutex
);
577 return ret
< 0 ? ret
: 0;
579 EXPORT_SYMBOL_GPL(component_add
);
581 void component_del(struct device
*dev
, const struct component_ops
*ops
)
583 struct component
*c
, *component
= NULL
;
585 mutex_lock(&component_mutex
);
586 list_for_each_entry(c
, &component_list
, node
)
587 if (c
->dev
== dev
&& c
->ops
== ops
) {
593 if (component
&& component
->master
) {
594 take_down_master(component
->master
);
595 remove_component(component
->master
, component
);
598 mutex_unlock(&component_mutex
);
603 EXPORT_SYMBOL_GPL(component_del
);
605 MODULE_LICENSE("GPL v2");