[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250423175040.784680-4-david.e.box@linux.intel.com>
Date: Wed, 23 Apr 2025 10:50:33 -0700
From: "David E. Box" <david.e.box@...ux.intel.com>
To: corbet@....net,
bhelgaas@...gle.com,
kuurtb@...il.com,
hdegoede@...hat.com,
ilpo.jarvinen@...ux.intel.com,
vkoul@...nel.org,
yung-chuan.liao@...ux.intel.com,
pierre-louis.bossart@...ux.dev,
sanyog.r.kale@...el.com,
gregkh@...uxfoundation.org,
rafael@...nel.org,
dakr@...nel.org,
david.e.box@...ux.intel.com,
dan.j.williams@...el.com,
andriy.shevchenko@...ux.intel.com
Cc: linux-doc@...r.kernel.org,
linux-kernel@...r.kernel.org,
linux-pci@...r.kernel.org,
platform-driver-x86@...r.kernel.org,
Dell.Client.Kernel@...l.com,
linux-sound@...r.kernel.org
Subject: [PATCH 3/7] docs: sysfs.rst: document additional attribute group macros
Add documentation to Documentation/filesystems/sysfs.rst for several sysfs
helper macros, including recently introduced and previously undocumented
helpers.
Document the following macros:
__ATTR_IGNORE_LOCKDEP
DEFINE_SYSFS_GROUP_VISIBILITY
DEFINE_SYSFS_BIN_GROUP_VISIBILITY
DEFINE_SYSFS_BIN_GROUP_COMBO_VISIBILITY
ATTRIBUTE_GROUPS
BIN_ATTRIBUTE_GROUPS
NAMED_ATTRIBUTE_GROUP_VISIBLE
NAMED_ATTRIBUTE_GROUPS_VISIBLE
NAMED_ATTRIBUTE_GROUP_COMBO_VISIBLE
NAMED_ATTRIBUTE_GROUPS_COMBO_VISIBLE
Suggested-by: Andy Shevchenko <andriy.shevchenko@...ux.intel.com>
Signed-off-by: David E. Box <david.e.box@...ux.intel.com>
---
Documentation/filesystems/sysfs.rst | 244 ++++++++++++++++++++++++++++
1 file changed, 244 insertions(+)
diff --git a/Documentation/filesystems/sysfs.rst b/Documentation/filesystems/sysfs.rst
index c32993bc83c7..16bcc3e7c80c 100644
--- a/Documentation/filesystems/sysfs.rst
+++ b/Documentation/filesystems/sysfs.rst
@@ -147,6 +147,250 @@ __ATTR_RW(name):
__ATTR_NULL:
which sets the name to NULL and is used as end of list
indicator (see: kernel/workqueue.c)
+__ATTR_IGNORE_LOCKDEP(name, mode, show, store):
+ like __ATTR() but disables lockdep checks; used in cases
+ where lockdep may emit false positives
+
+Additional Attribute Helpers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ATTRIBUTE_GROUPS(name):
+ Convenience macro to create an array of attribute group pointers.
+
+Example::
+
+ static struct attribute *foo_attrs[] = {
+ &attr1.attr,
+ &attr2.attr,
+ NULL
+ };
+ ATTRIBUTE_GROUPS(foo);
+
+BIN_ATTRIBUTE_GROUPS(name):
+ Same as ATTRIBUTE_GROUPS(), but for bin_attribute_group structures.
+
+Example::
+
+ static struct bin_attribute *foo_attrs[] = {
+ &bin_attr1.attr,
+ &bin_attr2.attr,
+ NULL
+ };
+ BIN_ATTRIBUTE_GROUPS(bin_foo);
+
+DEFINE_SYSFS_GROUP_COMBO_VISIBILITY(name):
+ A helper macro to pair with the assignment of
+
+ ".is_visible = SYSFS_GROUP_VISIBLE(name)",
+
+ that arranges for the directory associated with a named attribute_group
+ to optionally be hidden. This allows for static declaration of
+ attribute_groups, and the simplification of attribute visibility
+ lifetime that implies, without polluting sysfs with empty attribute
+ directories.
+
+Example::
+
+ static umode_t example_attr_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+ {
+ if (example_attr_condition)
+ return 0;
+ if (ro_attr_condition)
+ return 0444;
+ return a->mode;
+ }
+
+ static bool example_group_visible(struct kobject *kobj)
+ {
+ if (example_group_condition)
+ return false;
+ return true;
+ }
+
+ DEFINE_SYSFS_GROUP_COMBO_VISIBILITY(example);
+
+ static struct attribute_group example_group = {
+ .name = "example",
+ .is_visible = SYSFS_GROUP_VISIBLE(example),
+ .attrs = &example_attrs,
+ };
+
+Note that it expects <name>_attr_visible and <name>_group_visible to
+be defined. For cases where individual attributes do not need
+separate visibility consideration, only entire group visibility at
+once, see DEFINE_SYSFS_GROUP_VISIBILITY().
+
+DEFINE_SYSFS_GROUP_VISIBILITY(name):
+ A helper macro to pair with SYSFS_GROUP_VISIBLE() that, like
+ DEFINE_SYSFS_GROUP_COMBO_VISIBILITY(), controls group visibility, but
+ does not require the implementation of a per-attribute visibility
+ callback.
+
+Example::
+
+ static bool example_group_visible(struct kobject *kobj)
+ {
+ if (example_group_condition)
+ return false;
+ return true;
+ }
+
+ DEFINE_SYSFS_GROUP_VISIBILITY(example);
+
+ static struct attribute_group example_group = {
+ .name = "example",
+ .is_visible = SYSFS_GROUP_VISIBLE(example),
+ .attrs = &example_attrs,
+ };
+
+DEFINE_SYSFS_BIN_GROUP_COMBO_VISIBILITY(name):
+DEFINE_SYSFS_BIN_GROUP_VISIBILITY(name):
+ Same as DEFINE_SYSFS_GROUP_VISIBILITY(), but for groups with only binary
+ attributes. If an attribute_group defines both text and binary
+ attributes, the group visibility is determined by the function
+ specified to is_visible() not is_bin_visible().
+
+Named Attribute Group Macros (with visibility)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These macros define struct attribute_group objects with a static name and
+visibility function(s). They are useful for creating named directories in sysfs
+where individual attributes can be conditionally exposed.
+
+NAMED_ATTRIBUTE_GROUP_VISIBLE(name):
+ Defines an attribute group with a fixed directory name (matching name)
+ with a group visibility function. Expects an attribute array
+ <name>_attrs. The macro automatically defines the visibility function.
+
+Example::
+
+ static ssize_t foo_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+ {
+ ...
+ }
+
+ static ssize_t foo_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
+ ...
+ }
+ static DEVICE_ATTR_RW(foo);
+
+ static bool bar_group_visible(struct kobject *kobj)
+ {
+ if (bar_group_condition)
+ return false;
+ return true;
+ }
+
+ static struct attribute *bar_attrs[] = {
+ &dev_attr_foo.attr,
+ NULL
+ };
+ NAMED_ATTRIBUTE_GROUP_VISIBLE(bar);
+
+Creates::
+
+ static const struct attribute_group bar_group = {
+ .name = "bar",
+ .attrs = bar_attrs,
+ .is_visible = SYSFS_GROUP_VISIBLE(bar),
+ };
+
+ /*
+ * Where SYSFS_GROUP_VISIBLE(bar) is a function created by
+ * DEFINE_SYSFS_GROUP_VISIBILITY(bar) that calls bar_group_visible().
+ */
+
+NAMED_ATTRIBUTE_GROUPS_VISIBLE(name):
+ Like NAMED_ATTRIBUTE_GROUP_VISIBLE(), defines the visible attribute
+ group but also creates the group list <name>_groups[].
+
+Example::
+
+ ...
+
+ static struct attribute *bar_attrs[] = {
+ &attr1.attr,
+ &attr2.attr,
+ NULL
+ };
+ NAMED_ATTRIBUTE_GROUPS_VISIBLE(bar);
+
+Creates::
+
+ static const struct attribute_group bar_group = {
+ .name = "bar",
+ .attrs = bar_attrs,
+ .is_visible = SYSFS_GROUP_VISIBLE(bar),
+ };
+
+ static const struct attribute_group *bar_groups[] = {
+ &bar_group,
+ NULL
+ };
+
+NAMED_ATTRIBUTE_GROUP_COMBO_VISIBLE(name):
+ Same as NAMED_ATTRIBUTE_GROUP_VISIBLE(), but uses the "combo" visibility
+ variant to support both group and per-attribute visibility control.
+ Automatically generates the combo visibility boilerplate.
+
+Example::
+
+ static ssize_t foo_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+ {
+ ...
+ }
+
+ static ssize_t foo_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
+ ...
+ }
+ static DEVICE_ATTR_RW(foo);
+
+ static umode_t foo_attr_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+ {
+ if (example_attr_condition)
+ return 0;
+ return attr->mode;
+ }
+
+ static bool foo_group_visible(struct kobject *kobj)
+ {
+ if (foo_group_condition)
+ return false;
+ return true;
+ }
+
+ static struct attribute *foo_attrs[] = {
+ &dev_attr_foo.attr,
+ NULL
+ };
+ NAMED_ATTRIBUTE_GROUP_COMBO_VISIBLE(foo);
+
+Creates::
+
+ static const struct attribute_group foo_group = {
+ .name = "foo",
+ .attrs = foo_attrs,
+ .is_visible = SYSFS_GROUP_VISIBLE(foo),
+ };
+
+ /*
+ * Where SYSFS_GROUP_VISIBLE(foo) is a function created by
+ * DEFINE_SYSFS_GROUP_COMBO_VISIBILITY(foo) that calls foo_group_visible()
+ * and foo_attr_visible().
+ */
+
+NAMED_ATTRIBUTE_GROUPS_COMBO_VISIBLE(name):
+ Like NAMED_ATTRIBUTE_GROUP_COMBO_VISIBLE() defines the attribute group,
+ supporting both group and per-attribute visibility control, but also
+ creates the group list <name>_groups[].
Subsystem-Specific Callbacks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
2.43.0
Powered by blists - more mailing lists