mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-16 01:04:08 +08:00
configfs: allow dynamic group creation
This patchset introduces IIO software triggers, offers a way of configuring them via configfs and adds the IIO hrtimer based interrupt source to be used with software triggers. The architecture is now split in 3 parts, to remove all IIO trigger specific parts from IIO configfs core: (1) IIO configfs - creates the root of the IIO configfs subsys. (2) IIO software triggers - software trigger implementation, dynamically creating /config/iio/triggers group. (3) IIO hrtimer trigger - is the first interrupt source for software triggers (with syfs to follow). Each trigger type can implement its own set of attributes. Lockdep seems to be happy with the locking in configfs patch. This patch (of 5): We don't want to hardcode default groups at subsystem creation time. We export: * configfs_register_group * configfs_unregister_group to allow drivers to programatically create/destroy groups later, after module init time. This is needed for IIO configfs support. (akpm: the other 4 patches to be merged via the IIO tree) Signed-off-by: Daniel Baluta <daniel.baluta@intel.com> Suggested-by: Lars-Peter Clausen <lars@metafoo.de> Reviewed-by: Christoph Hellwig <hch@lst.de> Acked-by: Joel Becker <jlbec@evilplan.org> Cc: Hartmut Knaack <knaack.h@gmx.de> Cc: Octavian Purdila <octavian.purdila@intel.com> Cc: Paul Bolle <pebolle@tiscali.nl> Cc: Adriana Reus <adriana.reus@intel.com> Cc: Cristina Opriceana <cristina.opriceana@gmail.com> Cc: Peter Meerwald <pmeerw@pmeerw.net> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
dd7d664a2b
commit
5cf6a51e60
@ -1636,6 +1636,116 @@ const struct file_operations configfs_dir_operations = {
|
||||
.iterate = configfs_readdir,
|
||||
};
|
||||
|
||||
/**
|
||||
* configfs_register_group - creates a parent-child relation between two groups
|
||||
* @parent_group: parent group
|
||||
* @group: child group
|
||||
*
|
||||
* link groups, creates dentry for the child and attaches it to the
|
||||
* parent dentry.
|
||||
*
|
||||
* Return: 0 on success, negative errno code on error
|
||||
*/
|
||||
int configfs_register_group(struct config_group *parent_group,
|
||||
struct config_group *group)
|
||||
{
|
||||
struct configfs_subsystem *subsys = parent_group->cg_subsys;
|
||||
struct dentry *parent;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&subsys->su_mutex);
|
||||
link_group(parent_group, group);
|
||||
mutex_unlock(&subsys->su_mutex);
|
||||
|
||||
parent = parent_group->cg_item.ci_dentry;
|
||||
|
||||
mutex_lock_nested(&d_inode(parent)->i_mutex, I_MUTEX_PARENT);
|
||||
ret = create_default_group(parent_group, group);
|
||||
if (!ret) {
|
||||
spin_lock(&configfs_dirent_lock);
|
||||
configfs_dir_set_ready(group->cg_item.ci_dentry->d_fsdata);
|
||||
spin_unlock(&configfs_dirent_lock);
|
||||
}
|
||||
mutex_unlock(&d_inode(parent)->i_mutex);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(configfs_register_group);
|
||||
|
||||
/**
|
||||
* configfs_unregister_group() - unregisters a child group from its parent
|
||||
* @group: parent group to be unregistered
|
||||
*
|
||||
* Undoes configfs_register_group()
|
||||
*/
|
||||
void configfs_unregister_group(struct config_group *group)
|
||||
{
|
||||
struct configfs_subsystem *subsys = group->cg_subsys;
|
||||
struct dentry *dentry = group->cg_item.ci_dentry;
|
||||
struct dentry *parent = group->cg_item.ci_parent->ci_dentry;
|
||||
|
||||
mutex_lock_nested(&d_inode(parent)->i_mutex, I_MUTEX_PARENT);
|
||||
spin_lock(&configfs_dirent_lock);
|
||||
configfs_detach_prep(dentry, NULL);
|
||||
spin_unlock(&configfs_dirent_lock);
|
||||
|
||||
configfs_detach_group(&group->cg_item);
|
||||
d_inode(dentry)->i_flags |= S_DEAD;
|
||||
dont_mount(dentry);
|
||||
d_delete(dentry);
|
||||
mutex_unlock(&d_inode(parent)->i_mutex);
|
||||
|
||||
dput(dentry);
|
||||
|
||||
mutex_lock(&subsys->su_mutex);
|
||||
unlink_group(group);
|
||||
mutex_unlock(&subsys->su_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(configfs_unregister_group);
|
||||
|
||||
/**
|
||||
* configfs_register_default_group() - allocates and registers a child group
|
||||
* @parent_group: parent group
|
||||
* @name: child group name
|
||||
* @item_type: child item type description
|
||||
*
|
||||
* boilerplate to allocate and register a child group with its parent. We need
|
||||
* kzalloc'ed memory because child's default_group is initially empty.
|
||||
*
|
||||
* Return: allocated config group or ERR_PTR() on error
|
||||
*/
|
||||
struct config_group *
|
||||
configfs_register_default_group(struct config_group *parent_group,
|
||||
const char *name,
|
||||
struct config_item_type *item_type)
|
||||
{
|
||||
int ret;
|
||||
struct config_group *group;
|
||||
|
||||
group = kzalloc(sizeof(*group), GFP_KERNEL);
|
||||
if (!group)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
config_group_init_type_name(group, name, item_type);
|
||||
|
||||
ret = configfs_register_group(parent_group, group);
|
||||
if (ret) {
|
||||
kfree(group);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
return group;
|
||||
}
|
||||
EXPORT_SYMBOL(configfs_register_default_group);
|
||||
|
||||
/**
|
||||
* configfs_unregister_default_group() - unregisters and frees a child group
|
||||
* @group: the group to act on
|
||||
*/
|
||||
void configfs_unregister_default_group(struct config_group *group)
|
||||
{
|
||||
configfs_unregister_group(group);
|
||||
kfree(group);
|
||||
}
|
||||
EXPORT_SYMBOL(configfs_unregister_default_group);
|
||||
|
||||
int configfs_register_subsystem(struct configfs_subsystem *subsys)
|
||||
{
|
||||
int err;
|
||||
|
@ -197,6 +197,16 @@ static inline struct configfs_subsystem *to_configfs_subsystem(struct config_gro
|
||||
int configfs_register_subsystem(struct configfs_subsystem *subsys);
|
||||
void configfs_unregister_subsystem(struct configfs_subsystem *subsys);
|
||||
|
||||
int configfs_register_group(struct config_group *parent_group,
|
||||
struct config_group *group);
|
||||
void configfs_unregister_group(struct config_group *group);
|
||||
|
||||
struct config_group *
|
||||
configfs_register_default_group(struct config_group *parent_group,
|
||||
const char *name,
|
||||
struct config_item_type *item_type);
|
||||
void configfs_unregister_default_group(struct config_group *group);
|
||||
|
||||
/* These functions can sleep and can alloc with GFP_KERNEL */
|
||||
/* WARNING: These cannot be called underneath configfs callbacks!! */
|
||||
int configfs_depend_item(struct configfs_subsystem *subsys, struct config_item *target);
|
||||
|
Loading…
Reference in New Issue
Block a user