[PATCH 2/4] base: add class device support

Sascha Hauer s.hauer at pengutronix.de
Mon Jun 10 01:12:11 PDT 2024


This introduces the concept of class devices in barebox. Class devices
group together devices of the same type. Several subsystems like
watchdog and network devices have a struct device embedded in their
subsystem specific struct anyway, so we can use this as a class device.
As these class devices are collected on a list we can use this list to
iterate over all network/watchdog devices and thus free the subsystems
from the burden of keeping a list themselves.

There is a 'class' command added in this patch which can be used to show
all registered classes along with the devices registered for each class.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 commands/Kconfig                  |  6 +++++
 commands/Makefile                 |  1 +
 commands/class.c                  | 30 ++++++++++++++++++++++
 drivers/base/Makefile             |  1 +
 drivers/base/class.c              | 41 +++++++++++++++++++++++++++++++
 include/asm-generic/barebox.lds.h |  7 ++++++
 include/device.h                  | 21 ++++++++++++++++
 7 files changed, 107 insertions(+)
 create mode 100644 commands/class.c
 create mode 100644 drivers/base/class.c

diff --git a/commands/Kconfig b/commands/Kconfig
index 899673bfee..7831e6276d 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -68,6 +68,12 @@ config CMD_BOOTROM
 
 	  bootrom [-la]
 
+config CMD_CLASS
+	tristate
+	prompt "class"
+	help
+	  Show information about registered classes and devices
+
 config CMD_DEVINFO
 	tristate
 	default y
diff --git a/commands/Makefile b/commands/Makefile
index 30e1f8403e..f65187703f 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -115,6 +115,7 @@ obj-$(CONFIG_CMD_BAREBOX_UPDATE)+= barebox-update.o
 obj-$(CONFIG_CMD_MIITOOL)	+= miitool.o
 obj-$(CONFIG_CMD_DETECT)	+= detect.o
 obj-$(CONFIG_CMD_BOOT)		+= boot.o
+obj-$(CONFIG_CMD_CLASS)		+= class.o
 obj-$(CONFIG_CMD_DEVINFO)	+= devinfo.o
 obj-$(CONFIG_CMD_DEVUNBIND)	+= devunbind.o
 obj-$(CONFIG_CMD_DEVLOOKUP)	+= devlookup.o
diff --git a/commands/class.c b/commands/class.c
new file mode 100644
index 0000000000..f5d67b012f
--- /dev/null
+++ b/commands/class.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <common.h>
+#include <command.h>
+#include <complete.h>
+
+static int do_class(int argc, char *argv[])
+{
+	struct class *class;
+	struct device *dev;
+
+	class_for_each(class) {
+		printf("%s:\n", class->name);
+		class_for_each_device(class, dev) {
+			printf("    %s\n", dev_name(dev));
+		}
+	}
+
+	return 0;
+}
+
+BAREBOX_CMD_HELP_START(class)
+BAREBOX_CMD_HELP_TEXT("Show information about registered classes and their devices")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(class)
+	.cmd = do_class,
+	BAREBOX_CMD_DESC("show information about classes")
+	BAREBOX_CMD_GROUP(CMD_GRP_INFO)
+	BAREBOX_CMD_COMPLETE(empty_complete)
+BAREBOX_CMD_END
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index acc53763da..94b677eea0 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -3,6 +3,7 @@ obj-y	+= bus.o
 obj-y	+= driver.o
 obj-y	+= platform.o
 obj-y	+= resource.o
+obj-y	+= class.o
 obj-y	+= regmap/
 
 obj-$(CONFIG_PM_GENERIC_DOMAINS) += power.o
diff --git a/drivers/base/class.c b/drivers/base/class.c
new file mode 100644
index 0000000000..6757d34140
--- /dev/null
+++ b/drivers/base/class.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <device.h>
+#include <driver.h>
+#include <linux/list.h>
+
+LIST_HEAD(class_list);
+
+static int class_register(struct class *class)
+{
+	list_add_tail(&class->list, &class_list);
+
+	return 0;
+}
+
+int class_add_device(struct class *class, struct device *dev)
+{
+	list_add_tail(&dev->class_list, &class->devices);
+
+	return 0;
+}
+
+void class_remove_device(struct class *class, struct device *dev)
+{
+	list_del(&class->devices);
+}
+
+extern struct class __barebox_class_start;
+extern struct class __barebox_class_end;
+
+static int register_classes(void)
+{
+	struct class *c;
+
+	for (c = &__barebox_class_start;
+	     c != &__barebox_class_end;
+	     c++)
+		class_register(c);
+
+	return 0;
+}
+device_initcall(register_classes);
diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
index d3736ebaed..8bbf5907cd 100644
--- a/include/asm-generic/barebox.lds.h
+++ b/include/asm-generic/barebox.lds.h
@@ -70,6 +70,12 @@
 	KEEP(*(SORT_BY_NAME(.barebox_magicvar*)))	\
 	__barebox_magicvar_end = .;
 
+#define BAREBOX_CLASSES				\
+	STRUCT_ALIGN();				\
+	__barebox_class_start = .;		\
+	KEEP(*(SORT_BY_NAME(.barebox_class*)))	\
+	__barebox_class_end = .;
+
 #define BAREBOX_CLK_TABLE			\
 	STRUCT_ALIGN();				\
 	__clk_of_table_start = .;		\
@@ -138,6 +144,7 @@
 	BAREBOX_SYMS				\
 	KERNEL_CTORS()				\
 	BAREBOX_MAGICVARS			\
+	BAREBOX_CLASSES				\
 	BAREBOX_CLK_TABLE			\
 	BAREBOX_DTB				\
 	BAREBOX_RSA_KEYS			\
diff --git a/include/device.h b/include/device.h
index ad1bc7ca1e..38eab6037e 100644
--- a/include/device.h
+++ b/include/device.h
@@ -76,6 +76,8 @@ struct device {
 
 	struct list_head cdevs;
 
+	struct list_head class_list;
+
 	const struct platform_device_id *id_entry;
 	union {
 		struct device_node *device_node;
@@ -102,6 +104,25 @@ struct device {
 	char *deferred_probe_reason;
 };
 
+struct class {
+	const char *name;
+	struct list_head devices;
+	struct list_head list;
+};
+
+#define DECLARE_CLASS(_name, _classname)					\
+	struct class _name __ll_elem(.barebox_class_##_name) = {		\
+		.name = _classname,						\
+		.devices = LIST_HEAD_INIT(_name.devices),			\
+	}
+
+int class_add_device(struct class *class, struct device *dev);
+void class_remove_device(struct class *class, struct device *dev);
+
+extern struct list_head class_list;
+#define class_for_each_device(class, dev) list_for_each_entry(dev, &class->devices, class_list)
+#define class_for_each(class) list_for_each_entry(class, &class_list, list)
+
 struct device_alias {
 	struct device *dev;
 	struct list_head list;
-- 
2.39.2




More information about the barebox mailing list