[PATCH 1/6] of: Add basic infrastructure to create early probe arrays

Marc Zyngier maz at kernel.org
Sat Sep 12 08:51:43 EDT 2020


We currently probe interrupt controller and timers that need
to be available very early using an infratstructure that creates
struct of_device_id instances in a special section. These are
individual structures that are ultimately collated by the linker.

In order to facilitate further use of this infrastructure for
drivers that can either be built modular or as an early driver,
let's add a couple of helpers that will make it look like a
"normal" device_id array, like this:

_OF_DECLARE_ARRAY_START(table, name)
_OF_DECLARE_ELMT("compat-1", probe, type)
_OF_DECLARE_ELMT("compat-2", probe, type)
_OF_DECLARE_ELMT("compat-3", other_probe, type)
_OF_DECLARE_ARRAY_END

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 include/linux/of.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/include/linux/of.h b/include/linux/of.h
index 5cf7ae0465d1..08f78da95378 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -1291,20 +1291,35 @@ static inline int of_get_available_child_count(const struct device_node *np)
 	return num;
 }
 
+#define __OF_DECLARE_ARRAY_START(name, section)				\
+	static const struct of_device_id __of_table_##name[]		\
+		__used __section(section) = {
+
 #if defined(CONFIG_OF) && !defined(MODULE)
 #define _OF_DECLARE(table, name, compat, fn, fn_type)			\
 	static const struct of_device_id __of_table_##name		\
 		__used __section(__##table##_of_table)			\
 		 = { .compatible = compat,				\
 		     .data = (fn == (fn_type)NULL) ? fn : fn  }
+#define _OF_DECLARE_ARRAY_START(table, name)				\
+	__OF_DECLARE_ARRAY_START(name, __##table##_of_table)
 #else
 #define _OF_DECLARE(table, name, compat, fn, fn_type)			\
 	static const struct of_device_id __of_table_##name		\
 		__attribute__((unused))					\
 		 = { .compatible = compat,				\
 		     .data = (fn == (fn_type)NULL) ? fn : fn }
+#define _OF_DECLARE_ARRAY_START(table, name)				\
+	__OF_DECLARE_ARRAY_START(name, unused)
 #endif
 
+#define _OF_DECLARE_ARRAY_END	}
+#define _OF_DECLARE_ELMT(compat, fn, fn_type)				\
+	{								\
+		.compatible = compat,					\
+		.data = (fn == (fn_type)NULL) ? fn : fn,		\
+	},
+
 typedef int (*of_init_fn_2)(struct device_node *, struct device_node *);
 typedef int (*of_init_fn_1_ret)(struct device_node *);
 typedef void (*of_init_fn_1)(struct device_node *);
-- 
2.28.0




More information about the linux-arm-kernel mailing list