diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-01 10:00:28 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-01 10:00:28 -0800 |
| commit | 47fcc0360cfb3fe82e4daddacad3c1cd80b0b75d (patch) | |
| tree | 6a72f705c4e16643e08152ce7828a23c68c623ae /drivers/base/component.c | |
| parent | Merge tag 'staging-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git... (diff) | |
| parent | device property: Define type of PROPERTY_ENRTY_*() macros (diff) | |
| download | linux-47fcc0360cfb3fe82e4daddacad3c1cd80b0b75d.tar.gz linux-47fcc0360cfb3fe82e4daddacad3c1cd80b0b75d.zip | |
Merge tag 'driver-core-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core updates from Greg KH:
"Here is the set of "big" driver core patches for 4.16-rc1.
The majority of the work here is in the firmware subsystem, with
reworks to try to attempt to make the code easier to handle in the
long run, but no functional change. There's also some tree-wide sysfs
attribute fixups with lots of acks from the various subsystem
maintainers, as well as a handful of other normal fixes and changes.
And finally, some license cleanups for the driver core and sysfs code.
All have been in linux-next for a while with no reported issues"
* tag 'driver-core-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (48 commits)
device property: Define type of PROPERTY_ENRTY_*() macros
device property: Reuse property_entry_free_data()
device property: Move property_entry_free_data() upper
firmware: Fix up docs referring to FIRMWARE_IN_KERNEL
firmware: Drop FIRMWARE_IN_KERNEL Kconfig option
USB: serial: keyspan: Drop firmware Kconfig options
sysfs: remove DEBUG defines
sysfs: use SPDX identifiers
drivers: base: add coredump driver ops
sysfs: add attribute specification for /sysfs/devices/.../coredump
test_firmware: fix missing unlock on error in config_num_requests_store()
test_firmware: make local symbol test_fw_config static
sysfs: turn WARN() into pr_warn()
firmware: Fix a typo in fallback-mechanisms.rst
treewide: Use DEVICE_ATTR_WO
treewide: Use DEVICE_ATTR_RO
treewide: Use DEVICE_ATTR_RW
sysfs.h: Use octal permissions
component: add debugfs support
bus: simple-pm-bus: convert bool SIMPLE_PM_BUS to tristate
...
Diffstat (limited to 'drivers/base/component.c')
| -rw-r--r-- | drivers/base/component.c | 83 |
1 files changed, 79 insertions, 4 deletions
diff --git a/drivers/base/component.c b/drivers/base/component.c index 89b032f2ffd2..8946dfee4768 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -1,10 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Componentized device handling. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * * This is work in progress. We gather up the component devices into a list, * and bind them when instructed. At the moment, we're specific to the DRM * subsystem, and only handles one master device, but this doesn't have to be @@ -17,6 +14,7 @@ #include <linux/module.h> #include <linux/mutex.h> #include <linux/slab.h> +#include <linux/debugfs.h> struct component; @@ -41,6 +39,7 @@ struct master { const struct component_master_ops *ops; struct device *dev; struct component_match *match; + struct dentry *dentry; }; struct component { @@ -56,6 +55,80 @@ static DEFINE_MUTEX(component_mutex); static LIST_HEAD(component_list); static LIST_HEAD(masters); +#ifdef CONFIG_DEBUG_FS + +static struct dentry *component_debugfs_dir; + +static int component_devices_show(struct seq_file *s, void *data) +{ + struct master *m = s->private; + struct component_match *match = m->match; + size_t i; + + mutex_lock(&component_mutex); + seq_printf(s, "%-40s %20s\n", "master name", "status"); + seq_puts(s, "-------------------------------------------------------------\n"); + seq_printf(s, "%-40s %20s\n\n", + dev_name(m->dev), m->bound ? "bound" : "not bound"); + + seq_printf(s, "%-40s %20s\n", "device name", "status"); + seq_puts(s, "-------------------------------------------------------------\n"); + for (i = 0; i < match->num; i++) { + struct device *d = (struct device *)match->compare[i].data; + + seq_printf(s, "%-40s %20s\n", dev_name(d), + match->compare[i].component ? + "registered" : "not registered"); + } + mutex_unlock(&component_mutex); + + return 0; +} + +static int component_devices_open(struct inode *inode, struct file *file) +{ + return single_open(file, component_devices_show, inode->i_private); +} + +static const struct file_operations component_devices_fops = { + .open = component_devices_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init component_debug_init(void) +{ + component_debugfs_dir = debugfs_create_dir("device_component", NULL); + + return 0; +} + +core_initcall(component_debug_init); + +static void component_master_debugfs_add(struct master *m) +{ + m->dentry = debugfs_create_file(dev_name(m->dev), 0444, + component_debugfs_dir, + m, &component_devices_fops); +} + +static void component_master_debugfs_del(struct master *m) +{ + debugfs_remove(m->dentry); + m->dentry = NULL; +} + +#else + +static void component_master_debugfs_add(struct master *m) +{ } + +static void component_master_debugfs_del(struct master *m) +{ } + +#endif + static struct master *__master_find(struct device *dev, const struct component_master_ops *ops) { @@ -290,6 +363,7 @@ static void free_master(struct master *master) struct component_match *match = master->match; int i; + component_master_debugfs_del(master); list_del(&master->node); if (match) { @@ -323,6 +397,7 @@ int component_master_add_with_match(struct device *dev, master->ops = ops; master->match = match; + component_master_debugfs_add(master); /* Add to the list of available masters. */ mutex_lock(&component_mutex); list_add(&master->node, &masters); |
