All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hanjun Guo <hanjun.guo@linaro.org>
To: Marc Zyngier <marc.zyngier@arm.com>,
	Jason Cooper <jason@lakedaemon.net>,
	Will Deacon <will.deacon@arm.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	"Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Thomas Gleixner <tglx@linutronix.de>,
	Jiang Liu <jiang.liu@linux.intel.com>,
	Lorenzo Pieralisi <Lorenzo.Pieralisi@arm.com>,
	Arnd Bergmann <arnd@arndb.de>,
	Tomasz Nowicki <tomasz.nowicki@linaro.org>,
	Grant Likely <grant.likely@linaro.org>,
	Olof Johansson <olof@lixom.net>, Wei Huang <wei@redhat.com>,
	linux-arm-kernel@lists.infradead.org, linux-acpi@vger.kernel.org,
	linux-kernel@vger.kernel.org, linaro-acpi@lists.linaro.org,
	Hanjun Guo <hanjun.guo@linaro.org>
Subject: [PATCH v2 4/9] ACPI / irqchip: Add self-probe infrastructure to initialize IRQ controller
Date: Fri, 19 Jun 2015 16:46:07 +0800	[thread overview]
Message-ID: <1434703572-26221-5-git-send-email-hanjun.guo@linaro.org> (raw)
In-Reply-To: <1434703572-26221-1-git-send-email-hanjun.guo@linaro.org>

This self-probe infrastructure works in the similar way as OF,
but there is some different in the mechanism:

For DT, the init fn will be called once it finds compatible strings
in DT,  but for ACPI, we init irqchips by static tables, and in
static ACPI tables, there are no compatible strings to indicate
irqchips, but thanks to the GIC version presented in ACPI table,
we can call the corresponding GIC drivers matching the GIC version
with this framework.

This mechanism can also be used for clock declare and may also works
on x86 for some table parsing too.

Part of this patch is based on Tomasz Nowicki's work.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-acpi.c    | 29 +++++++++++++++++++++++++++++
 drivers/irqchip/irqchip.h         | 12 ++++++++++++
 include/asm-generic/vmlinux.lds.h | 13 +++++++++++++
 include/linux/acpi.h              | 16 ++++++++++++++++
 include/linux/mod_devicetable.h   |  8 ++++++++
 5 files changed, 78 insertions(+)

diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
index 58f7831..f9f1fc7 100644
--- a/drivers/irqchip/irq-gic-acpi.c
+++ b/drivers/irqchip/irq-gic-acpi.c
@@ -110,3 +110,32 @@ static int __init acpi_gic_version_init(void)
 
 	return 0;
 }
+
+/*
+ * This special acpi_table_id is the sentinel at the end of the
+ * acpi_table_id[] array of all irqchips. It is automatically placed at
+ * the end of the array by the linker, thanks to being part of a
+ * special section.
+ */
+static const struct acpi_table_id
+irqchip_acpi_match_end __used __section(__irqchip_acpi_table_end);
+
+extern struct acpi_table_id __irqchip_acpi_table[];
+
+void __init acpi_irqchip_init(void)
+{
+	struct acpi_table_id *id;
+
+	if (acpi_disabled)
+		return;
+
+	if (acpi_gic_version_init())
+		return;
+
+	/* scan the irqchip table to match the GIC version and its driver */
+	for (id = __irqchip_acpi_table; id->id[0]; id++) {
+		if (gic_version == (u8)id->driver_data)
+			acpi_table_parse(id->id,
+					 (acpi_tbl_table_handler)id->handler);
+	}
+}
diff --git a/drivers/irqchip/irqchip.h b/drivers/irqchip/irqchip.h
index 0f6486d..241d5f8 100644
--- a/drivers/irqchip/irqchip.h
+++ b/drivers/irqchip/irqchip.h
@@ -11,6 +11,7 @@
 #ifndef _IRQCHIP_H
 #define _IRQCHIP_H
 
+#include <linux/acpi.h>
 #include <linux/of.h>
 
 /*
@@ -25,4 +26,15 @@
  */
 #define IRQCHIP_DECLARE(name, compat, fn) OF_DECLARE_2(irqchip, name, compat, fn)
 
+/*
+ * This macro must be used by the different ARM GIC drivers to declare
+ * the association between their version and their initialization function.
+ *
+ * @name: name that must be unique accross all IRQCHIP_ACPI_DECLARE of the
+ * same file.
+ * @gic_version: version of GIC
+ * @fn: initialization function
+ */
+#define IRQCHIP_ACPI_DECLARE(name, gic_version, fn)	\
+	ACPI_DECLARE(irqchip, name, ACPI_SIG_MADT, gic_version, fn)
 #endif
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 8bd374d..625776c 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -181,6 +181,18 @@
 #define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method)
 #define EARLYCON_OF_TABLES()	OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon)
 
+#ifdef CONFIG_ACPI
+#define ACPI_TABLE(name)						\
+	. = ALIGN(8);							\
+	VMLINUX_SYMBOL(__##name##_acpi_table) = .;			\
+	*(__##name##_acpi_table)					\
+	*(__##name##_acpi_table_end)
+
+#define IRQCHIP_ACPI_MATCH_TABLE()	ACPI_TABLE(irqchip)
+#else
+#define IRQCHIP_ACPI_MATCH_TABLE()
+#endif
+
 #define KERNEL_DTB()							\
 	STRUCT_ALIGN();							\
 	VMLINUX_SYMBOL(__dtb_start) = .;				\
@@ -516,6 +528,7 @@
 	CPUIDLE_METHOD_OF_TABLES()					\
 	KERNEL_DTB()							\
 	IRQCHIP_OF_MATCH_TABLE()					\
+	IRQCHIP_ACPI_MATCH_TABLE()					\
 	EARLYCON_TABLE()						\
 	EARLYCON_OF_TABLES()
 
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index caead48..d383e12 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -825,4 +825,20 @@ static inline struct acpi_device *acpi_get_next_child(struct device *dev,
 
 #endif
 
+#ifdef CONFIG_ACPI
+#define ACPI_DECLARE(table, name, table_id, data, fn)			\
+	static const struct acpi_table_id __acpi_table_##name		\
+		__used __section(__##table##_acpi_table)		\
+		 = { .id = table_id,					\
+		     .handler = (void *)fn,				\
+		     .driver_data = data }
+#else
+#define ACPI_DECLARE(table, name, table_id, data, fn)			\
+	static const struct acpi_table_id __acpi_table_##name		\
+		__attribute__((unused))					\
+		 = { .id = table_id,					\
+		     .handler = (void *)fn,				\
+		     .driver_data = data }
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 3bfd567..c7fefc7 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -191,6 +191,14 @@ struct acpi_device_id {
 	kernel_ulong_t driver_data;
 };
 
+#define ACPI_TABLE_ID_LEN	5
+
+struct acpi_table_id {
+	__u8 id[ACPI_TABLE_ID_LEN];
+	const void *handler;
+	kernel_ulong_t driver_data;
+};
+
 #define PNP_ID_LEN	8
 #define PNP_MAX_DEVICES	8
 
-- 
1.9.1


WARNING: multiple messages have this Message-ID (diff)
From: hanjun.guo@linaro.org (Hanjun Guo)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 4/9] ACPI / irqchip: Add self-probe infrastructure to initialize IRQ controller
Date: Fri, 19 Jun 2015 16:46:07 +0800	[thread overview]
Message-ID: <1434703572-26221-5-git-send-email-hanjun.guo@linaro.org> (raw)
In-Reply-To: <1434703572-26221-1-git-send-email-hanjun.guo@linaro.org>

This self-probe infrastructure works in the similar way as OF,
but there is some different in the mechanism:

For DT, the init fn will be called once it finds compatible strings
in DT,  but for ACPI, we init irqchips by static tables, and in
static ACPI tables, there are no compatible strings to indicate
irqchips, but thanks to the GIC version presented in ACPI table,
we can call the corresponding GIC drivers matching the GIC version
with this framework.

This mechanism can also be used for clock declare and may also works
on x86 for some table parsing too.

Part of this patch is based on Tomasz Nowicki's work.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-acpi.c    | 29 +++++++++++++++++++++++++++++
 drivers/irqchip/irqchip.h         | 12 ++++++++++++
 include/asm-generic/vmlinux.lds.h | 13 +++++++++++++
 include/linux/acpi.h              | 16 ++++++++++++++++
 include/linux/mod_devicetable.h   |  8 ++++++++
 5 files changed, 78 insertions(+)

diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
index 58f7831..f9f1fc7 100644
--- a/drivers/irqchip/irq-gic-acpi.c
+++ b/drivers/irqchip/irq-gic-acpi.c
@@ -110,3 +110,32 @@ static int __init acpi_gic_version_init(void)
 
 	return 0;
 }
+
+/*
+ * This special acpi_table_id is the sentinel at the end of the
+ * acpi_table_id[] array of all irqchips. It is automatically placed at
+ * the end of the array by the linker, thanks to being part of a
+ * special section.
+ */
+static const struct acpi_table_id
+irqchip_acpi_match_end __used __section(__irqchip_acpi_table_end);
+
+extern struct acpi_table_id __irqchip_acpi_table[];
+
+void __init acpi_irqchip_init(void)
+{
+	struct acpi_table_id *id;
+
+	if (acpi_disabled)
+		return;
+
+	if (acpi_gic_version_init())
+		return;
+
+	/* scan the irqchip table to match the GIC version and its driver */
+	for (id = __irqchip_acpi_table; id->id[0]; id++) {
+		if (gic_version == (u8)id->driver_data)
+			acpi_table_parse(id->id,
+					 (acpi_tbl_table_handler)id->handler);
+	}
+}
diff --git a/drivers/irqchip/irqchip.h b/drivers/irqchip/irqchip.h
index 0f6486d..241d5f8 100644
--- a/drivers/irqchip/irqchip.h
+++ b/drivers/irqchip/irqchip.h
@@ -11,6 +11,7 @@
 #ifndef _IRQCHIP_H
 #define _IRQCHIP_H
 
+#include <linux/acpi.h>
 #include <linux/of.h>
 
 /*
@@ -25,4 +26,15 @@
  */
 #define IRQCHIP_DECLARE(name, compat, fn) OF_DECLARE_2(irqchip, name, compat, fn)
 
+/*
+ * This macro must be used by the different ARM GIC drivers to declare
+ * the association between their version and their initialization function.
+ *
+ * @name: name that must be unique accross all IRQCHIP_ACPI_DECLARE of the
+ * same file.
+ * @gic_version: version of GIC
+ * @fn: initialization function
+ */
+#define IRQCHIP_ACPI_DECLARE(name, gic_version, fn)	\
+	ACPI_DECLARE(irqchip, name, ACPI_SIG_MADT, gic_version, fn)
 #endif
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 8bd374d..625776c 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -181,6 +181,18 @@
 #define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method)
 #define EARLYCON_OF_TABLES()	OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon)
 
+#ifdef CONFIG_ACPI
+#define ACPI_TABLE(name)						\
+	. = ALIGN(8);							\
+	VMLINUX_SYMBOL(__##name##_acpi_table) = .;			\
+	*(__##name##_acpi_table)					\
+	*(__##name##_acpi_table_end)
+
+#define IRQCHIP_ACPI_MATCH_TABLE()	ACPI_TABLE(irqchip)
+#else
+#define IRQCHIP_ACPI_MATCH_TABLE()
+#endif
+
 #define KERNEL_DTB()							\
 	STRUCT_ALIGN();							\
 	VMLINUX_SYMBOL(__dtb_start) = .;				\
@@ -516,6 +528,7 @@
 	CPUIDLE_METHOD_OF_TABLES()					\
 	KERNEL_DTB()							\
 	IRQCHIP_OF_MATCH_TABLE()					\
+	IRQCHIP_ACPI_MATCH_TABLE()					\
 	EARLYCON_TABLE()						\
 	EARLYCON_OF_TABLES()
 
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index caead48..d383e12 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -825,4 +825,20 @@ static inline struct acpi_device *acpi_get_next_child(struct device *dev,
 
 #endif
 
+#ifdef CONFIG_ACPI
+#define ACPI_DECLARE(table, name, table_id, data, fn)			\
+	static const struct acpi_table_id __acpi_table_##name		\
+		__used __section(__##table##_acpi_table)		\
+		 = { .id = table_id,					\
+		     .handler = (void *)fn,				\
+		     .driver_data = data }
+#else
+#define ACPI_DECLARE(table, name, table_id, data, fn)			\
+	static const struct acpi_table_id __acpi_table_##name		\
+		__attribute__((unused))					\
+		 = { .id = table_id,					\
+		     .handler = (void *)fn,				\
+		     .driver_data = data }
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 3bfd567..c7fefc7 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -191,6 +191,14 @@ struct acpi_device_id {
 	kernel_ulong_t driver_data;
 };
 
+#define ACPI_TABLE_ID_LEN	5
+
+struct acpi_table_id {
+	__u8 id[ACPI_TABLE_ID_LEN];
+	const void *handler;
+	kernel_ulong_t driver_data;
+};
+
 #define PNP_ID_LEN	8
 #define PNP_MAX_DEVICES	8
 
-- 
1.9.1

  parent reply	other threads:[~2015-06-19  8:46 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-19  8:46 [PATCH v2 0/9] Add self-probe infrastructure and stacked irqdomain support for ACPI based GICv2/3 init Hanjun Guo
2015-06-19  8:46 ` Hanjun Guo
2015-06-19  8:46 ` [PATCH v2 1/9] ACPICA: ACPI 6.0: Add changes for MADT table Hanjun Guo
2015-06-19  8:46   ` Hanjun Guo
2015-06-19  8:46 ` [PATCH v2 2/9] ACPICA: ACPI 6.0: Add values for MADT GIC version field Hanjun Guo
2015-06-19  8:46   ` Hanjun Guo
2015-06-19  8:46 ` [PATCH v2 3/9] irqchip / GIC: Add GIC version support in ACPI MADT Hanjun Guo
2015-06-19  8:46   ` Hanjun Guo
2015-06-22 16:45   ` Lorenzo Pieralisi
2015-06-22 16:45     ` Lorenzo Pieralisi
2015-06-22 16:45     ` Lorenzo Pieralisi
2015-06-23 11:18     ` Hanjun Guo
2015-06-23 11:18       ` Hanjun Guo
2015-06-23 11:18       ` Hanjun Guo
2015-06-27  6:07     ` Hanjun Guo
2015-06-27  6:07       ` Hanjun Guo
2015-06-27  6:07       ` Hanjun Guo
2015-06-19  8:46 ` Hanjun Guo [this message]
2015-06-19  8:46   ` [PATCH v2 4/9] ACPI / irqchip: Add self-probe infrastructure to initialize IRQ controller Hanjun Guo
2015-06-19  8:46 ` [PATCH v2 5/9] irqchip / GIC / ACPI: Use IRQCHIP_ACPI_DECLARE to simplify GICv2 init code Hanjun Guo
2015-06-19  8:46   ` Hanjun Guo
2015-06-19  8:46 ` [PATCH v2 6/9] irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init Hanjun Guo
2015-06-19  8:46   ` Hanjun Guo
2015-06-22 17:20   ` Lorenzo Pieralisi
2015-06-22 17:20     ` Lorenzo Pieralisi
2015-06-22 17:20     ` Lorenzo Pieralisi
2015-06-23 15:11     ` Hanjun Guo
2015-06-23 15:11       ` Hanjun Guo
2015-06-23 15:11       ` Hanjun Guo
2015-06-23 17:38       ` Lorenzo Pieralisi
2015-06-23 17:38         ` Lorenzo Pieralisi
2015-06-23 17:38         ` Lorenzo Pieralisi
2015-06-27  3:52         ` Hanjun Guo
2015-06-27  3:52           ` Hanjun Guo
2015-06-27  3:52           ` Hanjun Guo
2015-06-29  8:39           ` Marc Zyngier
2015-06-29  8:39             ` Marc Zyngier
2015-06-29  8:39             ` Marc Zyngier
2015-06-30 11:50             ` Hanjun Guo
2015-06-30 11:50               ` Hanjun Guo
2015-06-30 11:50               ` Hanjun Guo
2015-06-30 12:17               ` Marc Zyngier
2015-06-30 12:17                 ` Marc Zyngier
2015-06-30 12:17                 ` Marc Zyngier
2015-06-30 15:07                 ` Graeme Gregory
2015-06-30 15:07                   ` Graeme Gregory
2015-06-30 15:07                   ` Graeme Gregory
2015-07-03  8:47                   ` Hanjun Guo
2015-07-03  8:47                     ` Hanjun Guo
2015-07-03  8:47                     ` Hanjun Guo
2015-07-08  3:40                 ` Hanjun Guo
2015-07-08  3:40                   ` Hanjun Guo
2015-07-08  3:40                   ` Hanjun Guo
2015-07-10  9:41                   ` Marc Zyngier
2015-07-10  9:41                     ` Marc Zyngier
2015-07-10  9:41                     ` Marc Zyngier
2015-06-19  8:46 ` [PATCH v2 7/9] irqchip / GICv3: Refactor gic_of_init() for GICv3 driver Hanjun Guo
2015-06-19  8:46   ` Hanjun Guo
2015-06-19  8:46 ` [PATCH v2 8/9] irqchip / GICv3: Add ACPI support for GICv3+ initialization Hanjun Guo
2015-06-19  8:46   ` Hanjun Guo
2015-06-19  8:46 ` [PATCH v2 9/9] irqchip / GICv3: Add stacked irqdomain support for ACPI based init Hanjun Guo
2015-06-19  8:46   ` Hanjun Guo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1434703572-26221-5-git-send-email-hanjun.guo@linaro.org \
    --to=hanjun.guo@linaro.org \
    --cc=Lorenzo.Pieralisi@arm.com \
    --cc=arnd@arndb.de \
    --cc=catalin.marinas@arm.com \
    --cc=grant.likely@linaro.org \
    --cc=jason@lakedaemon.net \
    --cc=jiang.liu@linux.intel.com \
    --cc=linaro-acpi@lists.linaro.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marc.zyngier@arm.com \
    --cc=olof@lixom.net \
    --cc=rjw@rjwysocki.net \
    --cc=tglx@linutronix.de \
    --cc=tomasz.nowicki@linaro.org \
    --cc=wei@redhat.com \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.