All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/11] Add self-probe infrastructure and stacked irqdomain support for ACPI based GICv2/3 init
@ 2015-05-18 12:59 ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	Grant Likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi, Hanjun Guo

This patch set introduce self-probe infrastructure to init IRQ
controllers and stacked irqdomain support for ACPI based GICv2/3
init.

The self-probe infrastructure for ACPI GIC init is similar as
IRQCHIP_DECLARE() and based on the GIC version support in ACPI
MADT table.

We introduce acpi_irq_domain for GICv2/3 core domain to support
stacked irqdomain, and pass the gsi (global system interrupt) as
the agument (void *arg) for gic_irq_domain_alloc(), then we can
alloc virqs via acpi_register_gsi() with stacked irqdomain.

In order to make ACPI related GIC init code slef-contained, I
consolidated all the GIC init code into drivers/irqchip/irq-gic-acpi.c.

update from RFC version:
 - Consolidate all the GIC init code into drivers/irqchip/irq-gic-acpi.c

Hanjun Guo (8):
  irqchip / GIC: Add GIC version support in ACPI MADT
  irqchip / GIC / ACPI: Use IRQCHIP_ACPI_DECLARE to simplify GICv2 init
    code
  irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
  ACPI / gsi: Add gsi_mutex to synchronize
    acpi_register_gsi()/acpi_unregister_gsi()
  irqchip / GICv3: Add ACPI support for GICv3+ initialization
  irqchip / GICv3: Add stacked irqdomain support for ACPI based init
  irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
  irqchip / GICv3 / ACPI: Consolidate GICv3 ACPI related init code

Tomasz Nowicki (3):
  ACPICA: Introduce GIC version for arm based system
  ACPI / irqchip: Add self-probe infrastructure to initialize IRQ
    controller
  irqchip / GICv3: Refactor gic_of_init() for GICv3 driver

 arch/arm64/Kconfig                   |   1 +
 arch/arm64/include/asm/irq.h         |  13 --
 arch/arm64/kernel/acpi.c             |  25 ---
 drivers/acpi/Makefile                |   1 +
 drivers/acpi/gsi.c                   |  41 +++--
 drivers/acpi/irq.c                   |  40 +++++
 drivers/irqchip/Kconfig              |   3 +
 drivers/irqchip/Makefile             |   1 +
 drivers/irqchip/irq-gic-acpi.c       | 318 +++++++++++++++++++++++++++++++++++
 drivers/irqchip/irq-gic-v3.c         | 149 +++++++++-------
 drivers/irqchip/irq-gic.c            | 129 ++------------
 drivers/irqchip/irqchip.h            |  12 ++
 include/acpi/actbl1.h                |  17 +-
 include/asm-generic/vmlinux.lds.h    |  13 ++
 include/linux/acpi.h                 |  14 ++
 include/linux/acpi_irq.h             |   4 +-
 include/linux/irqchip/arm-gic-acpi.h |  13 +-
 include/linux/irqchip/arm-gic-v3.h   |  10 ++
 include/linux/mod_devicetable.h      |   7 +
 19 files changed, 577 insertions(+), 234 deletions(-)
 create mode 100644 drivers/acpi/irq.c
 create mode 100644 drivers/irqchip/irq-gic-acpi.c

-- 
1.9.1


^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 00/11] Add self-probe infrastructure and stacked irqdomain support for ACPI based GICv2/3 init
@ 2015-05-18 12:59 ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

This patch set introduce self-probe infrastructure to init IRQ
controllers and stacked irqdomain support for ACPI based GICv2/3
init.

The self-probe infrastructure for ACPI GIC init is similar as
IRQCHIP_DECLARE() and based on the GIC version support in ACPI
MADT table.

We introduce acpi_irq_domain for GICv2/3 core domain to support
stacked irqdomain, and pass the gsi (global system interrupt) as
the agument (void *arg) for gic_irq_domain_alloc(), then we can
alloc virqs via acpi_register_gsi() with stacked irqdomain.

In order to make ACPI related GIC init code slef-contained, I
consolidated all the GIC init code into drivers/irqchip/irq-gic-acpi.c.

update from RFC version:
 - Consolidate all the GIC init code into drivers/irqchip/irq-gic-acpi.c

Hanjun Guo (8):
  irqchip / GIC: Add GIC version support in ACPI MADT
  irqchip / GIC / ACPI: Use IRQCHIP_ACPI_DECLARE to simplify GICv2 init
    code
  irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
  ACPI / gsi: Add gsi_mutex to synchronize
    acpi_register_gsi()/acpi_unregister_gsi()
  irqchip / GICv3: Add ACPI support for GICv3+ initialization
  irqchip / GICv3: Add stacked irqdomain support for ACPI based init
  irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
  irqchip / GICv3 / ACPI: Consolidate GICv3 ACPI related init code

Tomasz Nowicki (3):
  ACPICA: Introduce GIC version for arm based system
  ACPI / irqchip: Add self-probe infrastructure to initialize IRQ
    controller
  irqchip / GICv3: Refactor gic_of_init() for GICv3 driver

 arch/arm64/Kconfig                   |   1 +
 arch/arm64/include/asm/irq.h         |  13 --
 arch/arm64/kernel/acpi.c             |  25 ---
 drivers/acpi/Makefile                |   1 +
 drivers/acpi/gsi.c                   |  41 +++--
 drivers/acpi/irq.c                   |  40 +++++
 drivers/irqchip/Kconfig              |   3 +
 drivers/irqchip/Makefile             |   1 +
 drivers/irqchip/irq-gic-acpi.c       | 318 +++++++++++++++++++++++++++++++++++
 drivers/irqchip/irq-gic-v3.c         | 149 +++++++++-------
 drivers/irqchip/irq-gic.c            | 129 ++------------
 drivers/irqchip/irqchip.h            |  12 ++
 include/acpi/actbl1.h                |  17 +-
 include/asm-generic/vmlinux.lds.h    |  13 ++
 include/linux/acpi.h                 |  14 ++
 include/linux/acpi_irq.h             |   4 +-
 include/linux/irqchip/arm-gic-acpi.h |  13 +-
 include/linux/irqchip/arm-gic-v3.h   |  10 ++
 include/linux/mod_devicetable.h      |   7 +
 19 files changed, 577 insertions(+), 234 deletions(-)
 create mode 100644 drivers/acpi/irq.c
 create mode 100644 drivers/irqchip/irq-gic-acpi.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 01/11] ACPICA: Introduce GIC version for arm based system
  2015-05-18 12:59 ` Hanjun Guo
@ 2015-05-18 12:59   ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	Grant Likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi, Hanjun Guo

From: Tomasz Nowicki <tomasz.nowicki@linaro.org>

A new field is added in GIC distributor to indication
the GIC version, support it in ACPICA for later use

Will upstreamed by Lv Zheng after ACPICA supporting
ACPI 6.0 is released.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 include/acpi/actbl1.h | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index b80b0e6..b4f0f74 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -819,7 +819,7 @@ struct acpi_madt_generic_interrupt {
 #define ACPI_MADT_PERFORMANCE_IRQ_MODE  (1<<1)	/* 01: Performance Interrupt Mode */
 #define ACPI_MADT_VGIC_IRQ_MODE         (1<<2)	/* 02: VGIC Maintenance Interrupt mode */
 
-/* 12: Generic Distributor (ACPI 5.0) */
+/* 12: Generic Distributor (ACPI 6.0) */
 
 struct acpi_madt_generic_distributor {
 	struct acpi_subtable_header header;
@@ -827,7 +827,20 @@ struct acpi_madt_generic_distributor {
 	u32 gic_id;
 	u64 base_address;
 	u32 global_irq_base;
-	u32 reserved2;		/* reserved - must be zero */
+	u8  gic_version;
+	u8  reserved2[3];	/* reserved - must be zero */
+};
+
+/* Values for gic_version in Generic Distributor  (ACPI 6.0) */
+
+enum acpi_madt_gic_ver_type
+{
+	ACPI_MADT_GIC_VER_UNKNOWN	= 0,
+	ACPI_MADT_GIC_VER_V1		= 1,
+	ACPI_MADT_GIC_VER_V2		= 2,
+	ACPI_MADT_GIC_VER_V3		= 3,
+	ACPI_MADT_GIC_VER_V4		= 4,
+	ACPI_MADT_GIC_VER_RESERVED	= 5	/* 5 and greater are reserved */
 };
 
 /* 13: Generic MSI Frame (ACPI 5.1) */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 01/11] ACPICA: Introduce GIC version for arm based system
@ 2015-05-18 12:59   ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tomasz Nowicki <tomasz.nowicki@linaro.org>

A new field is added in GIC distributor to indication
the GIC version, support it in ACPICA for later use

Will upstreamed by Lv Zheng after ACPICA supporting
ACPI 6.0 is released.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 include/acpi/actbl1.h | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index b80b0e6..b4f0f74 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -819,7 +819,7 @@ struct acpi_madt_generic_interrupt {
 #define ACPI_MADT_PERFORMANCE_IRQ_MODE  (1<<1)	/* 01: Performance Interrupt Mode */
 #define ACPI_MADT_VGIC_IRQ_MODE         (1<<2)	/* 02: VGIC Maintenance Interrupt mode */
 
-/* 12: Generic Distributor (ACPI 5.0) */
+/* 12: Generic Distributor (ACPI 6.0) */
 
 struct acpi_madt_generic_distributor {
 	struct acpi_subtable_header header;
@@ -827,7 +827,20 @@ struct acpi_madt_generic_distributor {
 	u32 gic_id;
 	u64 base_address;
 	u32 global_irq_base;
-	u32 reserved2;		/* reserved - must be zero */
+	u8  gic_version;
+	u8  reserved2[3];	/* reserved - must be zero */
+};
+
+/* Values for gic_version in Generic Distributor  (ACPI 6.0) */
+
+enum acpi_madt_gic_ver_type
+{
+	ACPI_MADT_GIC_VER_UNKNOWN	= 0,
+	ACPI_MADT_GIC_VER_V1		= 1,
+	ACPI_MADT_GIC_VER_V2		= 2,
+	ACPI_MADT_GIC_VER_V3		= 3,
+	ACPI_MADT_GIC_VER_V4		= 4,
+	ACPI_MADT_GIC_VER_RESERVED	= 5	/* 5 and greater are reserved */
 };
 
 /* 13: Generic MSI Frame (ACPI 5.1) */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 02/11] ACPI / irqchip: Add self-probe infrastructure to initialize IRQ controller
  2015-05-18 12:59 ` Hanjun Guo
@ 2015-05-18 12:59   ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	Grant Likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi, Hanjun Guo

From: Tomasz Nowicki <tomasz.nowicki@linaro.org>

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

For OF, the init fn will be called once it finds comptiable strings
in DT,  but for ACPI, we init irqchips by static tables, and in
static ACPI tables, there are no comptiable strings to indicate
irqchips, so every init function with IRQCHIP_ACPI_DECLARE in the
same table will be called, but thanks to the GIC version presented
in ACPI table, we can init different GIC irqchips with this framework.

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

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
[hj: introduce struct acpi_table_id instead of acpi_device_id]
[hj: rework it more generic to all ACPI tables and fix some issues]
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/Makefile             |  1 +
 drivers/acpi/irq.c                | 37 +++++++++++++++++++++++++++++++++++++
 drivers/irqchip/irqchip.h         | 12 ++++++++++++
 include/asm-generic/vmlinux.lds.h | 13 +++++++++++++
 include/linux/acpi.h              | 14 ++++++++++++++
 include/linux/mod_devicetable.h   |  7 +++++++
 6 files changed, 84 insertions(+)
 create mode 100644 drivers/acpi/irq.c

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 8a063e2..3e4aec3 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -80,6 +80,7 @@ obj-$(CONFIG_ACPI_HED)		+= hed.o
 obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
+obj-$(CONFIG_IRQCHIP)		+= irq.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o processor_throttling.o
diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
new file mode 100644
index 0000000..65d6b93
--- /dev/null
+++ b/drivers/acpi/irq.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015, Linaro Ltd.
+ * Author: Tomasz Nowicki <tomasz.nowicki@linaro.org>
+ *         Hanjun Guo <hanjun.guo@linaro.org>
+ *
+ * Inspired by drivers/irqchip/irqchip.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/acpi.h>
+
+/*
+ * 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;
+
+	for (id = __irqchip_acpi_table; id->id[0]; id++)
+		acpi_table_parse(id->id, (acpi_tbl_table_handler)id->data);
+}
diff --git a/drivers/irqchip/irqchip.h b/drivers/irqchip/irqchip.h
index 0f6486d..1949546 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 irqchip drivers to declare
+ * the association between their ACPI table and their initialization function.
+ *
+ * @name: name that must be unique accross all IRQCHIP_ACPI_DECLARE of the
+ * same file.
+ * @table_id: name of the ACPI table signature
+ * @fn: initialization function
+ */
+#define IRQCHIP_ACPI_DECLARE(name, table_id, fn)	\
+	ACPI_DECLARE(irqchip, name, table_id, 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 90e4ed1e..b904af3 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -820,4 +820,18 @@ static inline struct acpi_device *acpi_get_next_child(struct device *dev,
 
 #endif
 
+#ifdef CONFIG_ACPI
+#define ACPI_DECLARE(table, name, table_id, fn)				\
+	static const struct acpi_table_id __acpi_table_##name		\
+		__used __section(__##table##_acpi_table)		\
+		 = { .id = table_id,					\
+		     .data = (void *)fn }
+#else
+#define ACPI_DECLARE(table, name, table_id, fn)				\
+	static const struct acpi_table_id __acpi_table_##name		\
+		__attribute__((unused))					\
+		 = { .id = table_id,					\
+		     .data = (void*)fn }
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 3bfd567..47c1ea1 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -199,6 +199,13 @@ struct pnp_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 *data;
+};
+
 struct pnp_card_device_id {
 	__u8 id[PNP_ID_LEN];
 	kernel_ulong_t driver_data;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 02/11] ACPI / irqchip: Add self-probe infrastructure to initialize IRQ controller
@ 2015-05-18 12:59   ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tomasz Nowicki <tomasz.nowicki@linaro.org>

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

For OF, the init fn will be called once it finds comptiable strings
in DT,  but for ACPI, we init irqchips by static tables, and in
static ACPI tables, there are no comptiable strings to indicate
irqchips, so every init function with IRQCHIP_ACPI_DECLARE in the
same table will be called, but thanks to the GIC version presented
in ACPI table, we can init different GIC irqchips with this framework.

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

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
[hj: introduce struct acpi_table_id instead of acpi_device_id]
[hj: rework it more generic to all ACPI tables and fix some issues]
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/Makefile             |  1 +
 drivers/acpi/irq.c                | 37 +++++++++++++++++++++++++++++++++++++
 drivers/irqchip/irqchip.h         | 12 ++++++++++++
 include/asm-generic/vmlinux.lds.h | 13 +++++++++++++
 include/linux/acpi.h              | 14 ++++++++++++++
 include/linux/mod_devicetable.h   |  7 +++++++
 6 files changed, 84 insertions(+)
 create mode 100644 drivers/acpi/irq.c

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 8a063e2..3e4aec3 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -80,6 +80,7 @@ obj-$(CONFIG_ACPI_HED)		+= hed.o
 obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
+obj-$(CONFIG_IRQCHIP)		+= irq.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o processor_throttling.o
diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
new file mode 100644
index 0000000..65d6b93
--- /dev/null
+++ b/drivers/acpi/irq.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015, Linaro Ltd.
+ * Author: Tomasz Nowicki <tomasz.nowicki@linaro.org>
+ *         Hanjun Guo <hanjun.guo@linaro.org>
+ *
+ * Inspired by drivers/irqchip/irqchip.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/acpi.h>
+
+/*
+ * 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;
+
+	for (id = __irqchip_acpi_table; id->id[0]; id++)
+		acpi_table_parse(id->id, (acpi_tbl_table_handler)id->data);
+}
diff --git a/drivers/irqchip/irqchip.h b/drivers/irqchip/irqchip.h
index 0f6486d..1949546 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 irqchip drivers to declare
+ * the association between their ACPI table and their initialization function.
+ *
+ * @name: name that must be unique accross all IRQCHIP_ACPI_DECLARE of the
+ * same file.
+ * @table_id: name of the ACPI table signature
+ * @fn: initialization function
+ */
+#define IRQCHIP_ACPI_DECLARE(name, table_id, fn)	\
+	ACPI_DECLARE(irqchip, name, table_id, 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 90e4ed1e..b904af3 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -820,4 +820,18 @@ static inline struct acpi_device *acpi_get_next_child(struct device *dev,
 
 #endif
 
+#ifdef CONFIG_ACPI
+#define ACPI_DECLARE(table, name, table_id, fn)				\
+	static const struct acpi_table_id __acpi_table_##name		\
+		__used __section(__##table##_acpi_table)		\
+		 = { .id = table_id,					\
+		     .data = (void *)fn }
+#else
+#define ACPI_DECLARE(table, name, table_id, fn)				\
+	static const struct acpi_table_id __acpi_table_##name		\
+		__attribute__((unused))					\
+		 = { .id = table_id,					\
+		     .data = (void*)fn }
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 3bfd567..47c1ea1 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -199,6 +199,13 @@ struct pnp_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 *data;
+};
+
 struct pnp_card_device_id {
 	__u8 id[PNP_ID_LEN];
 	kernel_ulong_t driver_data;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 03/11] irqchip / GIC: Add GIC version support in ACPI MADT
  2015-05-18 12:59 ` Hanjun Guo
@ 2015-05-18 12:59   ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	Grant Likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi, Hanjun Guo

There is a field added in ACPI MADT table to indicate the
GIC version, so parse the table to get its value for later
use.

If GIC version presented in MADT is 0, we need to fallback
to hardware discovery to get the GIC version.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/Kconfig                   |   1 +
 drivers/acpi/irq.c                   |   3 +
 drivers/irqchip/Kconfig              |   3 +
 drivers/irqchip/Makefile             |   1 +
 drivers/irqchip/irq-gic-acpi.c       | 111 +++++++++++++++++++++++++++++++++++
 include/linux/irqchip/arm-gic-acpi.h |   2 +
 6 files changed, 121 insertions(+)
 create mode 100644 drivers/irqchip/irq-gic-acpi.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7796af4..9b80428 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -15,6 +15,7 @@ config ARM64
 	select ARM_AMBA
 	select ARM_ARCH_TIMER
 	select ARM_GIC
+	select ARM_GIC_ACPI if ACPI
 	select AUDIT_ARCH_COMPAT_GENERIC
 	select ARM_GIC_V2M if PCI_MSI
 	select ARM_GIC_V3
diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
index 65d6b93..855ead9 100644
--- a/drivers/acpi/irq.c
+++ b/drivers/acpi/irq.c
@@ -32,6 +32,9 @@ void __init acpi_irqchip_init(void)
 	if (acpi_disabled)
 		return;
 
+	if (acpi_gic_version_init())
+		return;
+
 	for (id = __irqchip_acpi_table; id->id[0]; id++)
 		acpi_table_parse(id->id, (acpi_tbl_table_handler)id->data);
 }
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 6de62a9..0dd64c5 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -46,6 +46,9 @@ config ARM_VIC_NR
 	  The maximum number of VICs available in the system, for
 	  power management.
 
+config ARM_GIC_ACPI
+	bool
+
 config ATMEL_AIC_IRQ
 	bool
 	select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index dda4927..0bd8e49 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_ARM_GIC)			+= irq-gic.o irq-gic-common.o
 obj-$(CONFIG_ARM_GIC_V2M)		+= irq-gic-v2m.o
 obj-$(CONFIG_ARM_GIC_V3)		+= irq-gic-v3.o irq-gic-common.o
 obj-$(CONFIG_ARM_GIC_V3_ITS)		+= irq-gic-v3-its.o
+obj-$(CONFIG_ARM_GIC_ACPI)		+= irq-gic-acpi.o
 obj-$(CONFIG_ARM_NVIC)			+= irq-nvic.o
 obj-$(CONFIG_ARM_VIC)			+= irq-vic.o
 obj-$(CONFIG_ATMEL_AIC_IRQ)		+= irq-atmel-aic-common.o irq-atmel-aic.o
diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
new file mode 100644
index 0000000..53a86ef
--- /dev/null
+++ b/drivers/irqchip/irq-gic-acpi.c
@@ -0,0 +1,111 @@
+/*
+ * ACPI based support for ARM GIC init
+ *
+ * Copyright (C) 2015, Linaro Ltd.
+ * Author: Hanjun Guo <hanjun.guo@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt) "ACPI: GIC: " fmt
+
+#include <linux/acpi.h>
+#include <linux/init.h>
+#include <linux/irqchip/arm-gic-acpi.h>
+#include <linux/irqchip/arm-gic-v3.h>
+
+/* GIC version presented in MADT GIC distributor structure */
+static u8 gic_version __initdata = ACPI_MADT_GIC_VER_UNKNOWN;
+
+static phys_addr_t dist_phy_base __initdata;
+
+static int __init
+acpi_gic_parse_distributor(struct acpi_subtable_header *header,
+				const unsigned long end)
+{
+	struct acpi_madt_generic_distributor *dist;
+
+	dist = (struct acpi_madt_generic_distributor *)header;
+
+	if (BAD_MADT_ENTRY(dist, end))
+		return -EINVAL;
+
+	gic_version = dist->gic_version;
+	dist_phy_base = dist->base_address;
+	return 0;
+}
+
+static int __init
+match_gic_redist(struct acpi_subtable_header *header, const unsigned long end)
+{
+	return 0;
+}
+
+static bool __init acpi_gic_redist_is_present(void)
+{
+	int count;
+
+	/* scan MADT table to find if we have redistributor entries */
+	count  =  acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
+					match_gic_redist, 0);
+
+	/* has at least one GIC redistributor entry */
+	if (count > 0)
+		return true;
+	else
+		return false;
+}
+
+int __init acpi_gic_version_init(void)
+{
+	int count;
+	void __iomem *dist_base;
+	u32 reg;
+
+	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+					acpi_gic_parse_distributor, 0);
+
+	if (count <= 0) {
+		pr_err("No valid GIC distributor entry exists\n");
+		return -ENODEV;
+	}
+
+	if (gic_version >= ACPI_MADT_GIC_VER_RESERVED) {
+		pr_err("Invalid GIC version %d in MADT\n", gic_version);
+		return -EINVAL;
+	}
+
+	/*
+	 * when the GIC version is 0, we fallback to hardware discovery.
+	 * this is also needed to keep compatiable with ACPI 5.1,
+	 * which has no gic_version field in distributor structure and
+	 * reserved as 0.
+	 *
+	 * For hardware discovery, the offset for GICv1/2 and GICv3/4 to
+	 * get the GIC version is different (0xFE8 for GICv1/2 and 0xFFE8
+	 * for GICv3/4), so we need to handle it separately.
+	 */
+	if (gic_version	== ACPI_MADT_GIC_VER_UNKNOWN) {
+		/* it's GICv3/v4 if redistributor is present */
+		if (acpi_gic_redist_is_present()) {
+			dist_base = ioremap(dist_phy_base,
+						ACPI_GICV3_DIST_MEM_SIZE);
+			if (!dist_base)
+				return -ENOMEM;
+
+			reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
+			if (reg == GIC_PIDR2_ARCH_GICv3)
+				gic_version = ACPI_MADT_GIC_VER_V3;
+			else
+				gic_version = ACPI_MADT_GIC_VER_V4;
+
+			iounmap(dist_base);
+		} else {
+			gic_version = ACPI_MADT_GIC_VER_V2;
+		}
+	}
+
+	return 0;
+}
diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
index de3419e..0d5f204 100644
--- a/include/linux/irqchip/arm-gic-acpi.h
+++ b/include/linux/irqchip/arm-gic-acpi.h
@@ -19,11 +19,13 @@
  */
 #define ACPI_GICV2_DIST_MEM_SIZE	(SZ_4K)
 #define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)
+#define ACPI_GICV3_DIST_MEM_SIZE	(SZ_64K)
 
 struct acpi_table_header;
 
 int gic_v2_acpi_init(struct acpi_table_header *table);
 void acpi_gic_init(void);
+int acpi_gic_version_init(void);
 #else
 static inline void acpi_gic_init(void) { }
 #endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 03/11] irqchip / GIC: Add GIC version support in ACPI MADT
@ 2015-05-18 12:59   ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

There is a field added in ACPI MADT table to indicate the
GIC version, so parse the table to get its value for later
use.

If GIC version presented in MADT is 0, we need to fallback
to hardware discovery to get the GIC version.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/Kconfig                   |   1 +
 drivers/acpi/irq.c                   |   3 +
 drivers/irqchip/Kconfig              |   3 +
 drivers/irqchip/Makefile             |   1 +
 drivers/irqchip/irq-gic-acpi.c       | 111 +++++++++++++++++++++++++++++++++++
 include/linux/irqchip/arm-gic-acpi.h |   2 +
 6 files changed, 121 insertions(+)
 create mode 100644 drivers/irqchip/irq-gic-acpi.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7796af4..9b80428 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -15,6 +15,7 @@ config ARM64
 	select ARM_AMBA
 	select ARM_ARCH_TIMER
 	select ARM_GIC
+	select ARM_GIC_ACPI if ACPI
 	select AUDIT_ARCH_COMPAT_GENERIC
 	select ARM_GIC_V2M if PCI_MSI
 	select ARM_GIC_V3
diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
index 65d6b93..855ead9 100644
--- a/drivers/acpi/irq.c
+++ b/drivers/acpi/irq.c
@@ -32,6 +32,9 @@ void __init acpi_irqchip_init(void)
 	if (acpi_disabled)
 		return;
 
+	if (acpi_gic_version_init())
+		return;
+
 	for (id = __irqchip_acpi_table; id->id[0]; id++)
 		acpi_table_parse(id->id, (acpi_tbl_table_handler)id->data);
 }
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 6de62a9..0dd64c5 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -46,6 +46,9 @@ config ARM_VIC_NR
 	  The maximum number of VICs available in the system, for
 	  power management.
 
+config ARM_GIC_ACPI
+	bool
+
 config ATMEL_AIC_IRQ
 	bool
 	select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index dda4927..0bd8e49 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_ARM_GIC)			+= irq-gic.o irq-gic-common.o
 obj-$(CONFIG_ARM_GIC_V2M)		+= irq-gic-v2m.o
 obj-$(CONFIG_ARM_GIC_V3)		+= irq-gic-v3.o irq-gic-common.o
 obj-$(CONFIG_ARM_GIC_V3_ITS)		+= irq-gic-v3-its.o
+obj-$(CONFIG_ARM_GIC_ACPI)		+= irq-gic-acpi.o
 obj-$(CONFIG_ARM_NVIC)			+= irq-nvic.o
 obj-$(CONFIG_ARM_VIC)			+= irq-vic.o
 obj-$(CONFIG_ATMEL_AIC_IRQ)		+= irq-atmel-aic-common.o irq-atmel-aic.o
diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
new file mode 100644
index 0000000..53a86ef
--- /dev/null
+++ b/drivers/irqchip/irq-gic-acpi.c
@@ -0,0 +1,111 @@
+/*
+ * ACPI based support for ARM GIC init
+ *
+ * Copyright (C) 2015, Linaro Ltd.
+ * Author: Hanjun Guo <hanjun.guo@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt) "ACPI: GIC: " fmt
+
+#include <linux/acpi.h>
+#include <linux/init.h>
+#include <linux/irqchip/arm-gic-acpi.h>
+#include <linux/irqchip/arm-gic-v3.h>
+
+/* GIC version presented in MADT GIC distributor structure */
+static u8 gic_version __initdata = ACPI_MADT_GIC_VER_UNKNOWN;
+
+static phys_addr_t dist_phy_base __initdata;
+
+static int __init
+acpi_gic_parse_distributor(struct acpi_subtable_header *header,
+				const unsigned long end)
+{
+	struct acpi_madt_generic_distributor *dist;
+
+	dist = (struct acpi_madt_generic_distributor *)header;
+
+	if (BAD_MADT_ENTRY(dist, end))
+		return -EINVAL;
+
+	gic_version = dist->gic_version;
+	dist_phy_base = dist->base_address;
+	return 0;
+}
+
+static int __init
+match_gic_redist(struct acpi_subtable_header *header, const unsigned long end)
+{
+	return 0;
+}
+
+static bool __init acpi_gic_redist_is_present(void)
+{
+	int count;
+
+	/* scan MADT table to find if we have redistributor entries */
+	count  =  acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
+					match_gic_redist, 0);
+
+	/* has at least one GIC redistributor entry */
+	if (count > 0)
+		return true;
+	else
+		return false;
+}
+
+int __init acpi_gic_version_init(void)
+{
+	int count;
+	void __iomem *dist_base;
+	u32 reg;
+
+	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+					acpi_gic_parse_distributor, 0);
+
+	if (count <= 0) {
+		pr_err("No valid GIC distributor entry exists\n");
+		return -ENODEV;
+	}
+
+	if (gic_version >= ACPI_MADT_GIC_VER_RESERVED) {
+		pr_err("Invalid GIC version %d in MADT\n", gic_version);
+		return -EINVAL;
+	}
+
+	/*
+	 * when the GIC version is 0, we fallback to hardware discovery.
+	 * this is also needed to keep compatiable with ACPI 5.1,
+	 * which has no gic_version field in distributor structure and
+	 * reserved as 0.
+	 *
+	 * For hardware discovery, the offset for GICv1/2 and GICv3/4 to
+	 * get the GIC version is different (0xFE8 for GICv1/2 and 0xFFE8
+	 * for GICv3/4), so we need to handle it separately.
+	 */
+	if (gic_version	== ACPI_MADT_GIC_VER_UNKNOWN) {
+		/* it's GICv3/v4 if redistributor is present */
+		if (acpi_gic_redist_is_present()) {
+			dist_base = ioremap(dist_phy_base,
+						ACPI_GICV3_DIST_MEM_SIZE);
+			if (!dist_base)
+				return -ENOMEM;
+
+			reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
+			if (reg == GIC_PIDR2_ARCH_GICv3)
+				gic_version = ACPI_MADT_GIC_VER_V3;
+			else
+				gic_version = ACPI_MADT_GIC_VER_V4;
+
+			iounmap(dist_base);
+		} else {
+			gic_version = ACPI_MADT_GIC_VER_V2;
+		}
+	}
+
+	return 0;
+}
diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
index de3419e..0d5f204 100644
--- a/include/linux/irqchip/arm-gic-acpi.h
+++ b/include/linux/irqchip/arm-gic-acpi.h
@@ -19,11 +19,13 @@
  */
 #define ACPI_GICV2_DIST_MEM_SIZE	(SZ_4K)
 #define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)
+#define ACPI_GICV3_DIST_MEM_SIZE	(SZ_64K)
 
 struct acpi_table_header;
 
 int gic_v2_acpi_init(struct acpi_table_header *table);
 void acpi_gic_init(void);
+int acpi_gic_version_init(void);
 #else
 static inline void acpi_gic_init(void) { }
 #endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 04/11] irqchip / GIC / ACPI: Use IRQCHIP_ACPI_DECLARE to simplify GICv2 init code
  2015-05-18 12:59 ` Hanjun Guo
@ 2015-05-18 12:59   ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	Grant Likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi, Hanjun Guo

As the ACPI self-probe infrastructure for irqchip is ready,
we use the infrastructure and the GIC version to simplify
GICv2 init code.

>From now on, GIC init calls reside in theirs drivers only.
This means the code becomes cleaner and it is not spread
outside irqchip driver.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/include/asm/irq.h         | 13 -------------
 arch/arm64/kernel/acpi.c             | 25 -------------------------
 drivers/acpi/irq.c                   |  2 +-
 drivers/irqchip/irq-gic-acpi.c       |  5 +++++
 drivers/irqchip/irq-gic.c            |  6 +++++-
 include/linux/acpi_irq.h             |  4 +++-
 include/linux/irqchip/arm-gic-acpi.h | 10 ++--------
 7 files changed, 16 insertions(+), 49 deletions(-)

diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h
index bbb251b..94c5367 100644
--- a/arch/arm64/include/asm/irq.h
+++ b/arch/arm64/include/asm/irq.h
@@ -1,8 +1,6 @@
 #ifndef __ASM_IRQ_H
 #define __ASM_IRQ_H
 
-#include <linux/irqchip/arm-gic-acpi.h>
-
 #include <asm-generic/irq.h>
 
 struct pt_regs;
@@ -10,15 +8,4 @@ struct pt_regs;
 extern void migrate_irqs(void);
 extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
 
-static inline void acpi_irq_init(void)
-{
-	/*
-	 * Hardcode ACPI IRQ chip initialization to GICv2 for now.
-	 * Proper irqchip infrastructure will be implemented along with
-	 * incoming  GICv2m|GICv3|ITS bits.
-	 */
-	acpi_gic_init();
-}
-#define acpi_irq_init acpi_irq_init
-
 #endif
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 8b83955..69809e7 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -318,28 +318,3 @@ void __init acpi_boot_table_init(void)
 			disable_acpi();
 	}
 }
-
-void __init acpi_gic_init(void)
-{
-	struct acpi_table_header *table;
-	acpi_status status;
-	acpi_size tbl_size;
-	int err;
-
-	if (acpi_disabled)
-		return;
-
-	status = acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table, &tbl_size);
-	if (ACPI_FAILURE(status)) {
-		const char *msg = acpi_format_exception(status);
-
-		pr_err("Failed to get MADT table, %s\n", msg);
-		return;
-	}
-
-	err = gic_v2_acpi_init(table);
-	if (err)
-		pr_err("Failed to initialize GIC IRQ controller");
-
-	early_acpi_os_unmap_memory((char *)table, tbl_size);
-}
diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
index 855ead9..7bd1ef6 100644
--- a/drivers/acpi/irq.c
+++ b/drivers/acpi/irq.c
@@ -25,7 +25,7 @@ irqchip_acpi_match_end __used __section(__irqchip_acpi_table_end);
 
 extern struct acpi_table_id __irqchip_acpi_table[];
 
-void __init acpi_irqchip_init(void)
+void __init acpi_irq_init(void)
 {
 	struct acpi_table_id *id;
 
diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
index 53a86ef..1388d9e 100644
--- a/drivers/irqchip/irq-gic-acpi.c
+++ b/drivers/irqchip/irq-gic-acpi.c
@@ -21,6 +21,11 @@ static u8 gic_version __initdata = ACPI_MADT_GIC_VER_UNKNOWN;
 
 static phys_addr_t dist_phy_base __initdata;
 
+u8 __init acpi_gic_version(void)
+{
+	return gic_version;
+}
+
 static int __init
 acpi_gic_parse_distributor(struct acpi_subtable_header *header,
 				const unsigned long end)
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 01999d7..fefbcb5 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -1085,12 +1085,15 @@ gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
 	return 0;
 }
 
-int __init
+static int __init
 gic_v2_acpi_init(struct acpi_table_header *table)
 {
 	void __iomem *cpu_base, *dist_base;
 	int count;
 
+	if (acpi_gic_version() >= ACPI_MADT_GIC_VER_V3)
+		return -ENODEV;
+
 	/* Collect CPU base addresses */
 	count = acpi_parse_entries(ACPI_SIG_MADT,
 				   sizeof(struct acpi_table_madt),
@@ -1141,4 +1144,5 @@ gic_v2_acpi_init(struct acpi_table_header *table)
 	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
 	return 0;
 }
+IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_SIG_MADT, gic_v2_acpi_init);
 #endif
diff --git a/include/linux/acpi_irq.h b/include/linux/acpi_irq.h
index f10c872..4c0e108 100644
--- a/include/linux/acpi_irq.h
+++ b/include/linux/acpi_irq.h
@@ -3,7 +3,9 @@
 
 #include <linux/irq.h>
 
-#ifndef acpi_irq_init
+#ifdef CONFIG_ACPI
+void acpi_irq_init(void);
+#else
 static inline void acpi_irq_init(void) { }
 #endif
 
diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
index 0d5f204..021e8e8 100644
--- a/include/linux/irqchip/arm-gic-acpi.h
+++ b/include/linux/irqchip/arm-gic-acpi.h
@@ -21,13 +21,7 @@
 #define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)
 #define ACPI_GICV3_DIST_MEM_SIZE	(SZ_64K)
 
-struct acpi_table_header;
-
-int gic_v2_acpi_init(struct acpi_table_header *table);
-void acpi_gic_init(void);
 int acpi_gic_version_init(void);
-#else
-static inline void acpi_gic_init(void) { }
-#endif
-
+u8 acpi_gic_version(void);
+#endif /* CONFIG_ACPI */
 #endif /* ARM_GIC_ACPI_H_ */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 04/11] irqchip / GIC / ACPI: Use IRQCHIP_ACPI_DECLARE to simplify GICv2 init code
@ 2015-05-18 12:59   ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

As the ACPI self-probe infrastructure for irqchip is ready,
we use the infrastructure and the GIC version to simplify
GICv2 init code.

>From now on, GIC init calls reside in theirs drivers only.
This means the code becomes cleaner and it is not spread
outside irqchip driver.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/include/asm/irq.h         | 13 -------------
 arch/arm64/kernel/acpi.c             | 25 -------------------------
 drivers/acpi/irq.c                   |  2 +-
 drivers/irqchip/irq-gic-acpi.c       |  5 +++++
 drivers/irqchip/irq-gic.c            |  6 +++++-
 include/linux/acpi_irq.h             |  4 +++-
 include/linux/irqchip/arm-gic-acpi.h | 10 ++--------
 7 files changed, 16 insertions(+), 49 deletions(-)

diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h
index bbb251b..94c5367 100644
--- a/arch/arm64/include/asm/irq.h
+++ b/arch/arm64/include/asm/irq.h
@@ -1,8 +1,6 @@
 #ifndef __ASM_IRQ_H
 #define __ASM_IRQ_H
 
-#include <linux/irqchip/arm-gic-acpi.h>
-
 #include <asm-generic/irq.h>
 
 struct pt_regs;
@@ -10,15 +8,4 @@ struct pt_regs;
 extern void migrate_irqs(void);
 extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
 
-static inline void acpi_irq_init(void)
-{
-	/*
-	 * Hardcode ACPI IRQ chip initialization to GICv2 for now.
-	 * Proper irqchip infrastructure will be implemented along with
-	 * incoming  GICv2m|GICv3|ITS bits.
-	 */
-	acpi_gic_init();
-}
-#define acpi_irq_init acpi_irq_init
-
 #endif
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 8b83955..69809e7 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -318,28 +318,3 @@ void __init acpi_boot_table_init(void)
 			disable_acpi();
 	}
 }
-
-void __init acpi_gic_init(void)
-{
-	struct acpi_table_header *table;
-	acpi_status status;
-	acpi_size tbl_size;
-	int err;
-
-	if (acpi_disabled)
-		return;
-
-	status = acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table, &tbl_size);
-	if (ACPI_FAILURE(status)) {
-		const char *msg = acpi_format_exception(status);
-
-		pr_err("Failed to get MADT table, %s\n", msg);
-		return;
-	}
-
-	err = gic_v2_acpi_init(table);
-	if (err)
-		pr_err("Failed to initialize GIC IRQ controller");
-
-	early_acpi_os_unmap_memory((char *)table, tbl_size);
-}
diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
index 855ead9..7bd1ef6 100644
--- a/drivers/acpi/irq.c
+++ b/drivers/acpi/irq.c
@@ -25,7 +25,7 @@ irqchip_acpi_match_end __used __section(__irqchip_acpi_table_end);
 
 extern struct acpi_table_id __irqchip_acpi_table[];
 
-void __init acpi_irqchip_init(void)
+void __init acpi_irq_init(void)
 {
 	struct acpi_table_id *id;
 
diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
index 53a86ef..1388d9e 100644
--- a/drivers/irqchip/irq-gic-acpi.c
+++ b/drivers/irqchip/irq-gic-acpi.c
@@ -21,6 +21,11 @@ static u8 gic_version __initdata = ACPI_MADT_GIC_VER_UNKNOWN;
 
 static phys_addr_t dist_phy_base __initdata;
 
+u8 __init acpi_gic_version(void)
+{
+	return gic_version;
+}
+
 static int __init
 acpi_gic_parse_distributor(struct acpi_subtable_header *header,
 				const unsigned long end)
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 01999d7..fefbcb5 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -1085,12 +1085,15 @@ gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
 	return 0;
 }
 
-int __init
+static int __init
 gic_v2_acpi_init(struct acpi_table_header *table)
 {
 	void __iomem *cpu_base, *dist_base;
 	int count;
 
+	if (acpi_gic_version() >= ACPI_MADT_GIC_VER_V3)
+		return -ENODEV;
+
 	/* Collect CPU base addresses */
 	count = acpi_parse_entries(ACPI_SIG_MADT,
 				   sizeof(struct acpi_table_madt),
@@ -1141,4 +1144,5 @@ gic_v2_acpi_init(struct acpi_table_header *table)
 	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
 	return 0;
 }
+IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_SIG_MADT, gic_v2_acpi_init);
 #endif
diff --git a/include/linux/acpi_irq.h b/include/linux/acpi_irq.h
index f10c872..4c0e108 100644
--- a/include/linux/acpi_irq.h
+++ b/include/linux/acpi_irq.h
@@ -3,7 +3,9 @@
 
 #include <linux/irq.h>
 
-#ifndef acpi_irq_init
+#ifdef CONFIG_ACPI
+void acpi_irq_init(void);
+#else
 static inline void acpi_irq_init(void) { }
 #endif
 
diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
index 0d5f204..021e8e8 100644
--- a/include/linux/irqchip/arm-gic-acpi.h
+++ b/include/linux/irqchip/arm-gic-acpi.h
@@ -21,13 +21,7 @@
 #define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)
 #define ACPI_GICV3_DIST_MEM_SIZE	(SZ_64K)
 
-struct acpi_table_header;
-
-int gic_v2_acpi_init(struct acpi_table_header *table);
-void acpi_gic_init(void);
 int acpi_gic_version_init(void);
-#else
-static inline void acpi_gic_init(void) { }
-#endif
-
+u8 acpi_gic_version(void);
+#endif /* CONFIG_ACPI */
 #endif /* ARM_GIC_ACPI_H_ */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 05/11] irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
  2015-05-18 12:59 ` Hanjun Guo
@ 2015-05-18 12:59   ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	Grant Likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi, Hanjun Guo

Introduce acpi_irq_domain for GICv2 core domain instead of referring
to the irq_default_domain, based on that, pass gsi as the argument and
get the gsi in gic_irq_domain_alloc() to add stacked irqdomain support
for ACPI based GICv2 init.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/gsi.c                   | 28 +++++++++++++---------------
 drivers/irqchip/irq-gic.c            | 32 +++++++++++++++++---------------
 include/linux/irqchip/arm-gic-acpi.h |  2 ++
 3 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
index 38208f2..55b5f31 100644
--- a/drivers/acpi/gsi.c
+++ b/drivers/acpi/gsi.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2015 ARM Ltd.
  * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+ *         Hanjun Guo <hanjun.guo@linaro.org> for stacked irqdomains support
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -13,6 +14,8 @@
 #include <linux/irqdomain.h>
 
 enum acpi_irq_model_id acpi_irq_model;
+/* ACPI core domian pointing to GICv2/3 core domain */
+struct irq_domain *acpi_irq_domain __read_mostly;
 
 static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
 {
@@ -45,12 +48,7 @@ static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
  */
 int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 {
-	/*
-	 * Only default domain is supported at present, always find
-	 * the mapping corresponding to default domain by passing NULL
-	 * as irq_domain parameter
-	 */
-	*irq = irq_find_mapping(NULL, gsi);
+	*irq = irq_find_mapping(acpi_irq_domain, gsi);
 	/*
 	 * *irq == 0 means no mapping, that should
 	 * be reported as a failure
@@ -72,16 +70,16 @@ EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
 int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
 		      int polarity)
 {
-	unsigned int irq;
+	int irq;
 	unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
 
-	/*
-	 * There is no way at present to look-up the IRQ domain on ACPI,
-	 * hence always create mapping referring to the default domain
-	 * by passing NULL as irq_domain parameter
-	 */
-	irq = irq_create_mapping(NULL, gsi);
-	if (!irq)
+	irq = irq_find_mapping(acpi_irq_domain, gsi);
+	if (irq > 0)
+		return irq;
+
+	irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
+				    &gsi);
+	if (irq <= 0)
 		return -EINVAL;
 
 	/* Set irq type if specified and different than the current one */
@@ -98,7 +96,7 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
  */
 void acpi_unregister_gsi(u32 gsi)
 {
-	int irq = irq_find_mapping(NULL, gsi);
+	int irq = irq_find_mapping(acpi_irq_domain, gsi);
 
 	irq_dispose_mapping(irq);
 }
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index fefbcb5..869a69f 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -851,15 +851,22 @@ static struct notifier_block gic_cpu_notifier = {
 static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
 				unsigned int nr_irqs, void *arg)
 {
-	int i, ret;
+	int i;
 	irq_hw_number_t hwirq;
-	unsigned int type = IRQ_TYPE_NONE;
-	struct of_phandle_args *irq_data = arg;
 
-	ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args,
-				   irq_data->args_count, &hwirq, &type);
-	if (ret)
-		return ret;
+	if (domain->of_node) {	/* DT case */
+		int ret;
+		unsigned int type = IRQ_TYPE_NONE;
+		struct of_phandle_args *irq_data = arg;
+
+		ret = gic_irq_domain_xlate(domain, irq_data->np,
+					irq_data->args,
+					irq_data->args_count, &hwirq, &type);
+		if (ret)
+			return ret;
+	} else {	/* ACPI case */
+		hwirq = (irq_hw_number_t)*(u32 *)arg;
+	}
 
 	for (i = 0; i < nr_irqs; i++)
 		gic_irq_domain_map(domain, virq + i, hwirq + i);
@@ -945,11 +952,11 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 		gic_irqs = 1020;
 	gic->gic_irqs = gic_irqs;
 
-	if (node) {		/* DT case */
+	if (node || !acpi_disabled) {		/* DT or ACPI case */
 		gic->domain = irq_domain_add_linear(node, gic_irqs,
 						    &gic_irq_domain_hierarchy_ops,
 						    gic);
-	} else {		/* Non-DT case */
+	} else {		/* Non-DT and ACPI case */
 		/*
 		 * For primary GICs, skip over SGIs.
 		 * For secondary GICs, skip over PPIs, too.
@@ -1133,13 +1140,8 @@ gic_v2_acpi_init(struct acpi_table_header *table)
 		return -ENOMEM;
 	}
 
-	/*
-	 * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
-	 * as default IRQ domain to allow for GSI registration and GSI to IRQ
-	 * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()).
-	 */
 	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
-	irq_set_default_host(gic_data[0].domain);
+	acpi_irq_domain = gic_data[0].domain;
 
 	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
 	return 0;
diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
index 021e8e8..245386d 100644
--- a/include/linux/irqchip/arm-gic-acpi.h
+++ b/include/linux/irqchip/arm-gic-acpi.h
@@ -21,6 +21,8 @@
 #define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)
 #define ACPI_GICV3_DIST_MEM_SIZE	(SZ_64K)
 
+extern struct irq_domain *acpi_irq_domain;
+
 int acpi_gic_version_init(void);
 u8 acpi_gic_version(void);
 #endif /* CONFIG_ACPI */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 05/11] irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
@ 2015-05-18 12:59   ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

Introduce acpi_irq_domain for GICv2 core domain instead of referring
to the irq_default_domain, based on that, pass gsi as the argument and
get the gsi in gic_irq_domain_alloc() to add stacked irqdomain support
for ACPI based GICv2 init.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/gsi.c                   | 28 +++++++++++++---------------
 drivers/irqchip/irq-gic.c            | 32 +++++++++++++++++---------------
 include/linux/irqchip/arm-gic-acpi.h |  2 ++
 3 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
index 38208f2..55b5f31 100644
--- a/drivers/acpi/gsi.c
+++ b/drivers/acpi/gsi.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2015 ARM Ltd.
  * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+ *         Hanjun Guo <hanjun.guo@linaro.org> for stacked irqdomains support
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -13,6 +14,8 @@
 #include <linux/irqdomain.h>
 
 enum acpi_irq_model_id acpi_irq_model;
+/* ACPI core domian pointing to GICv2/3 core domain */
+struct irq_domain *acpi_irq_domain __read_mostly;
 
 static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
 {
@@ -45,12 +48,7 @@ static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
  */
 int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 {
-	/*
-	 * Only default domain is supported at present, always find
-	 * the mapping corresponding to default domain by passing NULL
-	 * as irq_domain parameter
-	 */
-	*irq = irq_find_mapping(NULL, gsi);
+	*irq = irq_find_mapping(acpi_irq_domain, gsi);
 	/*
 	 * *irq == 0 means no mapping, that should
 	 * be reported as a failure
@@ -72,16 +70,16 @@ EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
 int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
 		      int polarity)
 {
-	unsigned int irq;
+	int irq;
 	unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
 
-	/*
-	 * There is no way at present to look-up the IRQ domain on ACPI,
-	 * hence always create mapping referring to the default domain
-	 * by passing NULL as irq_domain parameter
-	 */
-	irq = irq_create_mapping(NULL, gsi);
-	if (!irq)
+	irq = irq_find_mapping(acpi_irq_domain, gsi);
+	if (irq > 0)
+		return irq;
+
+	irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
+				    &gsi);
+	if (irq <= 0)
 		return -EINVAL;
 
 	/* Set irq type if specified and different than the current one */
@@ -98,7 +96,7 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
  */
 void acpi_unregister_gsi(u32 gsi)
 {
-	int irq = irq_find_mapping(NULL, gsi);
+	int irq = irq_find_mapping(acpi_irq_domain, gsi);
 
 	irq_dispose_mapping(irq);
 }
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index fefbcb5..869a69f 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -851,15 +851,22 @@ static struct notifier_block gic_cpu_notifier = {
 static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
 				unsigned int nr_irqs, void *arg)
 {
-	int i, ret;
+	int i;
 	irq_hw_number_t hwirq;
-	unsigned int type = IRQ_TYPE_NONE;
-	struct of_phandle_args *irq_data = arg;
 
-	ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args,
-				   irq_data->args_count, &hwirq, &type);
-	if (ret)
-		return ret;
+	if (domain->of_node) {	/* DT case */
+		int ret;
+		unsigned int type = IRQ_TYPE_NONE;
+		struct of_phandle_args *irq_data = arg;
+
+		ret = gic_irq_domain_xlate(domain, irq_data->np,
+					irq_data->args,
+					irq_data->args_count, &hwirq, &type);
+		if (ret)
+			return ret;
+	} else {	/* ACPI case */
+		hwirq = (irq_hw_number_t)*(u32 *)arg;
+	}
 
 	for (i = 0; i < nr_irqs; i++)
 		gic_irq_domain_map(domain, virq + i, hwirq + i);
@@ -945,11 +952,11 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 		gic_irqs = 1020;
 	gic->gic_irqs = gic_irqs;
 
-	if (node) {		/* DT case */
+	if (node || !acpi_disabled) {		/* DT or ACPI case */
 		gic->domain = irq_domain_add_linear(node, gic_irqs,
 						    &gic_irq_domain_hierarchy_ops,
 						    gic);
-	} else {		/* Non-DT case */
+	} else {		/* Non-DT and ACPI case */
 		/*
 		 * For primary GICs, skip over SGIs.
 		 * For secondary GICs, skip over PPIs, too.
@@ -1133,13 +1140,8 @@ gic_v2_acpi_init(struct acpi_table_header *table)
 		return -ENOMEM;
 	}
 
-	/*
-	 * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
-	 * as default IRQ domain to allow for GSI registration and GSI to IRQ
-	 * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()).
-	 */
 	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
-	irq_set_default_host(gic_data[0].domain);
+	acpi_irq_domain = gic_data[0].domain;
 
 	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
 	return 0;
diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
index 021e8e8..245386d 100644
--- a/include/linux/irqchip/arm-gic-acpi.h
+++ b/include/linux/irqchip/arm-gic-acpi.h
@@ -21,6 +21,8 @@
 #define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)
 #define ACPI_GICV3_DIST_MEM_SIZE	(SZ_64K)
 
+extern struct irq_domain *acpi_irq_domain;
+
 int acpi_gic_version_init(void);
 u8 acpi_gic_version(void);
 #endif /* CONFIG_ACPI */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 06/11] ACPI / gsi: Add gsi_mutex to synchronize acpi_register_gsi()/acpi_unregister_gsi()
  2015-05-18 12:59 ` Hanjun Guo
@ 2015-05-18 12:59   ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	Grant Likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi, Hanjun Guo

Add a mutex for acpi_register_gsi()/acpi_unregister_gsi() to avoid
concurrency issues.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/gsi.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
index 55b5f31..ab0dcb4 100644
--- a/drivers/acpi/gsi.c
+++ b/drivers/acpi/gsi.c
@@ -16,6 +16,7 @@
 enum acpi_irq_model_id acpi_irq_model;
 /* ACPI core domian pointing to GICv2/3 core domain */
 struct irq_domain *acpi_irq_domain __read_mostly;
+static DEFINE_MUTEX(gsi_mutex);
 
 static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
 {
@@ -73,20 +74,24 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
 	int irq;
 	unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
 
+	mutex_lock(&gsi_mutex);
 	irq = irq_find_mapping(acpi_irq_domain, gsi);
 	if (irq > 0)
-		return irq;
+		goto out;
 
 	irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
 				    &gsi);
 	if (irq <= 0)
-		return -EINVAL;
+		goto out;
 
 	/* Set irq type if specified and different than the current one */
 	if (irq_type != IRQ_TYPE_NONE &&
 		irq_type != irq_get_trigger_type(irq))
 		irq_set_irq_type(irq, irq_type);
-	return irq;
+
+out:
+	mutex_unlock(&gsi_mutex);
+	return irq > 0 ? irq : -EINVAL;
 }
 EXPORT_SYMBOL_GPL(acpi_register_gsi);
 
@@ -96,8 +101,12 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
  */
 void acpi_unregister_gsi(u32 gsi)
 {
-	int irq = irq_find_mapping(acpi_irq_domain, gsi);
+	int irq;
+
+	mutex_lock(&gsi_mutex);
+	irq = irq_find_mapping(acpi_irq_domain, gsi);
 
 	irq_dispose_mapping(irq);
+	mutex_unlock(&gsi_mutex);
 }
 EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 06/11] ACPI / gsi: Add gsi_mutex to synchronize acpi_register_gsi()/acpi_unregister_gsi()
@ 2015-05-18 12:59   ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

Add a mutex for acpi_register_gsi()/acpi_unregister_gsi() to avoid
concurrency issues.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/gsi.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
index 55b5f31..ab0dcb4 100644
--- a/drivers/acpi/gsi.c
+++ b/drivers/acpi/gsi.c
@@ -16,6 +16,7 @@
 enum acpi_irq_model_id acpi_irq_model;
 /* ACPI core domian pointing to GICv2/3 core domain */
 struct irq_domain *acpi_irq_domain __read_mostly;
+static DEFINE_MUTEX(gsi_mutex);
 
 static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
 {
@@ -73,20 +74,24 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
 	int irq;
 	unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
 
+	mutex_lock(&gsi_mutex);
 	irq = irq_find_mapping(acpi_irq_domain, gsi);
 	if (irq > 0)
-		return irq;
+		goto out;
 
 	irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
 				    &gsi);
 	if (irq <= 0)
-		return -EINVAL;
+		goto out;
 
 	/* Set irq type if specified and different than the current one */
 	if (irq_type != IRQ_TYPE_NONE &&
 		irq_type != irq_get_trigger_type(irq))
 		irq_set_irq_type(irq, irq_type);
-	return irq;
+
+out:
+	mutex_unlock(&gsi_mutex);
+	return irq > 0 ? irq : -EINVAL;
 }
 EXPORT_SYMBOL_GPL(acpi_register_gsi);
 
@@ -96,8 +101,12 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
  */
 void acpi_unregister_gsi(u32 gsi)
 {
-	int irq = irq_find_mapping(acpi_irq_domain, gsi);
+	int irq;
+
+	mutex_lock(&gsi_mutex);
+	irq = irq_find_mapping(acpi_irq_domain, gsi);
 
 	irq_dispose_mapping(irq);
+	mutex_unlock(&gsi_mutex);
 }
 EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 07/11] irqchip / GICv3: Refactor gic_of_init() for GICv3 driver
  2015-05-18 12:59 ` Hanjun Guo
@ 2015-05-18 12:59   ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	Grant Likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi, Hanjun Guo

From: Tomasz Nowicki <tomasz.nowicki@linaro.org>

Isolate hardware abstraction (FDT) code to gic_of_init().
Rest of the logic goes to gic_init_bases() and expects well
defined data to initialize GIC properly. The same solution
is used for GICv2 driver.

This is needed for ACPI initialization later.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3.c | 105 +++++++++++++++++++++++++------------------
 1 file changed, 61 insertions(+), 44 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 49875ad..87cf81b 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -765,17 +765,69 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
 	.free = gic_irq_domain_free,
 };
 
+static int __init gic_init_bases(void __iomem *dist_base,
+			    struct redist_region *rdist_regs,
+			    u32 nr_redist_regions,
+			    u64 redist_stride,
+			    struct device_node *node)
+{
+	u32 typer;
+	int gic_irqs;
+	int err;
+
+	gic_data.dist_base = dist_base;
+	gic_data.redist_regions = rdist_regs;
+	gic_data.nr_redist_regions = nr_redist_regions;
+	gic_data.redist_stride = redist_stride;
+
+	/*
+	 * Find out how many interrupts are supported.
+	 * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI)
+	 */
+	typer = readl_relaxed(gic_data.dist_base + GICD_TYPER);
+	gic_data.rdists.id_bits = GICD_TYPER_ID_BITS(typer);
+	gic_irqs = GICD_TYPER_IRQS(typer);
+	if (gic_irqs > 1020)
+		gic_irqs = 1020;
+	gic_data.irq_nr = gic_irqs;
+
+	gic_data.domain = irq_domain_add_tree(node, &gic_irq_domain_ops,
+					      &gic_data);
+	gic_data.rdists.rdist = alloc_percpu(typeof(*gic_data.rdists.rdist));
+
+	if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdists.rdist)) {
+		err = -ENOMEM;
+		goto out_free;
+	}
+
+	set_handle_irq(gic_handle_irq);
+
+	if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
+		its_init(node, &gic_data.rdists, gic_data.domain);
+
+	gic_smp_init();
+	gic_dist_init();
+	gic_cpu_init();
+	gic_cpu_pm_init();
+
+	return 0;
+
+out_free:
+	if (gic_data.domain)
+		irq_domain_remove(gic_data.domain);
+	free_percpu(gic_data.rdists.rdist);
+	return err;
+}
+
+#ifdef CONFIG_OF
 static int __init gic_of_init(struct device_node *node, struct device_node *parent)
 {
 	void __iomem *dist_base;
 	struct redist_region *rdist_regs;
 	u64 redist_stride;
 	u32 nr_redist_regions;
-	u32 typer;
 	u32 reg;
-	int gic_irqs;
-	int err;
-	int i;
+	int err, i;
 
 	dist_base = of_iomap(node, 0);
 	if (!dist_base) {
@@ -819,47 +871,11 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 	if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
 		redist_stride = 0;
 
-	gic_data.dist_base = dist_base;
-	gic_data.redist_regions = rdist_regs;
-	gic_data.nr_redist_regions = nr_redist_regions;
-	gic_data.redist_stride = redist_stride;
-
-	/*
-	 * Find out how many interrupts are supported.
-	 * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI)
-	 */
-	typer = readl_relaxed(gic_data.dist_base + GICD_TYPER);
-	gic_data.rdists.id_bits = GICD_TYPER_ID_BITS(typer);
-	gic_irqs = GICD_TYPER_IRQS(typer);
-	if (gic_irqs > 1020)
-		gic_irqs = 1020;
-	gic_data.irq_nr = gic_irqs;
+	err = gic_init_bases(dist_base, rdist_regs, nr_redist_regions,
+			     redist_stride, node);
+	if (!err)
+		return 0;
 
-	gic_data.domain = irq_domain_add_tree(node, &gic_irq_domain_ops,
-					      &gic_data);
-	gic_data.rdists.rdist = alloc_percpu(typeof(*gic_data.rdists.rdist));
-
-	if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdists.rdist)) {
-		err = -ENOMEM;
-		goto out_free;
-	}
-
-	set_handle_irq(gic_handle_irq);
-
-	if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
-		its_init(node, &gic_data.rdists, gic_data.domain);
-
-	gic_smp_init();
-	gic_dist_init();
-	gic_cpu_init();
-	gic_cpu_pm_init();
-
-	return 0;
-
-out_free:
-	if (gic_data.domain)
-		irq_domain_remove(gic_data.domain);
-	free_percpu(gic_data.rdists.rdist);
 out_unmap_rdist:
 	for (i = 0; i < nr_redist_regions; i++)
 		if (rdist_regs[i].redist_base)
@@ -871,3 +887,4 @@ out_unmap_dist:
 }
 
 IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 07/11] irqchip / GICv3: Refactor gic_of_init() for GICv3 driver
@ 2015-05-18 12:59   ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tomasz Nowicki <tomasz.nowicki@linaro.org>

Isolate hardware abstraction (FDT) code to gic_of_init().
Rest of the logic goes to gic_init_bases() and expects well
defined data to initialize GIC properly. The same solution
is used for GICv2 driver.

This is needed for ACPI initialization later.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3.c | 105 +++++++++++++++++++++++++------------------
 1 file changed, 61 insertions(+), 44 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 49875ad..87cf81b 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -765,17 +765,69 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
 	.free = gic_irq_domain_free,
 };
 
+static int __init gic_init_bases(void __iomem *dist_base,
+			    struct redist_region *rdist_regs,
+			    u32 nr_redist_regions,
+			    u64 redist_stride,
+			    struct device_node *node)
+{
+	u32 typer;
+	int gic_irqs;
+	int err;
+
+	gic_data.dist_base = dist_base;
+	gic_data.redist_regions = rdist_regs;
+	gic_data.nr_redist_regions = nr_redist_regions;
+	gic_data.redist_stride = redist_stride;
+
+	/*
+	 * Find out how many interrupts are supported.
+	 * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI)
+	 */
+	typer = readl_relaxed(gic_data.dist_base + GICD_TYPER);
+	gic_data.rdists.id_bits = GICD_TYPER_ID_BITS(typer);
+	gic_irqs = GICD_TYPER_IRQS(typer);
+	if (gic_irqs > 1020)
+		gic_irqs = 1020;
+	gic_data.irq_nr = gic_irqs;
+
+	gic_data.domain = irq_domain_add_tree(node, &gic_irq_domain_ops,
+					      &gic_data);
+	gic_data.rdists.rdist = alloc_percpu(typeof(*gic_data.rdists.rdist));
+
+	if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdists.rdist)) {
+		err = -ENOMEM;
+		goto out_free;
+	}
+
+	set_handle_irq(gic_handle_irq);
+
+	if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
+		its_init(node, &gic_data.rdists, gic_data.domain);
+
+	gic_smp_init();
+	gic_dist_init();
+	gic_cpu_init();
+	gic_cpu_pm_init();
+
+	return 0;
+
+out_free:
+	if (gic_data.domain)
+		irq_domain_remove(gic_data.domain);
+	free_percpu(gic_data.rdists.rdist);
+	return err;
+}
+
+#ifdef CONFIG_OF
 static int __init gic_of_init(struct device_node *node, struct device_node *parent)
 {
 	void __iomem *dist_base;
 	struct redist_region *rdist_regs;
 	u64 redist_stride;
 	u32 nr_redist_regions;
-	u32 typer;
 	u32 reg;
-	int gic_irqs;
-	int err;
-	int i;
+	int err, i;
 
 	dist_base = of_iomap(node, 0);
 	if (!dist_base) {
@@ -819,47 +871,11 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 	if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
 		redist_stride = 0;
 
-	gic_data.dist_base = dist_base;
-	gic_data.redist_regions = rdist_regs;
-	gic_data.nr_redist_regions = nr_redist_regions;
-	gic_data.redist_stride = redist_stride;
-
-	/*
-	 * Find out how many interrupts are supported.
-	 * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI)
-	 */
-	typer = readl_relaxed(gic_data.dist_base + GICD_TYPER);
-	gic_data.rdists.id_bits = GICD_TYPER_ID_BITS(typer);
-	gic_irqs = GICD_TYPER_IRQS(typer);
-	if (gic_irqs > 1020)
-		gic_irqs = 1020;
-	gic_data.irq_nr = gic_irqs;
+	err = gic_init_bases(dist_base, rdist_regs, nr_redist_regions,
+			     redist_stride, node);
+	if (!err)
+		return 0;
 
-	gic_data.domain = irq_domain_add_tree(node, &gic_irq_domain_ops,
-					      &gic_data);
-	gic_data.rdists.rdist = alloc_percpu(typeof(*gic_data.rdists.rdist));
-
-	if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdists.rdist)) {
-		err = -ENOMEM;
-		goto out_free;
-	}
-
-	set_handle_irq(gic_handle_irq);
-
-	if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
-		its_init(node, &gic_data.rdists, gic_data.domain);
-
-	gic_smp_init();
-	gic_dist_init();
-	gic_cpu_init();
-	gic_cpu_pm_init();
-
-	return 0;
-
-out_free:
-	if (gic_data.domain)
-		irq_domain_remove(gic_data.domain);
-	free_percpu(gic_data.rdists.rdist);
 out_unmap_rdist:
 	for (i = 0; i < nr_redist_regions; i++)
 		if (rdist_regs[i].redist_base)
@@ -871,3 +887,4 @@ out_unmap_dist:
 }
 
 IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 08/11] irqchip / GICv3: Add ACPI support for GICv3+ initialization
  2015-05-18 12:59 ` Hanjun Guo
@ 2015-05-18 12:59   ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	Grant Likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi, Hanjun Guo

With the refator of gic_of_init(), GICv3/4 can be initialized
by gic_init_bases() with gic distributor base address and gic
redistributor region(s).

So get the redistributor region base addresses from MADT GIC
redistributor subtable, and the distributor base address from
GICD subtable to init GICv3 irqchip in ACPI way.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
[hj: Rework this patch and fix multi issues]
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3.c | 146 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 142 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 87cf81b..11946a6 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -15,6 +15,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/acpi.h>
 #include <linux/cpu.h>
 #include <linux/cpu_pm.h>
 #include <linux/delay.h>
@@ -25,6 +26,7 @@
 #include <linux/percpu.h>
 #include <linux/slab.h>
 
+#include <linux/irqchip/arm-gic-acpi.h>
 #include <linux/irqchip/arm-gic-v3.h>
 
 #include <asm/cputype.h>
@@ -819,6 +821,16 @@ out_free:
 	return err;
 }
 
+static int __init detect_distributor(void __iomem *dist_base)
+{
+	u32 reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
+
+	if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4)
+		return -ENODEV;
+
+	return 0;
+}
+
 #ifdef CONFIG_OF
 static int __init gic_of_init(struct device_node *node, struct device_node *parent)
 {
@@ -826,7 +838,6 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 	struct redist_region *rdist_regs;
 	u64 redist_stride;
 	u32 nr_redist_regions;
-	u32 reg;
 	int err, i;
 
 	dist_base = of_iomap(node, 0);
@@ -836,11 +847,10 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 		return -ENXIO;
 	}
 
-	reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
-	if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4) {
+	err = detect_distributor(dist_base);
+	if (err) {
 		pr_err("%s: no distributor detected, giving up\n",
 			node->full_name);
-		err = -ENODEV;
 		goto out_unmap_dist;
 	}
 
@@ -888,3 +898,131 @@ out_unmap_dist:
 
 IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
 #endif
+
+#ifdef CONFIG_ACPI
+static struct redist_region *redist_regs __initdata;
+static u32 nr_redist_regions __initdata;
+static phys_addr_t dist_phy_base __initdata;
+
+static int __init
+gic_acpi_register_redist(u64 phys_base, u64 size)
+{
+	struct redist_region *redist_regs_new;
+	void __iomem *redist_base;
+
+	redist_regs_new = krealloc(redist_regs,
+				   sizeof(*redist_regs) * (nr_redist_regions + 1),
+				   GFP_KERNEL);
+	if (!redist_regs_new) {
+		pr_err("Couldn't allocate resource for GICR region\n");
+		return -ENOMEM;
+	}
+
+	redist_regs = redist_regs_new;
+
+	redist_base = ioremap(phys_base, size);
+	if (!redist_base) {
+		pr_err("Couldn't map GICR region @%llx\n", phys_base);
+		return -ENOMEM;
+	}
+
+	redist_regs[nr_redist_regions].phys_base = phys_base;
+	redist_regs[nr_redist_regions].redist_base = redist_base;
+	nr_redist_regions++;
+	return 0;
+}
+
+static int __init
+gic_acpi_parse_madt_redist(struct acpi_subtable_header *header,
+			const unsigned long end)
+{
+	struct acpi_madt_generic_redistributor *redist;
+
+	if (BAD_MADT_ENTRY(header, end))
+		return -EINVAL;
+
+	redist = (struct acpi_madt_generic_redistributor *)header;
+	if (!redist->base_address)
+		return -EINVAL;
+
+	return gic_acpi_register_redist(redist->base_address, redist->length);
+}
+
+static int __init
+gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
+				const unsigned long end)
+{
+	struct acpi_madt_generic_distributor *dist;
+
+	dist = (struct acpi_madt_generic_distributor *)header;
+
+	if (BAD_MADT_ENTRY(dist, end))
+		return -EINVAL;
+
+	dist_phy_base = dist->base_address;
+	return 0;
+}
+
+static int __init
+gic_v3_acpi_init(struct acpi_table_header *table)
+{
+	int count, i, err = 0;
+	void __iomem *dist_base;
+
+	if (acpi_gic_version() < ACPI_MADT_GIC_VER_V3)
+		return -ENODEV;
+
+	/* Get distributor base address */
+	count = acpi_parse_entries(ACPI_SIG_MADT,
+				sizeof(struct acpi_table_madt),
+				gic_acpi_parse_madt_distributor, table,
+				ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+	if (count <= 0) {
+		pr_err("No valid GICD entry exist\n");
+		return -EINVAL;
+	} else if (count > 1) {
+		pr_err("More than one GICD entry detected\n");
+		return -EINVAL;
+	}
+
+	dist_base = ioremap(dist_phy_base, ACPI_GICV3_DIST_MEM_SIZE);
+	if (!dist_base) {
+		pr_err("Unable to map GICD registers\n");
+		return -ENOMEM;
+	}
+
+	err = detect_distributor(dist_base);
+	if (err) {
+		pr_err("No distributor detected at @%p, giving up", dist_base);
+		goto out_dist_unmap;
+	}
+
+	/* Collect redistributor base addresses */
+	count = acpi_parse_entries(ACPI_SIG_MADT,
+			sizeof(struct acpi_table_madt),
+			gic_acpi_parse_madt_redist, table,
+			ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
+	if (count <= 0) {
+		pr_info("No valid GICR entries exist\n");
+		err = -EINVAL;
+		goto out_redist_unmap;
+	}
+
+	err = gic_init_bases(dist_base, redist_regs, nr_redist_regions, 0, NULL);
+	if (err)
+		goto out_redist_unmap;
+
+	irq_set_default_host(gic_data.domain);
+	return 0;
+
+out_redist_unmap:
+	for (i = 0; i < nr_redist_regions; i++)
+		if (redist_regs[i].redist_base)
+			iounmap(redist_regs[i].redist_base);
+	kfree(redist_regs);
+out_dist_unmap:
+	iounmap(dist_base);
+	return err;
+}
+IRQCHIP_ACPI_DECLARE(gic_v3, ACPI_SIG_MADT, gic_v3_acpi_init);
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 08/11] irqchip / GICv3: Add ACPI support for GICv3+ initialization
@ 2015-05-18 12:59   ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

With the refator of gic_of_init(), GICv3/4 can be initialized
by gic_init_bases() with gic distributor base address and gic
redistributor region(s).

So get the redistributor region base addresses from MADT GIC
redistributor subtable, and the distributor base address from
GICD subtable to init GICv3 irqchip in ACPI way.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
[hj: Rework this patch and fix multi issues]
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3.c | 146 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 142 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 87cf81b..11946a6 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -15,6 +15,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/acpi.h>
 #include <linux/cpu.h>
 #include <linux/cpu_pm.h>
 #include <linux/delay.h>
@@ -25,6 +26,7 @@
 #include <linux/percpu.h>
 #include <linux/slab.h>
 
+#include <linux/irqchip/arm-gic-acpi.h>
 #include <linux/irqchip/arm-gic-v3.h>
 
 #include <asm/cputype.h>
@@ -819,6 +821,16 @@ out_free:
 	return err;
 }
 
+static int __init detect_distributor(void __iomem *dist_base)
+{
+	u32 reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
+
+	if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4)
+		return -ENODEV;
+
+	return 0;
+}
+
 #ifdef CONFIG_OF
 static int __init gic_of_init(struct device_node *node, struct device_node *parent)
 {
@@ -826,7 +838,6 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 	struct redist_region *rdist_regs;
 	u64 redist_stride;
 	u32 nr_redist_regions;
-	u32 reg;
 	int err, i;
 
 	dist_base = of_iomap(node, 0);
@@ -836,11 +847,10 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 		return -ENXIO;
 	}
 
-	reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
-	if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4) {
+	err = detect_distributor(dist_base);
+	if (err) {
 		pr_err("%s: no distributor detected, giving up\n",
 			node->full_name);
-		err = -ENODEV;
 		goto out_unmap_dist;
 	}
 
@@ -888,3 +898,131 @@ out_unmap_dist:
 
 IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
 #endif
+
+#ifdef CONFIG_ACPI
+static struct redist_region *redist_regs __initdata;
+static u32 nr_redist_regions __initdata;
+static phys_addr_t dist_phy_base __initdata;
+
+static int __init
+gic_acpi_register_redist(u64 phys_base, u64 size)
+{
+	struct redist_region *redist_regs_new;
+	void __iomem *redist_base;
+
+	redist_regs_new = krealloc(redist_regs,
+				   sizeof(*redist_regs) * (nr_redist_regions + 1),
+				   GFP_KERNEL);
+	if (!redist_regs_new) {
+		pr_err("Couldn't allocate resource for GICR region\n");
+		return -ENOMEM;
+	}
+
+	redist_regs = redist_regs_new;
+
+	redist_base = ioremap(phys_base, size);
+	if (!redist_base) {
+		pr_err("Couldn't map GICR region @%llx\n", phys_base);
+		return -ENOMEM;
+	}
+
+	redist_regs[nr_redist_regions].phys_base = phys_base;
+	redist_regs[nr_redist_regions].redist_base = redist_base;
+	nr_redist_regions++;
+	return 0;
+}
+
+static int __init
+gic_acpi_parse_madt_redist(struct acpi_subtable_header *header,
+			const unsigned long end)
+{
+	struct acpi_madt_generic_redistributor *redist;
+
+	if (BAD_MADT_ENTRY(header, end))
+		return -EINVAL;
+
+	redist = (struct acpi_madt_generic_redistributor *)header;
+	if (!redist->base_address)
+		return -EINVAL;
+
+	return gic_acpi_register_redist(redist->base_address, redist->length);
+}
+
+static int __init
+gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
+				const unsigned long end)
+{
+	struct acpi_madt_generic_distributor *dist;
+
+	dist = (struct acpi_madt_generic_distributor *)header;
+
+	if (BAD_MADT_ENTRY(dist, end))
+		return -EINVAL;
+
+	dist_phy_base = dist->base_address;
+	return 0;
+}
+
+static int __init
+gic_v3_acpi_init(struct acpi_table_header *table)
+{
+	int count, i, err = 0;
+	void __iomem *dist_base;
+
+	if (acpi_gic_version() < ACPI_MADT_GIC_VER_V3)
+		return -ENODEV;
+
+	/* Get distributor base address */
+	count = acpi_parse_entries(ACPI_SIG_MADT,
+				sizeof(struct acpi_table_madt),
+				gic_acpi_parse_madt_distributor, table,
+				ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+	if (count <= 0) {
+		pr_err("No valid GICD entry exist\n");
+		return -EINVAL;
+	} else if (count > 1) {
+		pr_err("More than one GICD entry detected\n");
+		return -EINVAL;
+	}
+
+	dist_base = ioremap(dist_phy_base, ACPI_GICV3_DIST_MEM_SIZE);
+	if (!dist_base) {
+		pr_err("Unable to map GICD registers\n");
+		return -ENOMEM;
+	}
+
+	err = detect_distributor(dist_base);
+	if (err) {
+		pr_err("No distributor detected at @%p, giving up", dist_base);
+		goto out_dist_unmap;
+	}
+
+	/* Collect redistributor base addresses */
+	count = acpi_parse_entries(ACPI_SIG_MADT,
+			sizeof(struct acpi_table_madt),
+			gic_acpi_parse_madt_redist, table,
+			ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
+	if (count <= 0) {
+		pr_info("No valid GICR entries exist\n");
+		err = -EINVAL;
+		goto out_redist_unmap;
+	}
+
+	err = gic_init_bases(dist_base, redist_regs, nr_redist_regions, 0, NULL);
+	if (err)
+		goto out_redist_unmap;
+
+	irq_set_default_host(gic_data.domain);
+	return 0;
+
+out_redist_unmap:
+	for (i = 0; i < nr_redist_regions; i++)
+		if (redist_regs[i].redist_base)
+			iounmap(redist_regs[i].redist_base);
+	kfree(redist_regs);
+out_dist_unmap:
+	iounmap(dist_base);
+	return err;
+}
+IRQCHIP_ACPI_DECLARE(gic_v3, ACPI_SIG_MADT, gic_v3_acpi_init);
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 09/11] irqchip / GICv3: Add stacked irqdomain support for ACPI based init
  2015-05-18 12:59 ` Hanjun Guo
@ 2015-05-18 12:59   ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	Grant Likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi, Hanjun Guo

Similar as stacked domain support for ACPI based GICv2 init, let
acpi_irq_domain point to the core domain of GICv3 and pass the
gsi as the arg to support stacked irqdomain.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 11946a6..e7f134e 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -733,15 +733,21 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
 static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
 				unsigned int nr_irqs, void *arg)
 {
-	int i, ret;
+	int i;
 	irq_hw_number_t hwirq;
-	unsigned int type = IRQ_TYPE_NONE;
-	struct of_phandle_args *irq_data = arg;
 
-	ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args,
-				   irq_data->args_count, &hwirq, &type);
-	if (ret)
-		return ret;
+	if (domain->of_node) {	/* DT case */
+		int ret;
+		unsigned int type = IRQ_TYPE_NONE;
+		struct of_phandle_args *irq_data = arg;
+
+		ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args,
+					   irq_data->args_count, &hwirq, &type);
+		if (ret)
+			return ret;
+	} else {	/* ACPI case */
+		hwirq = (irq_hw_number_t)*(u32 *)arg;
+	}
 
 	for (i = 0; i < nr_irqs; i++)
 		gic_irq_domain_map(domain, virq + i, hwirq + i);
@@ -1012,7 +1018,7 @@ gic_v3_acpi_init(struct acpi_table_header *table)
 	if (err)
 		goto out_redist_unmap;
 
-	irq_set_default_host(gic_data.domain);
+	acpi_irq_domain = gic_data.domain;
 	return 0;
 
 out_redist_unmap:
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 09/11] irqchip / GICv3: Add stacked irqdomain support for ACPI based init
@ 2015-05-18 12:59   ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

Similar as stacked domain support for ACPI based GICv2 init, let
acpi_irq_domain point to the core domain of GICv3 and pass the
gsi as the arg to support stacked irqdomain.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 11946a6..e7f134e 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -733,15 +733,21 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
 static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
 				unsigned int nr_irqs, void *arg)
 {
-	int i, ret;
+	int i;
 	irq_hw_number_t hwirq;
-	unsigned int type = IRQ_TYPE_NONE;
-	struct of_phandle_args *irq_data = arg;
 
-	ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args,
-				   irq_data->args_count, &hwirq, &type);
-	if (ret)
-		return ret;
+	if (domain->of_node) {	/* DT case */
+		int ret;
+		unsigned int type = IRQ_TYPE_NONE;
+		struct of_phandle_args *irq_data = arg;
+
+		ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args,
+					   irq_data->args_count, &hwirq, &type);
+		if (ret)
+			return ret;
+	} else {	/* ACPI case */
+		hwirq = (irq_hw_number_t)*(u32 *)arg;
+	}
 
 	for (i = 0; i < nr_irqs; i++)
 		gic_irq_domain_map(domain, virq + i, hwirq + i);
@@ -1012,7 +1018,7 @@ gic_v3_acpi_init(struct acpi_table_header *table)
 	if (err)
 		goto out_redist_unmap;
 
-	irq_set_default_host(gic_data.domain);
+	acpi_irq_domain = gic_data.domain;
 	return 0;
 
 out_redist_unmap:
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 10/11] irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
  2015-05-18 12:59 ` Hanjun Guo
@ 2015-05-18 12:59   ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	Grant Likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi, Hanjun Guo

Move GICv2 ACPI related init code in irq-gic.c to irq-gic-acpi.c,
this can make the ACPI related GIC init code slef-contained.

Introduce set_acpi_core_irqdomain() to set acpi_irqdomain then
it will be no need to make gic_data[] as a global value, and
it will save the confilcts with GICv3's gic_data in the later
patch.

acpi_gic_parse_distributor() have the same function as
gic_acpi_parse_madt_distributor() to get the GIC distributor
physical base address, so just remove the duplicate one, and
only get the GIC version when it is unknown.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-acpi.c       |  95 +++++++++++++++++++++++++++++++-
 drivers/irqchip/irq-gic.c            | 103 +----------------------------------
 include/linux/irqchip/arm-gic-acpi.h |   5 ++
 3 files changed, 101 insertions(+), 102 deletions(-)

diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
index 1388d9e..8463e48 100644
--- a/drivers/irqchip/irq-gic-acpi.c
+++ b/drivers/irqchip/irq-gic-acpi.c
@@ -13,12 +13,16 @@
 
 #include <linux/acpi.h>
 #include <linux/init.h>
+#include <linux/irqchip/arm-gic.h>
 #include <linux/irqchip/arm-gic-acpi.h>
 #include <linux/irqchip/arm-gic-v3.h>
 
+#include "irqchip.h"
+
 /* GIC version presented in MADT GIC distributor structure */
 static u8 gic_version __initdata = ACPI_MADT_GIC_VER_UNKNOWN;
 
+/* GIC distributor physical base address, which is needed for both GICv2/3 */
 static phys_addr_t dist_phy_base __initdata;
 
 u8 __init acpi_gic_version(void)
@@ -26,6 +30,11 @@ u8 __init acpi_gic_version(void)
 	return gic_version;
 }
 
+void __init set_acpi_core_irqdomain(struct irq_domain *domain)
+{
+	acpi_irq_domain = domain;
+}
+
 static int __init
 acpi_gic_parse_distributor(struct acpi_subtable_header *header,
 				const unsigned long end)
@@ -37,8 +46,9 @@ acpi_gic_parse_distributor(struct acpi_subtable_header *header,
 	if (BAD_MADT_ENTRY(dist, end))
 		return -EINVAL;
 
-	gic_version = dist->gic_version;
 	dist_phy_base = dist->base_address;
+	if (gic_version == ACPI_MADT_GIC_VER_UNKNOWN)
+		gic_version = dist->gic_version;
 	return 0;
 }
 
@@ -114,3 +124,86 @@ int __init acpi_gic_version_init(void)
 
 	return 0;
 }
+
+static phys_addr_t cpu_phy_base __initdata;
+
+static int __init
+gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
+			const unsigned long end)
+{
+	struct acpi_madt_generic_interrupt *processor;
+	phys_addr_t gic_cpu_base;
+	static int cpu_base_assigned;
+
+	processor = (struct acpi_madt_generic_interrupt *)header;
+
+	if (BAD_MADT_ENTRY(processor, end))
+		return -EINVAL;
+
+	/*
+	 * There is no support for non-banked GICv1/2 register in ACPI spec.
+	 * All CPU interface addresses have to be the same.
+	 */
+	gic_cpu_base = processor->base_address;
+	if (cpu_base_assigned && gic_cpu_base != cpu_phy_base)
+		return -EINVAL;
+
+	cpu_phy_base = gic_cpu_base;
+	cpu_base_assigned = 1;
+	return 0;
+}
+
+static int __init
+gic_v2_acpi_init(struct acpi_table_header *table)
+{
+	void __iomem *cpu_base, *dist_base;
+	int count;
+
+	if (acpi_gic_version() >= ACPI_MADT_GIC_VER_V3)
+		return -ENODEV;
+
+	/* Collect CPU base addresses */
+	count = acpi_parse_entries(ACPI_SIG_MADT,
+				   sizeof(struct acpi_table_madt),
+				   gic_acpi_parse_madt_cpu, table,
+				   ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
+	if (count <= 0) {
+		pr_err("No valid GICC entries exist\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Find distributor base address. We expect one distributor entry since
+	 * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
+	 */
+	count = acpi_parse_entries(ACPI_SIG_MADT,
+				   sizeof(struct acpi_table_madt),
+				   acpi_gic_parse_distributor, table,
+				   ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+	if (count <= 0) {
+		pr_err("No valid GICD entries exist\n");
+		return -EINVAL;
+	} else if (count > 1) {
+		pr_err("More than one GICD entry detected\n");
+		return -EINVAL;
+	}
+
+	cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
+	if (!cpu_base) {
+		pr_err("Unable to map GICC registers\n");
+		return -ENOMEM;
+	}
+
+	dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE);
+	if (!dist_base) {
+		pr_err("Unable to map GICD registers\n");
+		iounmap(cpu_base);
+		return -ENOMEM;
+	}
+
+	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
+
+	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
+	return 0;
+}
+IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_SIG_MADT, gic_v2_acpi_init);
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 869a69f..2f934fe 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -986,6 +986,8 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 	if (WARN_ON(!gic->domain))
 		return;
 
+	set_acpi_core_irqdomain(gic->domain);
+
 	if (gic_nr == 0) {
 #ifdef CONFIG_SMP
 		set_smp_cross_call(gic_raise_softirq);
@@ -1047,104 +1049,3 @@ IRQCHIP_DECLARE(msm_8660_qgic, "qcom,msm-8660-qgic", gic_of_init);
 IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
 
 #endif
-
-#ifdef CONFIG_ACPI
-static phys_addr_t dist_phy_base, cpu_phy_base __initdata;
-
-static int __init
-gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
-			const unsigned long end)
-{
-	struct acpi_madt_generic_interrupt *processor;
-	phys_addr_t gic_cpu_base;
-	static int cpu_base_assigned;
-
-	processor = (struct acpi_madt_generic_interrupt *)header;
-
-	if (BAD_MADT_ENTRY(processor, end))
-		return -EINVAL;
-
-	/*
-	 * There is no support for non-banked GICv1/2 register in ACPI spec.
-	 * All CPU interface addresses have to be the same.
-	 */
-	gic_cpu_base = processor->base_address;
-	if (cpu_base_assigned && gic_cpu_base != cpu_phy_base)
-		return -EINVAL;
-
-	cpu_phy_base = gic_cpu_base;
-	cpu_base_assigned = 1;
-	return 0;
-}
-
-static int __init
-gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
-				const unsigned long end)
-{
-	struct acpi_madt_generic_distributor *dist;
-
-	dist = (struct acpi_madt_generic_distributor *)header;
-
-	if (BAD_MADT_ENTRY(dist, end))
-		return -EINVAL;
-
-	dist_phy_base = dist->base_address;
-	return 0;
-}
-
-static int __init
-gic_v2_acpi_init(struct acpi_table_header *table)
-{
-	void __iomem *cpu_base, *dist_base;
-	int count;
-
-	if (acpi_gic_version() >= ACPI_MADT_GIC_VER_V3)
-		return -ENODEV;
-
-	/* Collect CPU base addresses */
-	count = acpi_parse_entries(ACPI_SIG_MADT,
-				   sizeof(struct acpi_table_madt),
-				   gic_acpi_parse_madt_cpu, table,
-				   ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
-	if (count <= 0) {
-		pr_err("No valid GICC entries exist\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * Find distributor base address. We expect one distributor entry since
-	 * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
-	 */
-	count = acpi_parse_entries(ACPI_SIG_MADT,
-				   sizeof(struct acpi_table_madt),
-				   gic_acpi_parse_madt_distributor, table,
-				   ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
-	if (count <= 0) {
-		pr_err("No valid GICD entries exist\n");
-		return -EINVAL;
-	} else if (count > 1) {
-		pr_err("More than one GICD entry detected\n");
-		return -EINVAL;
-	}
-
-	cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
-	if (!cpu_base) {
-		pr_err("Unable to map GICC registers\n");
-		return -ENOMEM;
-	}
-
-	dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE);
-	if (!dist_base) {
-		pr_err("Unable to map GICD registers\n");
-		iounmap(cpu_base);
-		return -ENOMEM;
-	}
-
-	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
-	acpi_irq_domain = gic_data[0].domain;
-
-	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
-	return 0;
-}
-IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_SIG_MADT, gic_v2_acpi_init);
-#endif
diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
index 245386d..f4a17c7 100644
--- a/include/linux/irqchip/arm-gic-acpi.h
+++ b/include/linux/irqchip/arm-gic-acpi.h
@@ -25,5 +25,10 @@ extern struct irq_domain *acpi_irq_domain;
 
 int acpi_gic_version_init(void);
 u8 acpi_gic_version(void);
+
+void set_acpi_core_irqdomain(struct irq_domain *domain);
+#else
+#define set_acpi_core_irqdomain(domain)
 #endif /* CONFIG_ACPI */
+
 #endif /* ARM_GIC_ACPI_H_ */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 10/11] irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
@ 2015-05-18 12:59   ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

Move GICv2 ACPI related init code in irq-gic.c to irq-gic-acpi.c,
this can make the ACPI related GIC init code slef-contained.

Introduce set_acpi_core_irqdomain() to set acpi_irqdomain then
it will be no need to make gic_data[] as a global value, and
it will save the confilcts with GICv3's gic_data in the later
patch.

acpi_gic_parse_distributor() have the same function as
gic_acpi_parse_madt_distributor() to get the GIC distributor
physical base address, so just remove the duplicate one, and
only get the GIC version when it is unknown.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-acpi.c       |  95 +++++++++++++++++++++++++++++++-
 drivers/irqchip/irq-gic.c            | 103 +----------------------------------
 include/linux/irqchip/arm-gic-acpi.h |   5 ++
 3 files changed, 101 insertions(+), 102 deletions(-)

diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
index 1388d9e..8463e48 100644
--- a/drivers/irqchip/irq-gic-acpi.c
+++ b/drivers/irqchip/irq-gic-acpi.c
@@ -13,12 +13,16 @@
 
 #include <linux/acpi.h>
 #include <linux/init.h>
+#include <linux/irqchip/arm-gic.h>
 #include <linux/irqchip/arm-gic-acpi.h>
 #include <linux/irqchip/arm-gic-v3.h>
 
+#include "irqchip.h"
+
 /* GIC version presented in MADT GIC distributor structure */
 static u8 gic_version __initdata = ACPI_MADT_GIC_VER_UNKNOWN;
 
+/* GIC distributor physical base address, which is needed for both GICv2/3 */
 static phys_addr_t dist_phy_base __initdata;
 
 u8 __init acpi_gic_version(void)
@@ -26,6 +30,11 @@ u8 __init acpi_gic_version(void)
 	return gic_version;
 }
 
+void __init set_acpi_core_irqdomain(struct irq_domain *domain)
+{
+	acpi_irq_domain = domain;
+}
+
 static int __init
 acpi_gic_parse_distributor(struct acpi_subtable_header *header,
 				const unsigned long end)
@@ -37,8 +46,9 @@ acpi_gic_parse_distributor(struct acpi_subtable_header *header,
 	if (BAD_MADT_ENTRY(dist, end))
 		return -EINVAL;
 
-	gic_version = dist->gic_version;
 	dist_phy_base = dist->base_address;
+	if (gic_version == ACPI_MADT_GIC_VER_UNKNOWN)
+		gic_version = dist->gic_version;
 	return 0;
 }
 
@@ -114,3 +124,86 @@ int __init acpi_gic_version_init(void)
 
 	return 0;
 }
+
+static phys_addr_t cpu_phy_base __initdata;
+
+static int __init
+gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
+			const unsigned long end)
+{
+	struct acpi_madt_generic_interrupt *processor;
+	phys_addr_t gic_cpu_base;
+	static int cpu_base_assigned;
+
+	processor = (struct acpi_madt_generic_interrupt *)header;
+
+	if (BAD_MADT_ENTRY(processor, end))
+		return -EINVAL;
+
+	/*
+	 * There is no support for non-banked GICv1/2 register in ACPI spec.
+	 * All CPU interface addresses have to be the same.
+	 */
+	gic_cpu_base = processor->base_address;
+	if (cpu_base_assigned && gic_cpu_base != cpu_phy_base)
+		return -EINVAL;
+
+	cpu_phy_base = gic_cpu_base;
+	cpu_base_assigned = 1;
+	return 0;
+}
+
+static int __init
+gic_v2_acpi_init(struct acpi_table_header *table)
+{
+	void __iomem *cpu_base, *dist_base;
+	int count;
+
+	if (acpi_gic_version() >= ACPI_MADT_GIC_VER_V3)
+		return -ENODEV;
+
+	/* Collect CPU base addresses */
+	count = acpi_parse_entries(ACPI_SIG_MADT,
+				   sizeof(struct acpi_table_madt),
+				   gic_acpi_parse_madt_cpu, table,
+				   ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
+	if (count <= 0) {
+		pr_err("No valid GICC entries exist\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Find distributor base address. We expect one distributor entry since
+	 * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
+	 */
+	count = acpi_parse_entries(ACPI_SIG_MADT,
+				   sizeof(struct acpi_table_madt),
+				   acpi_gic_parse_distributor, table,
+				   ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+	if (count <= 0) {
+		pr_err("No valid GICD entries exist\n");
+		return -EINVAL;
+	} else if (count > 1) {
+		pr_err("More than one GICD entry detected\n");
+		return -EINVAL;
+	}
+
+	cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
+	if (!cpu_base) {
+		pr_err("Unable to map GICC registers\n");
+		return -ENOMEM;
+	}
+
+	dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE);
+	if (!dist_base) {
+		pr_err("Unable to map GICD registers\n");
+		iounmap(cpu_base);
+		return -ENOMEM;
+	}
+
+	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
+
+	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
+	return 0;
+}
+IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_SIG_MADT, gic_v2_acpi_init);
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 869a69f..2f934fe 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -986,6 +986,8 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 	if (WARN_ON(!gic->domain))
 		return;
 
+	set_acpi_core_irqdomain(gic->domain);
+
 	if (gic_nr == 0) {
 #ifdef CONFIG_SMP
 		set_smp_cross_call(gic_raise_softirq);
@@ -1047,104 +1049,3 @@ IRQCHIP_DECLARE(msm_8660_qgic, "qcom,msm-8660-qgic", gic_of_init);
 IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
 
 #endif
-
-#ifdef CONFIG_ACPI
-static phys_addr_t dist_phy_base, cpu_phy_base __initdata;
-
-static int __init
-gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
-			const unsigned long end)
-{
-	struct acpi_madt_generic_interrupt *processor;
-	phys_addr_t gic_cpu_base;
-	static int cpu_base_assigned;
-
-	processor = (struct acpi_madt_generic_interrupt *)header;
-
-	if (BAD_MADT_ENTRY(processor, end))
-		return -EINVAL;
-
-	/*
-	 * There is no support for non-banked GICv1/2 register in ACPI spec.
-	 * All CPU interface addresses have to be the same.
-	 */
-	gic_cpu_base = processor->base_address;
-	if (cpu_base_assigned && gic_cpu_base != cpu_phy_base)
-		return -EINVAL;
-
-	cpu_phy_base = gic_cpu_base;
-	cpu_base_assigned = 1;
-	return 0;
-}
-
-static int __init
-gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
-				const unsigned long end)
-{
-	struct acpi_madt_generic_distributor *dist;
-
-	dist = (struct acpi_madt_generic_distributor *)header;
-
-	if (BAD_MADT_ENTRY(dist, end))
-		return -EINVAL;
-
-	dist_phy_base = dist->base_address;
-	return 0;
-}
-
-static int __init
-gic_v2_acpi_init(struct acpi_table_header *table)
-{
-	void __iomem *cpu_base, *dist_base;
-	int count;
-
-	if (acpi_gic_version() >= ACPI_MADT_GIC_VER_V3)
-		return -ENODEV;
-
-	/* Collect CPU base addresses */
-	count = acpi_parse_entries(ACPI_SIG_MADT,
-				   sizeof(struct acpi_table_madt),
-				   gic_acpi_parse_madt_cpu, table,
-				   ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
-	if (count <= 0) {
-		pr_err("No valid GICC entries exist\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * Find distributor base address. We expect one distributor entry since
-	 * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
-	 */
-	count = acpi_parse_entries(ACPI_SIG_MADT,
-				   sizeof(struct acpi_table_madt),
-				   gic_acpi_parse_madt_distributor, table,
-				   ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
-	if (count <= 0) {
-		pr_err("No valid GICD entries exist\n");
-		return -EINVAL;
-	} else if (count > 1) {
-		pr_err("More than one GICD entry detected\n");
-		return -EINVAL;
-	}
-
-	cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
-	if (!cpu_base) {
-		pr_err("Unable to map GICC registers\n");
-		return -ENOMEM;
-	}
-
-	dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE);
-	if (!dist_base) {
-		pr_err("Unable to map GICD registers\n");
-		iounmap(cpu_base);
-		return -ENOMEM;
-	}
-
-	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
-	acpi_irq_domain = gic_data[0].domain;
-
-	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
-	return 0;
-}
-IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_SIG_MADT, gic_v2_acpi_init);
-#endif
diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
index 245386d..f4a17c7 100644
--- a/include/linux/irqchip/arm-gic-acpi.h
+++ b/include/linux/irqchip/arm-gic-acpi.h
@@ -25,5 +25,10 @@ extern struct irq_domain *acpi_irq_domain;
 
 int acpi_gic_version_init(void);
 u8 acpi_gic_version(void);
+
+void set_acpi_core_irqdomain(struct irq_domain *domain);
+#else
+#define set_acpi_core_irqdomain(domain)
 #endif /* CONFIG_ACPI */
+
 #endif /* ARM_GIC_ACPI_H_ */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 11/11] irqchip / GICv3 / ACPI: Consolidate GICv3 ACPI related init code
  2015-05-18 12:59 ` Hanjun Guo
@ 2015-05-18 12:59   ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	Grant Likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi, Hanjun Guo

Move GICv3 ACPI related init code in irq-gic.c to irq-gic-acpi.c,
this can make the ACPI related GIC init code slef-contained as GICV2
did.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-acpi.c     | 109 +++++++++++++++++++++++++++++
 drivers/irqchip/irq-gic-v3.c       | 140 ++-----------------------------------
 include/linux/irqchip/arm-gic-v3.h |  10 +++
 3 files changed, 123 insertions(+), 136 deletions(-)

diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
index 8463e48..75c4893 100644
--- a/drivers/irqchip/irq-gic-acpi.c
+++ b/drivers/irqchip/irq-gic-acpi.c
@@ -207,3 +207,112 @@ gic_v2_acpi_init(struct acpi_table_header *table)
 	return 0;
 }
 IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_SIG_MADT, gic_v2_acpi_init);
+
+static struct redist_region *redist_regs __initdata;
+static u32 nr_redist_regions __initdata;
+
+static int __init
+gic_acpi_register_redist(u64 phys_base, u64 size)
+{
+	struct redist_region *redist_regs_new;
+	void __iomem *redist_base;
+
+	redist_regs_new = krealloc(redist_regs,
+				   sizeof(*redist_regs) * (nr_redist_regions + 1),
+				   GFP_KERNEL);
+	if (!redist_regs_new) {
+		pr_err("Couldn't allocate resource for GICR region\n");
+		return -ENOMEM;
+	}
+
+	redist_regs = redist_regs_new;
+
+	redist_base = ioremap(phys_base, size);
+	if (!redist_base) {
+		pr_err("Couldn't map GICR region @%llx\n", phys_base);
+		return -ENOMEM;
+	}
+
+	redist_regs[nr_redist_regions].phys_base = phys_base;
+	redist_regs[nr_redist_regions].redist_base = redist_base;
+	nr_redist_regions++;
+	return 0;
+}
+
+static int __init
+gic_acpi_parse_madt_redist(struct acpi_subtable_header *header,
+			const unsigned long end)
+{
+	struct acpi_madt_generic_redistributor *redist;
+
+	if (BAD_MADT_ENTRY(header, end))
+		return -EINVAL;
+
+	redist = (struct acpi_madt_generic_redistributor *)header;
+	if (!redist->base_address)
+		return -EINVAL;
+
+	return gic_acpi_register_redist(redist->base_address, redist->length);
+}
+
+static int __init
+gic_v3_acpi_init(struct acpi_table_header *table)
+{
+	int count, i, err = 0;
+	void __iomem *dist_base;
+
+	if (acpi_gic_version() < ACPI_MADT_GIC_VER_V3)
+		return -ENODEV;
+
+	/* Get distributor base address */
+	count = acpi_parse_entries(ACPI_SIG_MADT,
+				sizeof(struct acpi_table_madt),
+				acpi_gic_parse_distributor, table,
+				ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+	if (count <= 0) {
+		pr_err("No valid GICD entry exist\n");
+		return -EINVAL;
+	} else if (count > 1) {
+		pr_err("More than one GICD entry detected\n");
+		return -EINVAL;
+	}
+
+	dist_base = ioremap(dist_phy_base, ACPI_GICV3_DIST_MEM_SIZE);
+	if (!dist_base) {
+		pr_err("Unable to map GICD registers\n");
+		return -ENOMEM;
+	}
+
+	err = detect_distributor(dist_base);
+	if (err) {
+		pr_err("No distributor detected at @%p, giving up", dist_base);
+		goto out_dist_unmap;
+	}
+
+	/* Collect redistributor base addresses */
+	count = acpi_parse_entries(ACPI_SIG_MADT,
+			sizeof(struct acpi_table_madt),
+			gic_acpi_parse_madt_redist, table,
+			ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
+	if (count <= 0) {
+		pr_info("No valid GICR entries exist\n");
+		err = -EINVAL;
+		goto out_redist_unmap;
+	}
+
+	err = gicv3_init_bases(dist_base, redist_regs, nr_redist_regions, 0, NULL);
+	if (err)
+		goto out_redist_unmap;
+
+	return 0;
+
+out_redist_unmap:
+	for (i = 0; i < nr_redist_regions; i++)
+		if (redist_regs[i].redist_base)
+			iounmap(redist_regs[i].redist_base);
+	kfree(redist_regs);
+out_dist_unmap:
+	iounmap(dist_base);
+	return err;
+}
+IRQCHIP_ACPI_DECLARE(gic_v3, ACPI_SIG_MADT, gic_v3_acpi_init);
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index e7f134e..a8382f4 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -36,11 +36,6 @@
 #include "irq-gic-common.h"
 #include "irqchip.h"
 
-struct redist_region {
-	void __iomem		*redist_base;
-	phys_addr_t		phys_base;
-};
-
 struct gic_chip_data {
 	void __iomem		*dist_base;
 	struct redist_region	*redist_regions;
@@ -773,7 +768,7 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
 	.free = gic_irq_domain_free,
 };
 
-static int __init gic_init_bases(void __iomem *dist_base,
+int __init gicv3_init_bases(void __iomem *dist_base,
 			    struct redist_region *rdist_regs,
 			    u32 nr_redist_regions,
 			    u64 redist_stride,
@@ -808,6 +803,7 @@ static int __init gic_init_bases(void __iomem *dist_base,
 		goto out_free;
 	}
 
+	set_acpi_core_irqdomain(gic_data.domain);
 	set_handle_irq(gic_handle_irq);
 
 	if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
@@ -827,7 +823,7 @@ out_free:
 	return err;
 }
 
-static int __init detect_distributor(void __iomem *dist_base)
+int __init detect_distributor(void __iomem *dist_base)
 {
 	u32 reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
 
@@ -887,7 +883,7 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 	if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
 		redist_stride = 0;
 
-	err = gic_init_bases(dist_base, rdist_regs, nr_redist_regions,
+	err = gicv3_init_bases(dist_base, rdist_regs, nr_redist_regions,
 			     redist_stride, node);
 	if (!err)
 		return 0;
@@ -904,131 +900,3 @@ out_unmap_dist:
 
 IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
 #endif
-
-#ifdef CONFIG_ACPI
-static struct redist_region *redist_regs __initdata;
-static u32 nr_redist_regions __initdata;
-static phys_addr_t dist_phy_base __initdata;
-
-static int __init
-gic_acpi_register_redist(u64 phys_base, u64 size)
-{
-	struct redist_region *redist_regs_new;
-	void __iomem *redist_base;
-
-	redist_regs_new = krealloc(redist_regs,
-				   sizeof(*redist_regs) * (nr_redist_regions + 1),
-				   GFP_KERNEL);
-	if (!redist_regs_new) {
-		pr_err("Couldn't allocate resource for GICR region\n");
-		return -ENOMEM;
-	}
-
-	redist_regs = redist_regs_new;
-
-	redist_base = ioremap(phys_base, size);
-	if (!redist_base) {
-		pr_err("Couldn't map GICR region @%llx\n", phys_base);
-		return -ENOMEM;
-	}
-
-	redist_regs[nr_redist_regions].phys_base = phys_base;
-	redist_regs[nr_redist_regions].redist_base = redist_base;
-	nr_redist_regions++;
-	return 0;
-}
-
-static int __init
-gic_acpi_parse_madt_redist(struct acpi_subtable_header *header,
-			const unsigned long end)
-{
-	struct acpi_madt_generic_redistributor *redist;
-
-	if (BAD_MADT_ENTRY(header, end))
-		return -EINVAL;
-
-	redist = (struct acpi_madt_generic_redistributor *)header;
-	if (!redist->base_address)
-		return -EINVAL;
-
-	return gic_acpi_register_redist(redist->base_address, redist->length);
-}
-
-static int __init
-gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
-				const unsigned long end)
-{
-	struct acpi_madt_generic_distributor *dist;
-
-	dist = (struct acpi_madt_generic_distributor *)header;
-
-	if (BAD_MADT_ENTRY(dist, end))
-		return -EINVAL;
-
-	dist_phy_base = dist->base_address;
-	return 0;
-}
-
-static int __init
-gic_v3_acpi_init(struct acpi_table_header *table)
-{
-	int count, i, err = 0;
-	void __iomem *dist_base;
-
-	if (acpi_gic_version() < ACPI_MADT_GIC_VER_V3)
-		return -ENODEV;
-
-	/* Get distributor base address */
-	count = acpi_parse_entries(ACPI_SIG_MADT,
-				sizeof(struct acpi_table_madt),
-				gic_acpi_parse_madt_distributor, table,
-				ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
-	if (count <= 0) {
-		pr_err("No valid GICD entry exist\n");
-		return -EINVAL;
-	} else if (count > 1) {
-		pr_err("More than one GICD entry detected\n");
-		return -EINVAL;
-	}
-
-	dist_base = ioremap(dist_phy_base, ACPI_GICV3_DIST_MEM_SIZE);
-	if (!dist_base) {
-		pr_err("Unable to map GICD registers\n");
-		return -ENOMEM;
-	}
-
-	err = detect_distributor(dist_base);
-	if (err) {
-		pr_err("No distributor detected at @%p, giving up", dist_base);
-		goto out_dist_unmap;
-	}
-
-	/* Collect redistributor base addresses */
-	count = acpi_parse_entries(ACPI_SIG_MADT,
-			sizeof(struct acpi_table_madt),
-			gic_acpi_parse_madt_redist, table,
-			ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
-	if (count <= 0) {
-		pr_info("No valid GICR entries exist\n");
-		err = -EINVAL;
-		goto out_redist_unmap;
-	}
-
-	err = gic_init_bases(dist_base, redist_regs, nr_redist_regions, 0, NULL);
-	if (err)
-		goto out_redist_unmap;
-
-	acpi_irq_domain = gic_data.domain;
-	return 0;
-
-out_redist_unmap:
-	for (i = 0; i < nr_redist_regions; i++)
-		if (redist_regs[i].redist_base)
-			iounmap(redist_regs[i].redist_base);
-	kfree(redist_regs);
-out_dist_unmap:
-	iounmap(dist_base);
-	return err;
-}
-IRQCHIP_ACPI_DECLARE(gic_v3, ACPI_SIG_MADT, gic_v3_acpi_init);
-#endif
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index ffbc034..37ef420 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -378,6 +378,11 @@ struct rdists {
 	u64			flags;
 };
 
+struct redist_region {
+	void __iomem            *redist_base;
+	phys_addr_t             phys_base;
+};
+
 static inline void gic_write_eoir(u64 irq)
 {
 	asm volatile("msr_s " __stringify(ICC_EOIR1_EL1) ", %0" : : "r" (irq));
@@ -389,6 +394,11 @@ int its_cpu_init(void);
 int its_init(struct device_node *node, struct rdists *rdists,
 	     struct irq_domain *domain);
 
+int gicv3_init_bases(void __iomem *dist_base, struct redist_region *rdist_regs,
+		     u32 nr_redist_regions, u64 redist_stride,
+		     struct device_node *node);
+
+int detect_distributor(void __iomem *dist_base);
 #endif
 
 #endif
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [PATCH 11/11] irqchip / GICv3 / ACPI: Consolidate GICv3 ACPI related init code
@ 2015-05-18 12:59   ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-18 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

Move GICv3 ACPI related init code in irq-gic.c to irq-gic-acpi.c,
this can make the ACPI related GIC init code slef-contained as GICV2
did.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-acpi.c     | 109 +++++++++++++++++++++++++++++
 drivers/irqchip/irq-gic-v3.c       | 140 ++-----------------------------------
 include/linux/irqchip/arm-gic-v3.h |  10 +++
 3 files changed, 123 insertions(+), 136 deletions(-)

diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
index 8463e48..75c4893 100644
--- a/drivers/irqchip/irq-gic-acpi.c
+++ b/drivers/irqchip/irq-gic-acpi.c
@@ -207,3 +207,112 @@ gic_v2_acpi_init(struct acpi_table_header *table)
 	return 0;
 }
 IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_SIG_MADT, gic_v2_acpi_init);
+
+static struct redist_region *redist_regs __initdata;
+static u32 nr_redist_regions __initdata;
+
+static int __init
+gic_acpi_register_redist(u64 phys_base, u64 size)
+{
+	struct redist_region *redist_regs_new;
+	void __iomem *redist_base;
+
+	redist_regs_new = krealloc(redist_regs,
+				   sizeof(*redist_regs) * (nr_redist_regions + 1),
+				   GFP_KERNEL);
+	if (!redist_regs_new) {
+		pr_err("Couldn't allocate resource for GICR region\n");
+		return -ENOMEM;
+	}
+
+	redist_regs = redist_regs_new;
+
+	redist_base = ioremap(phys_base, size);
+	if (!redist_base) {
+		pr_err("Couldn't map GICR region @%llx\n", phys_base);
+		return -ENOMEM;
+	}
+
+	redist_regs[nr_redist_regions].phys_base = phys_base;
+	redist_regs[nr_redist_regions].redist_base = redist_base;
+	nr_redist_regions++;
+	return 0;
+}
+
+static int __init
+gic_acpi_parse_madt_redist(struct acpi_subtable_header *header,
+			const unsigned long end)
+{
+	struct acpi_madt_generic_redistributor *redist;
+
+	if (BAD_MADT_ENTRY(header, end))
+		return -EINVAL;
+
+	redist = (struct acpi_madt_generic_redistributor *)header;
+	if (!redist->base_address)
+		return -EINVAL;
+
+	return gic_acpi_register_redist(redist->base_address, redist->length);
+}
+
+static int __init
+gic_v3_acpi_init(struct acpi_table_header *table)
+{
+	int count, i, err = 0;
+	void __iomem *dist_base;
+
+	if (acpi_gic_version() < ACPI_MADT_GIC_VER_V3)
+		return -ENODEV;
+
+	/* Get distributor base address */
+	count = acpi_parse_entries(ACPI_SIG_MADT,
+				sizeof(struct acpi_table_madt),
+				acpi_gic_parse_distributor, table,
+				ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+	if (count <= 0) {
+		pr_err("No valid GICD entry exist\n");
+		return -EINVAL;
+	} else if (count > 1) {
+		pr_err("More than one GICD entry detected\n");
+		return -EINVAL;
+	}
+
+	dist_base = ioremap(dist_phy_base, ACPI_GICV3_DIST_MEM_SIZE);
+	if (!dist_base) {
+		pr_err("Unable to map GICD registers\n");
+		return -ENOMEM;
+	}
+
+	err = detect_distributor(dist_base);
+	if (err) {
+		pr_err("No distributor detected at @%p, giving up", dist_base);
+		goto out_dist_unmap;
+	}
+
+	/* Collect redistributor base addresses */
+	count = acpi_parse_entries(ACPI_SIG_MADT,
+			sizeof(struct acpi_table_madt),
+			gic_acpi_parse_madt_redist, table,
+			ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
+	if (count <= 0) {
+		pr_info("No valid GICR entries exist\n");
+		err = -EINVAL;
+		goto out_redist_unmap;
+	}
+
+	err = gicv3_init_bases(dist_base, redist_regs, nr_redist_regions, 0, NULL);
+	if (err)
+		goto out_redist_unmap;
+
+	return 0;
+
+out_redist_unmap:
+	for (i = 0; i < nr_redist_regions; i++)
+		if (redist_regs[i].redist_base)
+			iounmap(redist_regs[i].redist_base);
+	kfree(redist_regs);
+out_dist_unmap:
+	iounmap(dist_base);
+	return err;
+}
+IRQCHIP_ACPI_DECLARE(gic_v3, ACPI_SIG_MADT, gic_v3_acpi_init);
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index e7f134e..a8382f4 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -36,11 +36,6 @@
 #include "irq-gic-common.h"
 #include "irqchip.h"
 
-struct redist_region {
-	void __iomem		*redist_base;
-	phys_addr_t		phys_base;
-};
-
 struct gic_chip_data {
 	void __iomem		*dist_base;
 	struct redist_region	*redist_regions;
@@ -773,7 +768,7 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
 	.free = gic_irq_domain_free,
 };
 
-static int __init gic_init_bases(void __iomem *dist_base,
+int __init gicv3_init_bases(void __iomem *dist_base,
 			    struct redist_region *rdist_regs,
 			    u32 nr_redist_regions,
 			    u64 redist_stride,
@@ -808,6 +803,7 @@ static int __init gic_init_bases(void __iomem *dist_base,
 		goto out_free;
 	}
 
+	set_acpi_core_irqdomain(gic_data.domain);
 	set_handle_irq(gic_handle_irq);
 
 	if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
@@ -827,7 +823,7 @@ out_free:
 	return err;
 }
 
-static int __init detect_distributor(void __iomem *dist_base)
+int __init detect_distributor(void __iomem *dist_base)
 {
 	u32 reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
 
@@ -887,7 +883,7 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 	if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
 		redist_stride = 0;
 
-	err = gic_init_bases(dist_base, rdist_regs, nr_redist_regions,
+	err = gicv3_init_bases(dist_base, rdist_regs, nr_redist_regions,
 			     redist_stride, node);
 	if (!err)
 		return 0;
@@ -904,131 +900,3 @@ out_unmap_dist:
 
 IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
 #endif
-
-#ifdef CONFIG_ACPI
-static struct redist_region *redist_regs __initdata;
-static u32 nr_redist_regions __initdata;
-static phys_addr_t dist_phy_base __initdata;
-
-static int __init
-gic_acpi_register_redist(u64 phys_base, u64 size)
-{
-	struct redist_region *redist_regs_new;
-	void __iomem *redist_base;
-
-	redist_regs_new = krealloc(redist_regs,
-				   sizeof(*redist_regs) * (nr_redist_regions + 1),
-				   GFP_KERNEL);
-	if (!redist_regs_new) {
-		pr_err("Couldn't allocate resource for GICR region\n");
-		return -ENOMEM;
-	}
-
-	redist_regs = redist_regs_new;
-
-	redist_base = ioremap(phys_base, size);
-	if (!redist_base) {
-		pr_err("Couldn't map GICR region @%llx\n", phys_base);
-		return -ENOMEM;
-	}
-
-	redist_regs[nr_redist_regions].phys_base = phys_base;
-	redist_regs[nr_redist_regions].redist_base = redist_base;
-	nr_redist_regions++;
-	return 0;
-}
-
-static int __init
-gic_acpi_parse_madt_redist(struct acpi_subtable_header *header,
-			const unsigned long end)
-{
-	struct acpi_madt_generic_redistributor *redist;
-
-	if (BAD_MADT_ENTRY(header, end))
-		return -EINVAL;
-
-	redist = (struct acpi_madt_generic_redistributor *)header;
-	if (!redist->base_address)
-		return -EINVAL;
-
-	return gic_acpi_register_redist(redist->base_address, redist->length);
-}
-
-static int __init
-gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
-				const unsigned long end)
-{
-	struct acpi_madt_generic_distributor *dist;
-
-	dist = (struct acpi_madt_generic_distributor *)header;
-
-	if (BAD_MADT_ENTRY(dist, end))
-		return -EINVAL;
-
-	dist_phy_base = dist->base_address;
-	return 0;
-}
-
-static int __init
-gic_v3_acpi_init(struct acpi_table_header *table)
-{
-	int count, i, err = 0;
-	void __iomem *dist_base;
-
-	if (acpi_gic_version() < ACPI_MADT_GIC_VER_V3)
-		return -ENODEV;
-
-	/* Get distributor base address */
-	count = acpi_parse_entries(ACPI_SIG_MADT,
-				sizeof(struct acpi_table_madt),
-				gic_acpi_parse_madt_distributor, table,
-				ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
-	if (count <= 0) {
-		pr_err("No valid GICD entry exist\n");
-		return -EINVAL;
-	} else if (count > 1) {
-		pr_err("More than one GICD entry detected\n");
-		return -EINVAL;
-	}
-
-	dist_base = ioremap(dist_phy_base, ACPI_GICV3_DIST_MEM_SIZE);
-	if (!dist_base) {
-		pr_err("Unable to map GICD registers\n");
-		return -ENOMEM;
-	}
-
-	err = detect_distributor(dist_base);
-	if (err) {
-		pr_err("No distributor detected at @%p, giving up", dist_base);
-		goto out_dist_unmap;
-	}
-
-	/* Collect redistributor base addresses */
-	count = acpi_parse_entries(ACPI_SIG_MADT,
-			sizeof(struct acpi_table_madt),
-			gic_acpi_parse_madt_redist, table,
-			ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
-	if (count <= 0) {
-		pr_info("No valid GICR entries exist\n");
-		err = -EINVAL;
-		goto out_redist_unmap;
-	}
-
-	err = gic_init_bases(dist_base, redist_regs, nr_redist_regions, 0, NULL);
-	if (err)
-		goto out_redist_unmap;
-
-	acpi_irq_domain = gic_data.domain;
-	return 0;
-
-out_redist_unmap:
-	for (i = 0; i < nr_redist_regions; i++)
-		if (redist_regs[i].redist_base)
-			iounmap(redist_regs[i].redist_base);
-	kfree(redist_regs);
-out_dist_unmap:
-	iounmap(dist_base);
-	return err;
-}
-IRQCHIP_ACPI_DECLARE(gic_v3, ACPI_SIG_MADT, gic_v3_acpi_init);
-#endif
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index ffbc034..37ef420 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -378,6 +378,11 @@ struct rdists {
 	u64			flags;
 };
 
+struct redist_region {
+	void __iomem            *redist_base;
+	phys_addr_t             phys_base;
+};
+
 static inline void gic_write_eoir(u64 irq)
 {
 	asm volatile("msr_s " __stringify(ICC_EOIR1_EL1) ", %0" : : "r" (irq));
@@ -389,6 +394,11 @@ int its_cpu_init(void);
 int its_init(struct device_node *node, struct rdists *rdists,
 	     struct irq_domain *domain);
 
+int gicv3_init_bases(void __iomem *dist_base, struct redist_region *rdist_regs,
+		     u32 nr_redist_regions, u64 redist_stride,
+		     struct device_node *node);
+
+int detect_distributor(void __iomem *dist_base);
 #endif
 
 #endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* Re: [PATCH 03/11] irqchip / GIC: Add GIC version support in ACPI MADT
  2015-05-18 12:59   ` Hanjun Guo
@ 2015-05-20 20:02     ` Thomas Gleixner
  -1 siblings, 0 replies; 75+ messages in thread
From: Thomas Gleixner @ 2015-05-20 20:02 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki, Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann,
	Tomasz Nowicki, Grant Likely, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On Mon, 18 May 2015, Hanjun Guo wrote:
> diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
> index 65d6b93..855ead9 100644
> --- a/drivers/acpi/irq.c
> +++ b/drivers/acpi/irq.c
> @@ -32,6 +32,9 @@ void __init acpi_irqchip_init(void)
>  	if (acpi_disabled)
>  		return;
>  
> +	if (acpi_gic_version_init())
> +		return;

This looks just wrong. acpi_irqchip_init() is a generic ACPI function
and now you stick a GIC specific callback into it?

What calls acpi_irqchip_init?

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 03/11] irqchip / GIC: Add GIC version support in ACPI MADT
@ 2015-05-20 20:02     ` Thomas Gleixner
  0 siblings, 0 replies; 75+ messages in thread
From: Thomas Gleixner @ 2015-05-20 20:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 18 May 2015, Hanjun Guo wrote:
> diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
> index 65d6b93..855ead9 100644
> --- a/drivers/acpi/irq.c
> +++ b/drivers/acpi/irq.c
> @@ -32,6 +32,9 @@ void __init acpi_irqchip_init(void)
>  	if (acpi_disabled)
>  		return;
>  
> +	if (acpi_gic_version_init())
> +		return;

This looks just wrong. acpi_irqchip_init() is a generic ACPI function
and now you stick a GIC specific callback into it?

What calls acpi_irqchip_init?

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 10/11] irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
  2015-05-18 12:59   ` Hanjun Guo
@ 2015-05-20 20:44     ` Tomasz Nowicki
  -1 siblings, 0 replies; 75+ messages in thread
From: Tomasz Nowicki @ 2015-05-20 20:44 UTC (permalink / raw)
  To: Hanjun Guo, Marc Zyngier, Jason Cooper, Will Deacon,
	Catalin Marinas, Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Grant Likely,
	Thomas Gleixner, Olof Johansson, linux-arm-kernel, linux-acpi,
	linux-kernel, linaro-acpi

Hi Hanjun,

On 05/18/2015 02:59 PM, Hanjun Guo wrote:
> Move GICv2 ACPI related init code in irq-gic.c to irq-gic-acpi.c,
> this can make the ACPI related GIC init code slef-contained.
>
> Introduce set_acpi_core_irqdomain() to set acpi_irqdomain then
> it will be no need to make gic_data[] as a global value, and
> it will save the confilcts with GICv3's gic_data in the later
> patch.
>
> acpi_gic_parse_distributor() have the same function as
> gic_acpi_parse_madt_distributor() to get the GIC distributor
> physical base address, so just remove the duplicate one, and
> only get the GIC version when it is unknown.
>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>   drivers/irqchip/irq-gic-acpi.c       |  95 +++++++++++++++++++++++++++++++-
>   drivers/irqchip/irq-gic.c            | 103 +----------------------------------
>   include/linux/irqchip/arm-gic-acpi.h |   5 ++
>   3 files changed, 101 insertions(+), 102 deletions(-)
>
> diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
> index 1388d9e..8463e48 100644
> --- a/drivers/irqchip/irq-gic-acpi.c
> +++ b/drivers/irqchip/irq-gic-acpi.c
> @@ -13,12 +13,16 @@
>
>   #include <linux/acpi.h>
>   #include <linux/init.h>
> +#include <linux/irqchip/arm-gic.h>
>   #include <linux/irqchip/arm-gic-acpi.h>
>   #include <linux/irqchip/arm-gic-v3.h>

arm-gic.h and arm-gic-v3.h describe register map for respective drivers 
and should be used separately within parent driver only.

Tomasz

>
> +#include "irqchip.h"
> +
>   /* GIC version presented in MADT GIC distributor structure */
>   static u8 gic_version __initdata = ACPI_MADT_GIC_VER_UNKNOWN;
>
> +/* GIC distributor physical base address, which is needed for both GICv2/3 */
>   static phys_addr_t dist_phy_base __initdata;
>
>   u8 __init acpi_gic_version(void)
> @@ -26,6 +30,11 @@ u8 __init acpi_gic_version(void)
>   	return gic_version;
>   }
>
> +void __init set_acpi_core_irqdomain(struct irq_domain *domain)
> +{
> +	acpi_irq_domain = domain;
> +}
> +
>   static int __init
>   acpi_gic_parse_distributor(struct acpi_subtable_header *header,
>   				const unsigned long end)
> @@ -37,8 +46,9 @@ acpi_gic_parse_distributor(struct acpi_subtable_header *header,
>   	if (BAD_MADT_ENTRY(dist, end))
>   		return -EINVAL;
>
> -	gic_version = dist->gic_version;
>   	dist_phy_base = dist->base_address;
> +	if (gic_version == ACPI_MADT_GIC_VER_UNKNOWN)
> +		gic_version = dist->gic_version;
>   	return 0;
>   }
>
> @@ -114,3 +124,86 @@ int __init acpi_gic_version_init(void)
>
>   	return 0;
>   }
> +
> +static phys_addr_t cpu_phy_base __initdata;
> +
> +static int __init
> +gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
> +			const unsigned long end)
> +{
> +	struct acpi_madt_generic_interrupt *processor;
> +	phys_addr_t gic_cpu_base;
> +	static int cpu_base_assigned;
> +
> +	processor = (struct acpi_madt_generic_interrupt *)header;
> +
> +	if (BAD_MADT_ENTRY(processor, end))
> +		return -EINVAL;
> +
> +	/*
> +	 * There is no support for non-banked GICv1/2 register in ACPI spec.
> +	 * All CPU interface addresses have to be the same.
> +	 */
> +	gic_cpu_base = processor->base_address;
> +	if (cpu_base_assigned && gic_cpu_base != cpu_phy_base)
> +		return -EINVAL;
> +
> +	cpu_phy_base = gic_cpu_base;
> +	cpu_base_assigned = 1;
> +	return 0;
> +}
> +
> +static int __init
> +gic_v2_acpi_init(struct acpi_table_header *table)
> +{
> +	void __iomem *cpu_base, *dist_base;
> +	int count;
> +
> +	if (acpi_gic_version() >= ACPI_MADT_GIC_VER_V3)
> +		return -ENODEV;
> +
> +	/* Collect CPU base addresses */
> +	count = acpi_parse_entries(ACPI_SIG_MADT,
> +				   sizeof(struct acpi_table_madt),
> +				   gic_acpi_parse_madt_cpu, table,
> +				   ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
> +	if (count <= 0) {
> +		pr_err("No valid GICC entries exist\n");
> +		return -EINVAL;
> +	}
> +
> +	/*
> +	 * Find distributor base address. We expect one distributor entry since
> +	 * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
> +	 */
> +	count = acpi_parse_entries(ACPI_SIG_MADT,
> +				   sizeof(struct acpi_table_madt),
> +				   acpi_gic_parse_distributor, table,
> +				   ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
> +	if (count <= 0) {
> +		pr_err("No valid GICD entries exist\n");
> +		return -EINVAL;
> +	} else if (count > 1) {
> +		pr_err("More than one GICD entry detected\n");
> +		return -EINVAL;
> +	}
> +
> +	cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
> +	if (!cpu_base) {
> +		pr_err("Unable to map GICC registers\n");
> +		return -ENOMEM;
> +	}
> +
> +	dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE);
> +	if (!dist_base) {
> +		pr_err("Unable to map GICD registers\n");
> +		iounmap(cpu_base);
> +		return -ENOMEM;
> +	}
> +
> +	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
> +
> +	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
> +	return 0;
> +}
> +IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_SIG_MADT, gic_v2_acpi_init);
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index 869a69f..2f934fe 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -986,6 +986,8 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>   	if (WARN_ON(!gic->domain))
>   		return;
>
> +	set_acpi_core_irqdomain(gic->domain);
> +
>   	if (gic_nr == 0) {
>   #ifdef CONFIG_SMP
>   		set_smp_cross_call(gic_raise_softirq);
> @@ -1047,104 +1049,3 @@ IRQCHIP_DECLARE(msm_8660_qgic, "qcom,msm-8660-qgic", gic_of_init);
>   IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
>
>   #endif
> -
> -#ifdef CONFIG_ACPI
> -static phys_addr_t dist_phy_base, cpu_phy_base __initdata;
> -
> -static int __init
> -gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
> -			const unsigned long end)
> -{
> -	struct acpi_madt_generic_interrupt *processor;
> -	phys_addr_t gic_cpu_base;
> -	static int cpu_base_assigned;
> -
> -	processor = (struct acpi_madt_generic_interrupt *)header;
> -
> -	if (BAD_MADT_ENTRY(processor, end))
> -		return -EINVAL;
> -
> -	/*
> -	 * There is no support for non-banked GICv1/2 register in ACPI spec.
> -	 * All CPU interface addresses have to be the same.
> -	 */
> -	gic_cpu_base = processor->base_address;
> -	if (cpu_base_assigned && gic_cpu_base != cpu_phy_base)
> -		return -EINVAL;
> -
> -	cpu_phy_base = gic_cpu_base;
> -	cpu_base_assigned = 1;
> -	return 0;
> -}
> -
> -static int __init
> -gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
> -				const unsigned long end)
> -{
> -	struct acpi_madt_generic_distributor *dist;
> -
> -	dist = (struct acpi_madt_generic_distributor *)header;
> -
> -	if (BAD_MADT_ENTRY(dist, end))
> -		return -EINVAL;
> -
> -	dist_phy_base = dist->base_address;
> -	return 0;
> -}
> -
> -static int __init
> -gic_v2_acpi_init(struct acpi_table_header *table)
> -{
> -	void __iomem *cpu_base, *dist_base;
> -	int count;
> -
> -	if (acpi_gic_version() >= ACPI_MADT_GIC_VER_V3)
> -		return -ENODEV;
> -
> -	/* Collect CPU base addresses */
> -	count = acpi_parse_entries(ACPI_SIG_MADT,
> -				   sizeof(struct acpi_table_madt),
> -				   gic_acpi_parse_madt_cpu, table,
> -				   ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
> -	if (count <= 0) {
> -		pr_err("No valid GICC entries exist\n");
> -		return -EINVAL;
> -	}
> -
> -	/*
> -	 * Find distributor base address. We expect one distributor entry since
> -	 * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
> -	 */
> -	count = acpi_parse_entries(ACPI_SIG_MADT,
> -				   sizeof(struct acpi_table_madt),
> -				   gic_acpi_parse_madt_distributor, table,
> -				   ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
> -	if (count <= 0) {
> -		pr_err("No valid GICD entries exist\n");
> -		return -EINVAL;
> -	} else if (count > 1) {
> -		pr_err("More than one GICD entry detected\n");
> -		return -EINVAL;
> -	}
> -
> -	cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
> -	if (!cpu_base) {
> -		pr_err("Unable to map GICC registers\n");
> -		return -ENOMEM;
> -	}
> -
> -	dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE);
> -	if (!dist_base) {
> -		pr_err("Unable to map GICD registers\n");
> -		iounmap(cpu_base);
> -		return -ENOMEM;
> -	}
> -
> -	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
> -	acpi_irq_domain = gic_data[0].domain;
> -
> -	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
> -	return 0;
> -}
> -IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_SIG_MADT, gic_v2_acpi_init);
> -#endif
> diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
> index 245386d..f4a17c7 100644
> --- a/include/linux/irqchip/arm-gic-acpi.h
> +++ b/include/linux/irqchip/arm-gic-acpi.h
> @@ -25,5 +25,10 @@ extern struct irq_domain *acpi_irq_domain;
>
>   int acpi_gic_version_init(void);
>   u8 acpi_gic_version(void);
> +
> +void set_acpi_core_irqdomain(struct irq_domain *domain);
> +#else
> +#define set_acpi_core_irqdomain(domain)
>   #endif /* CONFIG_ACPI */
> +
>   #endif /* ARM_GIC_ACPI_H_ */
>

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 10/11] irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
@ 2015-05-20 20:44     ` Tomasz Nowicki
  0 siblings, 0 replies; 75+ messages in thread
From: Tomasz Nowicki @ 2015-05-20 20:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Hanjun,

On 05/18/2015 02:59 PM, Hanjun Guo wrote:
> Move GICv2 ACPI related init code in irq-gic.c to irq-gic-acpi.c,
> this can make the ACPI related GIC init code slef-contained.
>
> Introduce set_acpi_core_irqdomain() to set acpi_irqdomain then
> it will be no need to make gic_data[] as a global value, and
> it will save the confilcts with GICv3's gic_data in the later
> patch.
>
> acpi_gic_parse_distributor() have the same function as
> gic_acpi_parse_madt_distributor() to get the GIC distributor
> physical base address, so just remove the duplicate one, and
> only get the GIC version when it is unknown.
>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>   drivers/irqchip/irq-gic-acpi.c       |  95 +++++++++++++++++++++++++++++++-
>   drivers/irqchip/irq-gic.c            | 103 +----------------------------------
>   include/linux/irqchip/arm-gic-acpi.h |   5 ++
>   3 files changed, 101 insertions(+), 102 deletions(-)
>
> diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
> index 1388d9e..8463e48 100644
> --- a/drivers/irqchip/irq-gic-acpi.c
> +++ b/drivers/irqchip/irq-gic-acpi.c
> @@ -13,12 +13,16 @@
>
>   #include <linux/acpi.h>
>   #include <linux/init.h>
> +#include <linux/irqchip/arm-gic.h>
>   #include <linux/irqchip/arm-gic-acpi.h>
>   #include <linux/irqchip/arm-gic-v3.h>

arm-gic.h and arm-gic-v3.h describe register map for respective drivers 
and should be used separately within parent driver only.

Tomasz

>
> +#include "irqchip.h"
> +
>   /* GIC version presented in MADT GIC distributor structure */
>   static u8 gic_version __initdata = ACPI_MADT_GIC_VER_UNKNOWN;
>
> +/* GIC distributor physical base address, which is needed for both GICv2/3 */
>   static phys_addr_t dist_phy_base __initdata;
>
>   u8 __init acpi_gic_version(void)
> @@ -26,6 +30,11 @@ u8 __init acpi_gic_version(void)
>   	return gic_version;
>   }
>
> +void __init set_acpi_core_irqdomain(struct irq_domain *domain)
> +{
> +	acpi_irq_domain = domain;
> +}
> +
>   static int __init
>   acpi_gic_parse_distributor(struct acpi_subtable_header *header,
>   				const unsigned long end)
> @@ -37,8 +46,9 @@ acpi_gic_parse_distributor(struct acpi_subtable_header *header,
>   	if (BAD_MADT_ENTRY(dist, end))
>   		return -EINVAL;
>
> -	gic_version = dist->gic_version;
>   	dist_phy_base = dist->base_address;
> +	if (gic_version == ACPI_MADT_GIC_VER_UNKNOWN)
> +		gic_version = dist->gic_version;
>   	return 0;
>   }
>
> @@ -114,3 +124,86 @@ int __init acpi_gic_version_init(void)
>
>   	return 0;
>   }
> +
> +static phys_addr_t cpu_phy_base __initdata;
> +
> +static int __init
> +gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
> +			const unsigned long end)
> +{
> +	struct acpi_madt_generic_interrupt *processor;
> +	phys_addr_t gic_cpu_base;
> +	static int cpu_base_assigned;
> +
> +	processor = (struct acpi_madt_generic_interrupt *)header;
> +
> +	if (BAD_MADT_ENTRY(processor, end))
> +		return -EINVAL;
> +
> +	/*
> +	 * There is no support for non-banked GICv1/2 register in ACPI spec.
> +	 * All CPU interface addresses have to be the same.
> +	 */
> +	gic_cpu_base = processor->base_address;
> +	if (cpu_base_assigned && gic_cpu_base != cpu_phy_base)
> +		return -EINVAL;
> +
> +	cpu_phy_base = gic_cpu_base;
> +	cpu_base_assigned = 1;
> +	return 0;
> +}
> +
> +static int __init
> +gic_v2_acpi_init(struct acpi_table_header *table)
> +{
> +	void __iomem *cpu_base, *dist_base;
> +	int count;
> +
> +	if (acpi_gic_version() >= ACPI_MADT_GIC_VER_V3)
> +		return -ENODEV;
> +
> +	/* Collect CPU base addresses */
> +	count = acpi_parse_entries(ACPI_SIG_MADT,
> +				   sizeof(struct acpi_table_madt),
> +				   gic_acpi_parse_madt_cpu, table,
> +				   ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
> +	if (count <= 0) {
> +		pr_err("No valid GICC entries exist\n");
> +		return -EINVAL;
> +	}
> +
> +	/*
> +	 * Find distributor base address. We expect one distributor entry since
> +	 * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
> +	 */
> +	count = acpi_parse_entries(ACPI_SIG_MADT,
> +				   sizeof(struct acpi_table_madt),
> +				   acpi_gic_parse_distributor, table,
> +				   ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
> +	if (count <= 0) {
> +		pr_err("No valid GICD entries exist\n");
> +		return -EINVAL;
> +	} else if (count > 1) {
> +		pr_err("More than one GICD entry detected\n");
> +		return -EINVAL;
> +	}
> +
> +	cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
> +	if (!cpu_base) {
> +		pr_err("Unable to map GICC registers\n");
> +		return -ENOMEM;
> +	}
> +
> +	dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE);
> +	if (!dist_base) {
> +		pr_err("Unable to map GICD registers\n");
> +		iounmap(cpu_base);
> +		return -ENOMEM;
> +	}
> +
> +	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
> +
> +	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
> +	return 0;
> +}
> +IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_SIG_MADT, gic_v2_acpi_init);
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index 869a69f..2f934fe 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -986,6 +986,8 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>   	if (WARN_ON(!gic->domain))
>   		return;
>
> +	set_acpi_core_irqdomain(gic->domain);
> +
>   	if (gic_nr == 0) {
>   #ifdef CONFIG_SMP
>   		set_smp_cross_call(gic_raise_softirq);
> @@ -1047,104 +1049,3 @@ IRQCHIP_DECLARE(msm_8660_qgic, "qcom,msm-8660-qgic", gic_of_init);
>   IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
>
>   #endif
> -
> -#ifdef CONFIG_ACPI
> -static phys_addr_t dist_phy_base, cpu_phy_base __initdata;
> -
> -static int __init
> -gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
> -			const unsigned long end)
> -{
> -	struct acpi_madt_generic_interrupt *processor;
> -	phys_addr_t gic_cpu_base;
> -	static int cpu_base_assigned;
> -
> -	processor = (struct acpi_madt_generic_interrupt *)header;
> -
> -	if (BAD_MADT_ENTRY(processor, end))
> -		return -EINVAL;
> -
> -	/*
> -	 * There is no support for non-banked GICv1/2 register in ACPI spec.
> -	 * All CPU interface addresses have to be the same.
> -	 */
> -	gic_cpu_base = processor->base_address;
> -	if (cpu_base_assigned && gic_cpu_base != cpu_phy_base)
> -		return -EINVAL;
> -
> -	cpu_phy_base = gic_cpu_base;
> -	cpu_base_assigned = 1;
> -	return 0;
> -}
> -
> -static int __init
> -gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
> -				const unsigned long end)
> -{
> -	struct acpi_madt_generic_distributor *dist;
> -
> -	dist = (struct acpi_madt_generic_distributor *)header;
> -
> -	if (BAD_MADT_ENTRY(dist, end))
> -		return -EINVAL;
> -
> -	dist_phy_base = dist->base_address;
> -	return 0;
> -}
> -
> -static int __init
> -gic_v2_acpi_init(struct acpi_table_header *table)
> -{
> -	void __iomem *cpu_base, *dist_base;
> -	int count;
> -
> -	if (acpi_gic_version() >= ACPI_MADT_GIC_VER_V3)
> -		return -ENODEV;
> -
> -	/* Collect CPU base addresses */
> -	count = acpi_parse_entries(ACPI_SIG_MADT,
> -				   sizeof(struct acpi_table_madt),
> -				   gic_acpi_parse_madt_cpu, table,
> -				   ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
> -	if (count <= 0) {
> -		pr_err("No valid GICC entries exist\n");
> -		return -EINVAL;
> -	}
> -
> -	/*
> -	 * Find distributor base address. We expect one distributor entry since
> -	 * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
> -	 */
> -	count = acpi_parse_entries(ACPI_SIG_MADT,
> -				   sizeof(struct acpi_table_madt),
> -				   gic_acpi_parse_madt_distributor, table,
> -				   ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
> -	if (count <= 0) {
> -		pr_err("No valid GICD entries exist\n");
> -		return -EINVAL;
> -	} else if (count > 1) {
> -		pr_err("More than one GICD entry detected\n");
> -		return -EINVAL;
> -	}
> -
> -	cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
> -	if (!cpu_base) {
> -		pr_err("Unable to map GICC registers\n");
> -		return -ENOMEM;
> -	}
> -
> -	dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE);
> -	if (!dist_base) {
> -		pr_err("Unable to map GICD registers\n");
> -		iounmap(cpu_base);
> -		return -ENOMEM;
> -	}
> -
> -	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
> -	acpi_irq_domain = gic_data[0].domain;
> -
> -	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
> -	return 0;
> -}
> -IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_SIG_MADT, gic_v2_acpi_init);
> -#endif
> diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
> index 245386d..f4a17c7 100644
> --- a/include/linux/irqchip/arm-gic-acpi.h
> +++ b/include/linux/irqchip/arm-gic-acpi.h
> @@ -25,5 +25,10 @@ extern struct irq_domain *acpi_irq_domain;
>
>   int acpi_gic_version_init(void);
>   u8 acpi_gic_version(void);
> +
> +void set_acpi_core_irqdomain(struct irq_domain *domain);
> +#else
> +#define set_acpi_core_irqdomain(domain)
>   #endif /* CONFIG_ACPI */
> +
>   #endif /* ARM_GIC_ACPI_H_ */
>

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 03/11] irqchip / GIC: Add GIC version support in ACPI MADT
  2015-05-20 20:02     ` Thomas Gleixner
  (?)
@ 2015-05-21 14:19       ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-21 14:19 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki, Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann,
	Tomasz Nowicki, Grant Likely, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 2015年05月21日 04:02, Thomas Gleixner wrote:
> On Mon, 18 May 2015, Hanjun Guo wrote:
>> diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
>> index 65d6b93..855ead9 100644
>> --- a/drivers/acpi/irq.c
>> +++ b/drivers/acpi/irq.c
>> @@ -32,6 +32,9 @@ void __init acpi_irqchip_init(void)
>>   	if (acpi_disabled)
>>   		return;
>>
>> +	if (acpi_gic_version_init())
>> +		return;
>
> This looks just wrong. acpi_irqchip_init() is a generic ACPI function
> and now you stick a GIC specific callback into it?

For now, acpi_irqchip_init() just introduced for GIC init, not for
APIC init for x86, and I don't see the usage in the near future.

>
> What calls acpi_irqchip_init?

I renamed it as acpi_irq_init() in the later patch, which
is called in irqchip_init() in drivers/irqchip/irqchip.c
to init irqchip when DT is not available.

This is not a nice way, but the kernel should stay functional
for each patch goes in, so I separate the patch to smaller one
for easy review under that rule, does it make sense?

Thanks
Hanjun
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 03/11] irqchip / GIC: Add GIC version support in ACPI MADT
@ 2015-05-21 14:19       ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-21 14:19 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki, Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann,
	Tomasz Nowicki, Grant Likely, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 2015年05月21日 04:02, Thomas Gleixner wrote:
> On Mon, 18 May 2015, Hanjun Guo wrote:
>> diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
>> index 65d6b93..855ead9 100644
>> --- a/drivers/acpi/irq.c
>> +++ b/drivers/acpi/irq.c
>> @@ -32,6 +32,9 @@ void __init acpi_irqchip_init(void)
>>   	if (acpi_disabled)
>>   		return;
>>
>> +	if (acpi_gic_version_init())
>> +		return;
>
> This looks just wrong. acpi_irqchip_init() is a generic ACPI function
> and now you stick a GIC specific callback into it?

For now, acpi_irqchip_init() just introduced for GIC init, not for
APIC init for x86, and I don't see the usage in the near future.

>
> What calls acpi_irqchip_init?

I renamed it as acpi_irq_init() in the later patch, which
is called in irqchip_init() in drivers/irqchip/irqchip.c
to init irqchip when DT is not available.

This is not a nice way, but the kernel should stay functional
for each patch goes in, so I separate the patch to smaller one
for easy review under that rule, does it make sense?

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 03/11] irqchip / GIC: Add GIC version support in ACPI MADT
@ 2015-05-21 14:19       ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-21 14:19 UTC (permalink / raw)
  To: linux-arm-kernel

On 2015?05?21? 04:02, Thomas Gleixner wrote:
> On Mon, 18 May 2015, Hanjun Guo wrote:
>> diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
>> index 65d6b93..855ead9 100644
>> --- a/drivers/acpi/irq.c
>> +++ b/drivers/acpi/irq.c
>> @@ -32,6 +32,9 @@ void __init acpi_irqchip_init(void)
>>   	if (acpi_disabled)
>>   		return;
>>
>> +	if (acpi_gic_version_init())
>> +		return;
>
> This looks just wrong. acpi_irqchip_init() is a generic ACPI function
> and now you stick a GIC specific callback into it?

For now, acpi_irqchip_init() just introduced for GIC init, not for
APIC init for x86, and I don't see the usage in the near future.

>
> What calls acpi_irqchip_init?

I renamed it as acpi_irq_init() in the later patch, which
is called in irqchip_init() in drivers/irqchip/irqchip.c
to init irqchip when DT is not available.

This is not a nice way, but the kernel should stay functional
for each patch goes in, so I separate the patch to smaller one
for easy review under that rule, does it make sense?

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 10/11] irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
  2015-05-20 20:44     ` Tomasz Nowicki
  (?)
@ 2015-05-21 14:27       ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-21 14:27 UTC (permalink / raw)
  To: Tomasz Nowicki, Marc Zyngier, Jason Cooper, Will Deacon,
	Catalin Marinas, Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Grant Likely,
	Thomas Gleixner, Olof Johansson, linux-arm-kernel, linux-acpi,
	linux-kernel, linaro-acpi

On 2015年05月21日 04:44, Tomasz Nowicki wrote:
> Hi Hanjun,
>
> On 05/18/2015 02:59 PM, Hanjun Guo wrote:
>> Move GICv2 ACPI related init code in irq-gic.c to irq-gic-acpi.c,
>> this can make the ACPI related GIC init code slef-contained.
>>
>> Introduce set_acpi_core_irqdomain() to set acpi_irqdomain then
>> it will be no need to make gic_data[] as a global value, and
>> it will save the confilcts with GICv3's gic_data in the later
>> patch.
>>
>> acpi_gic_parse_distributor() have the same function as
>> gic_acpi_parse_madt_distributor() to get the GIC distributor
>> physical base address, so just remove the duplicate one, and
>> only get the GIC version when it is unknown.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   drivers/irqchip/irq-gic-acpi.c       |  95
>> +++++++++++++++++++++++++++++++-
>>   drivers/irqchip/irq-gic.c            | 103
>> +----------------------------------
>>   include/linux/irqchip/arm-gic-acpi.h |   5 ++
>>   3 files changed, 101 insertions(+), 102 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-acpi.c
>> b/drivers/irqchip/irq-gic-acpi.c
>> index 1388d9e..8463e48 100644
>> --- a/drivers/irqchip/irq-gic-acpi.c
>> +++ b/drivers/irqchip/irq-gic-acpi.c
>> @@ -13,12 +13,16 @@
>>
>>   #include <linux/acpi.h>
>>   #include <linux/init.h>
>> +#include <linux/irqchip/arm-gic.h>
>>   #include <linux/irqchip/arm-gic-acpi.h>
>>   #include <linux/irqchip/arm-gic-v3.h>
>
> arm-gic.h and arm-gic-v3.h describe register map for respective drivers
> and should be used separately within parent driver only.

Seems that there is no duplicate macros in that two head
file, but yes, it will confuse people.

Consolidating all ACPI GIC code is an improvement to make
ACPI related code self-contained, but also have some drawbacks,

Marc, what do you think?

Thanks
Hanjun
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 10/11] irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
@ 2015-05-21 14:27       ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-21 14:27 UTC (permalink / raw)
  To: Tomasz Nowicki, Marc Zyngier, Jason Cooper, Will Deacon,
	Catalin Marinas, Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Grant Likely,
	Thomas Gleixner, Olof Johansson, linux-arm-kernel, linux-acpi,
	linux-kernel, linaro-acpi

On 2015年05月21日 04:44, Tomasz Nowicki wrote:
> Hi Hanjun,
>
> On 05/18/2015 02:59 PM, Hanjun Guo wrote:
>> Move GICv2 ACPI related init code in irq-gic.c to irq-gic-acpi.c,
>> this can make the ACPI related GIC init code slef-contained.
>>
>> Introduce set_acpi_core_irqdomain() to set acpi_irqdomain then
>> it will be no need to make gic_data[] as a global value, and
>> it will save the confilcts with GICv3's gic_data in the later
>> patch.
>>
>> acpi_gic_parse_distributor() have the same function as
>> gic_acpi_parse_madt_distributor() to get the GIC distributor
>> physical base address, so just remove the duplicate one, and
>> only get the GIC version when it is unknown.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   drivers/irqchip/irq-gic-acpi.c       |  95
>> +++++++++++++++++++++++++++++++-
>>   drivers/irqchip/irq-gic.c            | 103
>> +----------------------------------
>>   include/linux/irqchip/arm-gic-acpi.h |   5 ++
>>   3 files changed, 101 insertions(+), 102 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-acpi.c
>> b/drivers/irqchip/irq-gic-acpi.c
>> index 1388d9e..8463e48 100644
>> --- a/drivers/irqchip/irq-gic-acpi.c
>> +++ b/drivers/irqchip/irq-gic-acpi.c
>> @@ -13,12 +13,16 @@
>>
>>   #include <linux/acpi.h>
>>   #include <linux/init.h>
>> +#include <linux/irqchip/arm-gic.h>
>>   #include <linux/irqchip/arm-gic-acpi.h>
>>   #include <linux/irqchip/arm-gic-v3.h>
>
> arm-gic.h and arm-gic-v3.h describe register map for respective drivers
> and should be used separately within parent driver only.

Seems that there is no duplicate macros in that two head
file, but yes, it will confuse people.

Consolidating all ACPI GIC code is an improvement to make
ACPI related code self-contained, but also have some drawbacks,

Marc, what do you think?

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 10/11] irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
@ 2015-05-21 14:27       ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-21 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

On 2015?05?21? 04:44, Tomasz Nowicki wrote:
> Hi Hanjun,
>
> On 05/18/2015 02:59 PM, Hanjun Guo wrote:
>> Move GICv2 ACPI related init code in irq-gic.c to irq-gic-acpi.c,
>> this can make the ACPI related GIC init code slef-contained.
>>
>> Introduce set_acpi_core_irqdomain() to set acpi_irqdomain then
>> it will be no need to make gic_data[] as a global value, and
>> it will save the confilcts with GICv3's gic_data in the later
>> patch.
>>
>> acpi_gic_parse_distributor() have the same function as
>> gic_acpi_parse_madt_distributor() to get the GIC distributor
>> physical base address, so just remove the duplicate one, and
>> only get the GIC version when it is unknown.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   drivers/irqchip/irq-gic-acpi.c       |  95
>> +++++++++++++++++++++++++++++++-
>>   drivers/irqchip/irq-gic.c            | 103
>> +----------------------------------
>>   include/linux/irqchip/arm-gic-acpi.h |   5 ++
>>   3 files changed, 101 insertions(+), 102 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-acpi.c
>> b/drivers/irqchip/irq-gic-acpi.c
>> index 1388d9e..8463e48 100644
>> --- a/drivers/irqchip/irq-gic-acpi.c
>> +++ b/drivers/irqchip/irq-gic-acpi.c
>> @@ -13,12 +13,16 @@
>>
>>   #include <linux/acpi.h>
>>   #include <linux/init.h>
>> +#include <linux/irqchip/arm-gic.h>
>>   #include <linux/irqchip/arm-gic-acpi.h>
>>   #include <linux/irqchip/arm-gic-v3.h>
>
> arm-gic.h and arm-gic-v3.h describe register map for respective drivers
> and should be used separately within parent driver only.

Seems that there is no duplicate macros in that two head
file, but yes, it will confuse people.

Consolidating all ACPI GIC code is an improvement to make
ACPI related code self-contained, but also have some drawbacks,

Marc, what do you think?

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 03/11] irqchip / GIC: Add GIC version support in ACPI MADT
  2015-05-21 14:19       ` Hanjun Guo
@ 2015-05-21 14:39         ` Thomas Gleixner
  -1 siblings, 0 replies; 75+ messages in thread
From: Thomas Gleixner @ 2015-05-21 14:39 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki, Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann,
	Tomasz Nowicki, Grant Likely, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1244 bytes --]

On Thu, 21 May 2015, Hanjun Guo wrote:
> On 2015年05月21日 04:02, Thomas Gleixner wrote:
> > On Mon, 18 May 2015, Hanjun Guo wrote:
> > > diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
> > > index 65d6b93..855ead9 100644
> > > --- a/drivers/acpi/irq.c
> > > +++ b/drivers/acpi/irq.c
> > > @@ -32,6 +32,9 @@ void __init acpi_irqchip_init(void)
> > >   	if (acpi_disabled)
> > >   		return;
> > > 
> > > +	if (acpi_gic_version_init())
> > > +		return;
> > 
> > This looks just wrong. acpi_irqchip_init() is a generic ACPI function
> > and now you stick a GIC specific callback into it?
> 
> For now, acpi_irqchip_init() just introduced for GIC init, not for
> APIC init for x86, and I don't see the usage in the near future.
> 
> > 
> > What calls acpi_irqchip_init?
> 
> I renamed it as acpi_irq_init() in the later patch, which
> is called in irqchip_init() in drivers/irqchip/irqchip.c
> to init irqchip when DT is not available.

Neither of those names is a good choice as they suggest that this is a
generic acpi mechanism while in fact it is a GIC specific ACPI
extension. And its therefor wrong to put that code into drivers/acpi.

It belongs into drivers/irqchip/gic-acpi.c or some other descriptive
name.

Thanks,

	tglx








^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 03/11] irqchip / GIC: Add GIC version support in ACPI MADT
@ 2015-05-21 14:39         ` Thomas Gleixner
  0 siblings, 0 replies; 75+ messages in thread
From: Thomas Gleixner @ 2015-05-21 14:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 21 May 2015, Hanjun Guo wrote:
> On 2015?05?21? 04:02, Thomas Gleixner wrote:
> > On Mon, 18 May 2015, Hanjun Guo wrote:
> > > diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
> > > index 65d6b93..855ead9 100644
> > > --- a/drivers/acpi/irq.c
> > > +++ b/drivers/acpi/irq.c
> > > @@ -32,6 +32,9 @@ void __init acpi_irqchip_init(void)
> > >   	if (acpi_disabled)
> > >   		return;
> > > 
> > > +	if (acpi_gic_version_init())
> > > +		return;
> > 
> > This looks just wrong. acpi_irqchip_init() is a generic ACPI function
> > and now you stick a GIC specific callback into it?
> 
> For now, acpi_irqchip_init() just introduced for GIC init, not for
> APIC init for x86, and I don't see the usage in the near future.
> 
> > 
> > What calls acpi_irqchip_init?
> 
> I renamed it as acpi_irq_init() in the later patch, which
> is called in irqchip_init() in drivers/irqchip/irqchip.c
> to init irqchip when DT is not available.

Neither of those names is a good choice as they suggest that this is a
generic acpi mechanism while in fact it is a GIC specific ACPI
extension. And its therefor wrong to put that code into drivers/acpi.

It belongs into drivers/irqchip/gic-acpi.c or some other descriptive
name.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 03/11] irqchip / GIC: Add GIC version support in ACPI MADT
  2015-05-21 14:39         ` Thomas Gleixner
  (?)
@ 2015-05-21 15:04           ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-21 15:04 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki, Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann,
	Tomasz Nowicki, Grant Likely, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 2015年05月21日 22:39, Thomas Gleixner wrote:
> On Thu, 21 May 2015, Hanjun Guo wrote:
>> On 2015年05月21日 04:02, Thomas Gleixner wrote:
>>> On Mon, 18 May 2015, Hanjun Guo wrote:
>>>> diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
>>>> index 65d6b93..855ead9 100644
>>>> --- a/drivers/acpi/irq.c
>>>> +++ b/drivers/acpi/irq.c
>>>> @@ -32,6 +32,9 @@ void __init acpi_irqchip_init(void)
>>>>    	if (acpi_disabled)
>>>>    		return;
>>>>
>>>> +	if (acpi_gic_version_init())
>>>> +		return;
>>>
>>> This looks just wrong. acpi_irqchip_init() is a generic ACPI function
>>> and now you stick a GIC specific callback into it?
>>
>> For now, acpi_irqchip_init() just introduced for GIC init, not for
>> APIC init for x86, and I don't see the usage in the near future.
>>
>>>
>>> What calls acpi_irqchip_init?
>>
>> I renamed it as acpi_irq_init() in the later patch, which
>> is called in irqchip_init() in drivers/irqchip/irqchip.c
>> to init irqchip when DT is not available.
>
> Neither of those names is a good choice as they suggest that this is a
> generic acpi mechanism while in fact it is a GIC specific ACPI
> extension. And its therefor wrong to put that code into drivers/acpi.

OK, thanks for the suggestion.

>
> It belongs into drivers/irqchip/gic-acpi.c or some other descriptive
> name.

I already introduced a similar file named irq-gic-acpi.c under
drivers/irqchip/, will move the code to there in next version.

Thanks
Hanjun

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 03/11] irqchip / GIC: Add GIC version support in ACPI MADT
@ 2015-05-21 15:04           ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-21 15:04 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki, Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann,
	Tomasz Nowicki, Grant Likely, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 2015年05月21日 22:39, Thomas Gleixner wrote:
> On Thu, 21 May 2015, Hanjun Guo wrote:
>> On 2015年05月21日 04:02, Thomas Gleixner wrote:
>>> On Mon, 18 May 2015, Hanjun Guo wrote:
>>>> diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
>>>> index 65d6b93..855ead9 100644
>>>> --- a/drivers/acpi/irq.c
>>>> +++ b/drivers/acpi/irq.c
>>>> @@ -32,6 +32,9 @@ void __init acpi_irqchip_init(void)
>>>>    	if (acpi_disabled)
>>>>    		return;
>>>>
>>>> +	if (acpi_gic_version_init())
>>>> +		return;
>>>
>>> This looks just wrong. acpi_irqchip_init() is a generic ACPI function
>>> and now you stick a GIC specific callback into it?
>>
>> For now, acpi_irqchip_init() just introduced for GIC init, not for
>> APIC init for x86, and I don't see the usage in the near future.
>>
>>>
>>> What calls acpi_irqchip_init?
>>
>> I renamed it as acpi_irq_init() in the later patch, which
>> is called in irqchip_init() in drivers/irqchip/irqchip.c
>> to init irqchip when DT is not available.
>
> Neither of those names is a good choice as they suggest that this is a
> generic acpi mechanism while in fact it is a GIC specific ACPI
> extension. And its therefor wrong to put that code into drivers/acpi.

OK, thanks for the suggestion.

>
> It belongs into drivers/irqchip/gic-acpi.c or some other descriptive
> name.

I already introduced a similar file named irq-gic-acpi.c under
drivers/irqchip/, will move the code to there in next version.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 03/11] irqchip / GIC: Add GIC version support in ACPI MADT
@ 2015-05-21 15:04           ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-05-21 15:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 2015?05?21? 22:39, Thomas Gleixner wrote:
> On Thu, 21 May 2015, Hanjun Guo wrote:
>> On 2015?05?21? 04:02, Thomas Gleixner wrote:
>>> On Mon, 18 May 2015, Hanjun Guo wrote:
>>>> diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
>>>> index 65d6b93..855ead9 100644
>>>> --- a/drivers/acpi/irq.c
>>>> +++ b/drivers/acpi/irq.c
>>>> @@ -32,6 +32,9 @@ void __init acpi_irqchip_init(void)
>>>>    	if (acpi_disabled)
>>>>    		return;
>>>>
>>>> +	if (acpi_gic_version_init())
>>>> +		return;
>>>
>>> This looks just wrong. acpi_irqchip_init() is a generic ACPI function
>>> and now you stick a GIC specific callback into it?
>>
>> For now, acpi_irqchip_init() just introduced for GIC init, not for
>> APIC init for x86, and I don't see the usage in the near future.
>>
>>>
>>> What calls acpi_irqchip_init?
>>
>> I renamed it as acpi_irq_init() in the later patch, which
>> is called in irqchip_init() in drivers/irqchip/irqchip.c
>> to init irqchip when DT is not available.
>
> Neither of those names is a good choice as they suggest that this is a
> generic acpi mechanism while in fact it is a GIC specific ACPI
> extension. And its therefor wrong to put that code into drivers/acpi.

OK, thanks for the suggestion.

>
> It belongs into drivers/irqchip/gic-acpi.c or some other descriptive
> name.

I already introduced a similar file named irq-gic-acpi.c under
drivers/irqchip/, will move the code to there in next version.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 00/11] Add self-probe infrastructure and stacked irqdomain support for ACPI based GICv2/3 init
  2015-05-18 12:59 ` Hanjun Guo
  (?)
@ 2015-06-02 12:24   ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-02 12:24 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	Grant Likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

Hi Marc,

Ping, could you comment on if we are on the right direction
for this patch set? much appreciated.

Thanks
Hanjun

On 2015年05月18日 20:59, Hanjun Guo wrote:
> This patch set introduce self-probe infrastructure to init IRQ
> controllers and stacked irqdomain support for ACPI based GICv2/3
> init.
>
> The self-probe infrastructure for ACPI GIC init is similar as
> IRQCHIP_DECLARE() and based on the GIC version support in ACPI
> MADT table.
>
> We introduce acpi_irq_domain for GICv2/3 core domain to support
> stacked irqdomain, and pass the gsi (global system interrupt) as
> the agument (void *arg) for gic_irq_domain_alloc(), then we can
> alloc virqs via acpi_register_gsi() with stacked irqdomain.
>
> In order to make ACPI related GIC init code slef-contained, I
> consolidated all the GIC init code into drivers/irqchip/irq-gic-acpi.c.
>
> update from RFC version:
>   - Consolidate all the GIC init code into drivers/irqchip/irq-gic-acpi.c
>
> Hanjun Guo (8):
>    irqchip / GIC: Add GIC version support in ACPI MADT
>    irqchip / GIC / ACPI: Use IRQCHIP_ACPI_DECLARE to simplify GICv2 init
>      code
>    irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
>    ACPI / gsi: Add gsi_mutex to synchronize
>      acpi_register_gsi()/acpi_unregister_gsi()
>    irqchip / GICv3: Add ACPI support for GICv3+ initialization
>    irqchip / GICv3: Add stacked irqdomain support for ACPI based init
>    irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
>    irqchip / GICv3 / ACPI: Consolidate GICv3 ACPI related init code
>
> Tomasz Nowicki (3):
>    ACPICA: Introduce GIC version for arm based system
>    ACPI / irqchip: Add self-probe infrastructure to initialize IRQ
>      controller
>    irqchip / GICv3: Refactor gic_of_init() for GICv3 driver
>
>   arch/arm64/Kconfig                   |   1 +
>   arch/arm64/include/asm/irq.h         |  13 --
>   arch/arm64/kernel/acpi.c             |  25 ---
>   drivers/acpi/Makefile                |   1 +
>   drivers/acpi/gsi.c                   |  41 +++--
>   drivers/acpi/irq.c                   |  40 +++++
>   drivers/irqchip/Kconfig              |   3 +
>   drivers/irqchip/Makefile             |   1 +
>   drivers/irqchip/irq-gic-acpi.c       | 318 +++++++++++++++++++++++++++++++++++
>   drivers/irqchip/irq-gic-v3.c         | 149 +++++++++-------
>   drivers/irqchip/irq-gic.c            | 129 ++------------
>   drivers/irqchip/irqchip.h            |  12 ++
>   include/acpi/actbl1.h                |  17 +-
>   include/asm-generic/vmlinux.lds.h    |  13 ++
>   include/linux/acpi.h                 |  14 ++
>   include/linux/acpi_irq.h             |   4 +-
>   include/linux/irqchip/arm-gic-acpi.h |  13 +-
>   include/linux/irqchip/arm-gic-v3.h   |  10 ++
>   include/linux/mod_devicetable.h      |   7 +
>   19 files changed, 577 insertions(+), 234 deletions(-)
>   create mode 100644 drivers/acpi/irq.c
>   create mode 100644 drivers/irqchip/irq-gic-acpi.c
>
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 00/11] Add self-probe infrastructure and stacked irqdomain support for ACPI based GICv2/3 init
@ 2015-06-02 12:24   ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-02 12:24 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	Grant Likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

Hi Marc,

Ping, could you comment on if we are on the right direction
for this patch set? much appreciated.

Thanks
Hanjun

On 2015年05月18日 20:59, Hanjun Guo wrote:
> This patch set introduce self-probe infrastructure to init IRQ
> controllers and stacked irqdomain support for ACPI based GICv2/3
> init.
>
> The self-probe infrastructure for ACPI GIC init is similar as
> IRQCHIP_DECLARE() and based on the GIC version support in ACPI
> MADT table.
>
> We introduce acpi_irq_domain for GICv2/3 core domain to support
> stacked irqdomain, and pass the gsi (global system interrupt) as
> the agument (void *arg) for gic_irq_domain_alloc(), then we can
> alloc virqs via acpi_register_gsi() with stacked irqdomain.
>
> In order to make ACPI related GIC init code slef-contained, I
> consolidated all the GIC init code into drivers/irqchip/irq-gic-acpi.c.
>
> update from RFC version:
>   - Consolidate all the GIC init code into drivers/irqchip/irq-gic-acpi.c
>
> Hanjun Guo (8):
>    irqchip / GIC: Add GIC version support in ACPI MADT
>    irqchip / GIC / ACPI: Use IRQCHIP_ACPI_DECLARE to simplify GICv2 init
>      code
>    irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
>    ACPI / gsi: Add gsi_mutex to synchronize
>      acpi_register_gsi()/acpi_unregister_gsi()
>    irqchip / GICv3: Add ACPI support for GICv3+ initialization
>    irqchip / GICv3: Add stacked irqdomain support for ACPI based init
>    irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
>    irqchip / GICv3 / ACPI: Consolidate GICv3 ACPI related init code
>
> Tomasz Nowicki (3):
>    ACPICA: Introduce GIC version for arm based system
>    ACPI / irqchip: Add self-probe infrastructure to initialize IRQ
>      controller
>    irqchip / GICv3: Refactor gic_of_init() for GICv3 driver
>
>   arch/arm64/Kconfig                   |   1 +
>   arch/arm64/include/asm/irq.h         |  13 --
>   arch/arm64/kernel/acpi.c             |  25 ---
>   drivers/acpi/Makefile                |   1 +
>   drivers/acpi/gsi.c                   |  41 +++--
>   drivers/acpi/irq.c                   |  40 +++++
>   drivers/irqchip/Kconfig              |   3 +
>   drivers/irqchip/Makefile             |   1 +
>   drivers/irqchip/irq-gic-acpi.c       | 318 +++++++++++++++++++++++++++++++++++
>   drivers/irqchip/irq-gic-v3.c         | 149 +++++++++-------
>   drivers/irqchip/irq-gic.c            | 129 ++------------
>   drivers/irqchip/irqchip.h            |  12 ++
>   include/acpi/actbl1.h                |  17 +-
>   include/asm-generic/vmlinux.lds.h    |  13 ++
>   include/linux/acpi.h                 |  14 ++
>   include/linux/acpi_irq.h             |   4 +-
>   include/linux/irqchip/arm-gic-acpi.h |  13 +-
>   include/linux/irqchip/arm-gic-v3.h   |  10 ++
>   include/linux/mod_devicetable.h      |   7 +
>   19 files changed, 577 insertions(+), 234 deletions(-)
>   create mode 100644 drivers/acpi/irq.c
>   create mode 100644 drivers/irqchip/irq-gic-acpi.c
>

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 00/11] Add self-probe infrastructure and stacked irqdomain support for ACPI based GICv2/3 init
@ 2015-06-02 12:24   ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-02 12:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marc,

Ping, could you comment on if we are on the right direction
for this patch set? much appreciated.

Thanks
Hanjun

On 2015?05?18? 20:59, Hanjun Guo wrote:
> This patch set introduce self-probe infrastructure to init IRQ
> controllers and stacked irqdomain support for ACPI based GICv2/3
> init.
>
> The self-probe infrastructure for ACPI GIC init is similar as
> IRQCHIP_DECLARE() and based on the GIC version support in ACPI
> MADT table.
>
> We introduce acpi_irq_domain for GICv2/3 core domain to support
> stacked irqdomain, and pass the gsi (global system interrupt) as
> the agument (void *arg) for gic_irq_domain_alloc(), then we can
> alloc virqs via acpi_register_gsi() with stacked irqdomain.
>
> In order to make ACPI related GIC init code slef-contained, I
> consolidated all the GIC init code into drivers/irqchip/irq-gic-acpi.c.
>
> update from RFC version:
>   - Consolidate all the GIC init code into drivers/irqchip/irq-gic-acpi.c
>
> Hanjun Guo (8):
>    irqchip / GIC: Add GIC version support in ACPI MADT
>    irqchip / GIC / ACPI: Use IRQCHIP_ACPI_DECLARE to simplify GICv2 init
>      code
>    irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
>    ACPI / gsi: Add gsi_mutex to synchronize
>      acpi_register_gsi()/acpi_unregister_gsi()
>    irqchip / GICv3: Add ACPI support for GICv3+ initialization
>    irqchip / GICv3: Add stacked irqdomain support for ACPI based init
>    irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
>    irqchip / GICv3 / ACPI: Consolidate GICv3 ACPI related init code
>
> Tomasz Nowicki (3):
>    ACPICA: Introduce GIC version for arm based system
>    ACPI / irqchip: Add self-probe infrastructure to initialize IRQ
>      controller
>    irqchip / GICv3: Refactor gic_of_init() for GICv3 driver
>
>   arch/arm64/Kconfig                   |   1 +
>   arch/arm64/include/asm/irq.h         |  13 --
>   arch/arm64/kernel/acpi.c             |  25 ---
>   drivers/acpi/Makefile                |   1 +
>   drivers/acpi/gsi.c                   |  41 +++--
>   drivers/acpi/irq.c                   |  40 +++++
>   drivers/irqchip/Kconfig              |   3 +
>   drivers/irqchip/Makefile             |   1 +
>   drivers/irqchip/irq-gic-acpi.c       | 318 +++++++++++++++++++++++++++++++++++
>   drivers/irqchip/irq-gic-v3.c         | 149 +++++++++-------
>   drivers/irqchip/irq-gic.c            | 129 ++------------
>   drivers/irqchip/irqchip.h            |  12 ++
>   include/acpi/actbl1.h                |  17 +-
>   include/asm-generic/vmlinux.lds.h    |  13 ++
>   include/linux/acpi.h                 |  14 ++
>   include/linux/acpi_irq.h             |   4 +-
>   include/linux/irqchip/arm-gic-acpi.h |  13 +-
>   include/linux/irqchip/arm-gic-v3.h   |  10 ++
>   include/linux/mod_devicetable.h      |   7 +
>   19 files changed, 577 insertions(+), 234 deletions(-)
>   create mode 100644 drivers/acpi/irq.c
>   create mode 100644 drivers/irqchip/irq-gic-acpi.c
>

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 02/11] ACPI / irqchip: Add self-probe infrastructure to initialize IRQ controller
  2015-05-18 12:59   ` Hanjun Guo
  (?)
@ 2015-06-10 15:33     ` Marc Zyngier
  -1 siblings, 0 replies; 75+ messages in thread
From: Marc Zyngier @ 2015-06-10 15:33 UTC (permalink / raw)
  To: Hanjun Guo, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

Hi Hanjun,

On 18/05/15 13:59, Hanjun Guo wrote:
> From: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> 
> This self-probe infrastructure works in the similar way as OF,
> but there is some different in the mechanism:
> 
> For OF, the init fn will be called once it finds comptiable strings
> in DT,  but for ACPI, we init irqchips by static tables, and in
> static ACPI tables, there are no comptiable strings to indicate
> irqchips, so every init function with IRQCHIP_ACPI_DECLARE in the
> same table will be called, but thanks to the GIC version presented
> in ACPI table, we can init different GIC irqchips with this framework.

This triggers an immediate question: If we can find out the GIC version
in the ACPI tables, which can't we just call the irqchips that implement
the support for this version?

i.e: the GICv2 irqchip code would have a line like:

IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_GIC_VER_V2, gic_v2_acpi_init);

and the probing code would simply call the drivers that have declared
their interest for this version code.

Having code that tests for the version in each driver is not an option
(this is exactly what we're trying to avoid).

Thanks,

	M.

> 
> This mechanism can also be used for clock declare and may also works
> on x86 for some table parsing too.
> 
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> [hj: introduce struct acpi_table_id instead of acpi_device_id]
> [hj: rework it more generic to all ACPI tables and fix some issues]
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/acpi/Makefile             |  1 +
>  drivers/acpi/irq.c                | 37 +++++++++++++++++++++++++++++++++++++
>  drivers/irqchip/irqchip.h         | 12 ++++++++++++
>  include/asm-generic/vmlinux.lds.h | 13 +++++++++++++
>  include/linux/acpi.h              | 14 ++++++++++++++
>  include/linux/mod_devicetable.h   |  7 +++++++
>  6 files changed, 84 insertions(+)
>  create mode 100644 drivers/acpi/irq.c
> 
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 8a063e2..3e4aec3 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -80,6 +80,7 @@ obj-$(CONFIG_ACPI_HED)		+= hed.o
>  obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
>  obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
>  obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
> +obj-$(CONFIG_IRQCHIP)		+= irq.o
>  
>  # processor has its own "processor." module_param namespace
>  processor-y			:= processor_driver.o processor_throttling.o
> diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
> new file mode 100644
> index 0000000..65d6b93
> --- /dev/null
> +++ b/drivers/acpi/irq.c
> @@ -0,0 +1,37 @@
> +/*
> + * Copyright (c) 2015, Linaro Ltd.
> + * Author: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> + *         Hanjun Guo <hanjun.guo@linaro.org>
> + *
> + * Inspired by drivers/irqchip/irqchip.c
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/init.h>
> +#include <linux/acpi.h>
> +
> +/*
> + * 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;
> +
> +	for (id = __irqchip_acpi_table; id->id[0]; id++)
> +		acpi_table_parse(id->id, (acpi_tbl_table_handler)id->data);
> +}
> diff --git a/drivers/irqchip/irqchip.h b/drivers/irqchip/irqchip.h
> index 0f6486d..1949546 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 irqchip drivers to declare
> + * the association between their ACPI table and their initialization function.
> + *
> + * @name: name that must be unique accross all IRQCHIP_ACPI_DECLARE of the
> + * same file.
> + * @table_id: name of the ACPI table signature
> + * @fn: initialization function
> + */
> +#define IRQCHIP_ACPI_DECLARE(name, table_id, fn)	\
> +	ACPI_DECLARE(irqchip, name, table_id, 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 90e4ed1e..b904af3 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -820,4 +820,18 @@ static inline struct acpi_device *acpi_get_next_child(struct device *dev,
>  
>  #endif
>  
> +#ifdef CONFIG_ACPI
> +#define ACPI_DECLARE(table, name, table_id, fn)				\
> +	static const struct acpi_table_id __acpi_table_##name		\
> +		__used __section(__##table##_acpi_table)		\
> +		 = { .id = table_id,					\
> +		     .data = (void *)fn }
> +#else
> +#define ACPI_DECLARE(table, name, table_id, fn)				\
> +	static const struct acpi_table_id __acpi_table_##name		\
> +		__attribute__((unused))					\
> +		 = { .id = table_id,					\
> +		     .data = (void*)fn }
> +#endif
> +
>  #endif	/*_LINUX_ACPI_H*/
> diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
> index 3bfd567..47c1ea1 100644
> --- a/include/linux/mod_devicetable.h
> +++ b/include/linux/mod_devicetable.h
> @@ -199,6 +199,13 @@ struct pnp_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 *data;
> +};
> +
>  struct pnp_card_device_id {
>  	__u8 id[PNP_ID_LEN];
>  	kernel_ulong_t driver_data;
> 


-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 02/11] ACPI / irqchip: Add self-probe infrastructure to initialize IRQ controller
@ 2015-06-10 15:33     ` Marc Zyngier
  0 siblings, 0 replies; 75+ messages in thread
From: Marc Zyngier @ 2015-06-10 15:33 UTC (permalink / raw)
  To: Hanjun Guo, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

Hi Hanjun,

On 18/05/15 13:59, Hanjun Guo wrote:
> From: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> 
> This self-probe infrastructure works in the similar way as OF,
> but there is some different in the mechanism:
> 
> For OF, the init fn will be called once it finds comptiable strings
> in DT,  but for ACPI, we init irqchips by static tables, and in
> static ACPI tables, there are no comptiable strings to indicate
> irqchips, so every init function with IRQCHIP_ACPI_DECLARE in the
> same table will be called, but thanks to the GIC version presented
> in ACPI table, we can init different GIC irqchips with this framework.

This triggers an immediate question: If we can find out the GIC version
in the ACPI tables, which can't we just call the irqchips that implement
the support for this version?

i.e: the GICv2 irqchip code would have a line like:

IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_GIC_VER_V2, gic_v2_acpi_init);

and the probing code would simply call the drivers that have declared
their interest for this version code.

Having code that tests for the version in each driver is not an option
(this is exactly what we're trying to avoid).

Thanks,

	M.

> 
> This mechanism can also be used for clock declare and may also works
> on x86 for some table parsing too.
> 
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> [hj: introduce struct acpi_table_id instead of acpi_device_id]
> [hj: rework it more generic to all ACPI tables and fix some issues]
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/acpi/Makefile             |  1 +
>  drivers/acpi/irq.c                | 37 +++++++++++++++++++++++++++++++++++++
>  drivers/irqchip/irqchip.h         | 12 ++++++++++++
>  include/asm-generic/vmlinux.lds.h | 13 +++++++++++++
>  include/linux/acpi.h              | 14 ++++++++++++++
>  include/linux/mod_devicetable.h   |  7 +++++++
>  6 files changed, 84 insertions(+)
>  create mode 100644 drivers/acpi/irq.c
> 
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 8a063e2..3e4aec3 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -80,6 +80,7 @@ obj-$(CONFIG_ACPI_HED)		+= hed.o
>  obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
>  obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
>  obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
> +obj-$(CONFIG_IRQCHIP)		+= irq.o
>  
>  # processor has its own "processor." module_param namespace
>  processor-y			:= processor_driver.o processor_throttling.o
> diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
> new file mode 100644
> index 0000000..65d6b93
> --- /dev/null
> +++ b/drivers/acpi/irq.c
> @@ -0,0 +1,37 @@
> +/*
> + * Copyright (c) 2015, Linaro Ltd.
> + * Author: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> + *         Hanjun Guo <hanjun.guo@linaro.org>
> + *
> + * Inspired by drivers/irqchip/irqchip.c
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/init.h>
> +#include <linux/acpi.h>
> +
> +/*
> + * 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;
> +
> +	for (id = __irqchip_acpi_table; id->id[0]; id++)
> +		acpi_table_parse(id->id, (acpi_tbl_table_handler)id->data);
> +}
> diff --git a/drivers/irqchip/irqchip.h b/drivers/irqchip/irqchip.h
> index 0f6486d..1949546 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 irqchip drivers to declare
> + * the association between their ACPI table and their initialization function.
> + *
> + * @name: name that must be unique accross all IRQCHIP_ACPI_DECLARE of the
> + * same file.
> + * @table_id: name of the ACPI table signature
> + * @fn: initialization function
> + */
> +#define IRQCHIP_ACPI_DECLARE(name, table_id, fn)	\
> +	ACPI_DECLARE(irqchip, name, table_id, 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 90e4ed1e..b904af3 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -820,4 +820,18 @@ static inline struct acpi_device *acpi_get_next_child(struct device *dev,
>  
>  #endif
>  
> +#ifdef CONFIG_ACPI
> +#define ACPI_DECLARE(table, name, table_id, fn)				\
> +	static const struct acpi_table_id __acpi_table_##name		\
> +		__used __section(__##table##_acpi_table)		\
> +		 = { .id = table_id,					\
> +		     .data = (void *)fn }
> +#else
> +#define ACPI_DECLARE(table, name, table_id, fn)				\
> +	static const struct acpi_table_id __acpi_table_##name		\
> +		__attribute__((unused))					\
> +		 = { .id = table_id,					\
> +		     .data = (void*)fn }
> +#endif
> +
>  #endif	/*_LINUX_ACPI_H*/
> diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
> index 3bfd567..47c1ea1 100644
> --- a/include/linux/mod_devicetable.h
> +++ b/include/linux/mod_devicetable.h
> @@ -199,6 +199,13 @@ struct pnp_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 *data;
> +};
> +
>  struct pnp_card_device_id {
>  	__u8 id[PNP_ID_LEN];
>  	kernel_ulong_t driver_data;
> 


-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 02/11] ACPI / irqchip: Add self-probe infrastructure to initialize IRQ controller
@ 2015-06-10 15:33     ` Marc Zyngier
  0 siblings, 0 replies; 75+ messages in thread
From: Marc Zyngier @ 2015-06-10 15:33 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Hanjun,

On 18/05/15 13:59, Hanjun Guo wrote:
> From: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> 
> This self-probe infrastructure works in the similar way as OF,
> but there is some different in the mechanism:
> 
> For OF, the init fn will be called once it finds comptiable strings
> in DT,  but for ACPI, we init irqchips by static tables, and in
> static ACPI tables, there are no comptiable strings to indicate
> irqchips, so every init function with IRQCHIP_ACPI_DECLARE in the
> same table will be called, but thanks to the GIC version presented
> in ACPI table, we can init different GIC irqchips with this framework.

This triggers an immediate question: If we can find out the GIC version
in the ACPI tables, which can't we just call the irqchips that implement
the support for this version?

i.e: the GICv2 irqchip code would have a line like:

IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_GIC_VER_V2, gic_v2_acpi_init);

and the probing code would simply call the drivers that have declared
their interest for this version code.

Having code that tests for the version in each driver is not an option
(this is exactly what we're trying to avoid).

Thanks,

	M.

> 
> This mechanism can also be used for clock declare and may also works
> on x86 for some table parsing too.
> 
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> [hj: introduce struct acpi_table_id instead of acpi_device_id]
> [hj: rework it more generic to all ACPI tables and fix some issues]
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/acpi/Makefile             |  1 +
>  drivers/acpi/irq.c                | 37 +++++++++++++++++++++++++++++++++++++
>  drivers/irqchip/irqchip.h         | 12 ++++++++++++
>  include/asm-generic/vmlinux.lds.h | 13 +++++++++++++
>  include/linux/acpi.h              | 14 ++++++++++++++
>  include/linux/mod_devicetable.h   |  7 +++++++
>  6 files changed, 84 insertions(+)
>  create mode 100644 drivers/acpi/irq.c
> 
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 8a063e2..3e4aec3 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -80,6 +80,7 @@ obj-$(CONFIG_ACPI_HED)		+= hed.o
>  obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
>  obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
>  obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
> +obj-$(CONFIG_IRQCHIP)		+= irq.o
>  
>  # processor has its own "processor." module_param namespace
>  processor-y			:= processor_driver.o processor_throttling.o
> diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
> new file mode 100644
> index 0000000..65d6b93
> --- /dev/null
> +++ b/drivers/acpi/irq.c
> @@ -0,0 +1,37 @@
> +/*
> + * Copyright (c) 2015, Linaro Ltd.
> + * Author: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> + *         Hanjun Guo <hanjun.guo@linaro.org>
> + *
> + * Inspired by drivers/irqchip/irqchip.c
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/init.h>
> +#include <linux/acpi.h>
> +
> +/*
> + * 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;
> +
> +	for (id = __irqchip_acpi_table; id->id[0]; id++)
> +		acpi_table_parse(id->id, (acpi_tbl_table_handler)id->data);
> +}
> diff --git a/drivers/irqchip/irqchip.h b/drivers/irqchip/irqchip.h
> index 0f6486d..1949546 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 irqchip drivers to declare
> + * the association between their ACPI table and their initialization function.
> + *
> + * @name: name that must be unique accross all IRQCHIP_ACPI_DECLARE of the
> + * same file.
> + * @table_id: name of the ACPI table signature
> + * @fn: initialization function
> + */
> +#define IRQCHIP_ACPI_DECLARE(name, table_id, fn)	\
> +	ACPI_DECLARE(irqchip, name, table_id, 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 90e4ed1e..b904af3 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -820,4 +820,18 @@ static inline struct acpi_device *acpi_get_next_child(struct device *dev,
>  
>  #endif
>  
> +#ifdef CONFIG_ACPI
> +#define ACPI_DECLARE(table, name, table_id, fn)				\
> +	static const struct acpi_table_id __acpi_table_##name		\
> +		__used __section(__##table##_acpi_table)		\
> +		 = { .id = table_id,					\
> +		     .data = (void *)fn }
> +#else
> +#define ACPI_DECLARE(table, name, table_id, fn)				\
> +	static const struct acpi_table_id __acpi_table_##name		\
> +		__attribute__((unused))					\
> +		 = { .id = table_id,					\
> +		     .data = (void*)fn }
> +#endif
> +
>  #endif	/*_LINUX_ACPI_H*/
> diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
> index 3bfd567..47c1ea1 100644
> --- a/include/linux/mod_devicetable.h
> +++ b/include/linux/mod_devicetable.h
> @@ -199,6 +199,13 @@ struct pnp_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 *data;
> +};
> +
>  struct pnp_card_device_id {
>  	__u8 id[PNP_ID_LEN];
>  	kernel_ulong_t driver_data;
> 


-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 06/11] ACPI / gsi: Add gsi_mutex to synchronize acpi_register_gsi()/acpi_unregister_gsi()
  2015-05-18 12:59   ` Hanjun Guo
  (?)
@ 2015-06-10 15:58     ` Marc Zyngier
  -1 siblings, 0 replies; 75+ messages in thread
From: Marc Zyngier @ 2015-06-10 15:58 UTC (permalink / raw)
  To: Hanjun Guo, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Lorenzo Pieralisi, Arnd Bergmann, linux-acpi, linaro-acpi,
	linux-kernel, Tomasz Nowicki, Olof Johansson, grant.likely,
	Thomas Gleixner, Jiang Liu, linux-arm-kernel

On 18/05/15 13:59, Hanjun Guo wrote:
> Add a mutex for acpi_register_gsi()/acpi_unregister_gsi() to avoid
> concurrency issues.
> 
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/acpi/gsi.c | 17 +++++++++++++----
>  1 file changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
> index 55b5f31..ab0dcb4 100644
> --- a/drivers/acpi/gsi.c
> +++ b/drivers/acpi/gsi.c
> @@ -16,6 +16,7 @@
>  enum acpi_irq_model_id acpi_irq_model;
>  /* ACPI core domian pointing to GICv2/3 core domain */
>  struct irq_domain *acpi_irq_domain __read_mostly;
> +static DEFINE_MUTEX(gsi_mutex);
>  
>  static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>  {
> @@ -73,20 +74,24 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
>  	int irq;
>  	unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
>  
> +	mutex_lock(&gsi_mutex);
>  	irq = irq_find_mapping(acpi_irq_domain, gsi);
>  	if (irq > 0)
> -		return irq;
> +		goto out;
>  
>  	irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
>  				    &gsi);
>  	if (irq <= 0)
> -		return -EINVAL;
> +		goto out;
>  
>  	/* Set irq type if specified and different than the current one */
>  	if (irq_type != IRQ_TYPE_NONE &&
>  		irq_type != irq_get_trigger_type(irq))
>  		irq_set_irq_type(irq, irq_type);
> -	return irq;
> +
> +out:
> +	mutex_unlock(&gsi_mutex);
> +	return irq > 0 ? irq : -EINVAL;
>  }
>  EXPORT_SYMBOL_GPL(acpi_register_gsi);
>  
> @@ -96,8 +101,12 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
>   */
>  void acpi_unregister_gsi(u32 gsi)
>  {
> -	int irq = irq_find_mapping(acpi_irq_domain, gsi);
> +	int irq;
> +
> +	mutex_lock(&gsi_mutex);
> +	irq = irq_find_mapping(acpi_irq_domain, gsi);
>  
>  	irq_dispose_mapping(irq);
> +	mutex_unlock(&gsi_mutex);
>  }
>  EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
> 

Can you point out why we need this locking? The rest of the kernel seems
to live without it pretty well. And if we really have an issue, I'd
prefer seeing it fixed in the core code rather than in something that is
very much firmware-specific.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 06/11] ACPI / gsi: Add gsi_mutex to synchronize acpi_register_gsi()/acpi_unregister_gsi()
@ 2015-06-10 15:58     ` Marc Zyngier
  0 siblings, 0 replies; 75+ messages in thread
From: Marc Zyngier @ 2015-06-10 15:58 UTC (permalink / raw)
  To: Hanjun Guo, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 18/05/15 13:59, Hanjun Guo wrote:
> Add a mutex for acpi_register_gsi()/acpi_unregister_gsi() to avoid
> concurrency issues.
> 
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/acpi/gsi.c | 17 +++++++++++++----
>  1 file changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
> index 55b5f31..ab0dcb4 100644
> --- a/drivers/acpi/gsi.c
> +++ b/drivers/acpi/gsi.c
> @@ -16,6 +16,7 @@
>  enum acpi_irq_model_id acpi_irq_model;
>  /* ACPI core domian pointing to GICv2/3 core domain */
>  struct irq_domain *acpi_irq_domain __read_mostly;
> +static DEFINE_MUTEX(gsi_mutex);
>  
>  static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>  {
> @@ -73,20 +74,24 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
>  	int irq;
>  	unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
>  
> +	mutex_lock(&gsi_mutex);
>  	irq = irq_find_mapping(acpi_irq_domain, gsi);
>  	if (irq > 0)
> -		return irq;
> +		goto out;
>  
>  	irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
>  				    &gsi);
>  	if (irq <= 0)
> -		return -EINVAL;
> +		goto out;
>  
>  	/* Set irq type if specified and different than the current one */
>  	if (irq_type != IRQ_TYPE_NONE &&
>  		irq_type != irq_get_trigger_type(irq))
>  		irq_set_irq_type(irq, irq_type);
> -	return irq;
> +
> +out:
> +	mutex_unlock(&gsi_mutex);
> +	return irq > 0 ? irq : -EINVAL;
>  }
>  EXPORT_SYMBOL_GPL(acpi_register_gsi);
>  
> @@ -96,8 +101,12 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
>   */
>  void acpi_unregister_gsi(u32 gsi)
>  {
> -	int irq = irq_find_mapping(acpi_irq_domain, gsi);
> +	int irq;
> +
> +	mutex_lock(&gsi_mutex);
> +	irq = irq_find_mapping(acpi_irq_domain, gsi);
>  
>  	irq_dispose_mapping(irq);
> +	mutex_unlock(&gsi_mutex);
>  }
>  EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
> 

Can you point out why we need this locking? The rest of the kernel seems
to live without it pretty well. And if we really have an issue, I'd
prefer seeing it fixed in the core code rather than in something that is
very much firmware-specific.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 06/11] ACPI / gsi: Add gsi_mutex to synchronize acpi_register_gsi()/acpi_unregister_gsi()
@ 2015-06-10 15:58     ` Marc Zyngier
  0 siblings, 0 replies; 75+ messages in thread
From: Marc Zyngier @ 2015-06-10 15:58 UTC (permalink / raw)
  To: linux-arm-kernel

On 18/05/15 13:59, Hanjun Guo wrote:
> Add a mutex for acpi_register_gsi()/acpi_unregister_gsi() to avoid
> concurrency issues.
> 
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/acpi/gsi.c | 17 +++++++++++++----
>  1 file changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
> index 55b5f31..ab0dcb4 100644
> --- a/drivers/acpi/gsi.c
> +++ b/drivers/acpi/gsi.c
> @@ -16,6 +16,7 @@
>  enum acpi_irq_model_id acpi_irq_model;
>  /* ACPI core domian pointing to GICv2/3 core domain */
>  struct irq_domain *acpi_irq_domain __read_mostly;
> +static DEFINE_MUTEX(gsi_mutex);
>  
>  static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>  {
> @@ -73,20 +74,24 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
>  	int irq;
>  	unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
>  
> +	mutex_lock(&gsi_mutex);
>  	irq = irq_find_mapping(acpi_irq_domain, gsi);
>  	if (irq > 0)
> -		return irq;
> +		goto out;
>  
>  	irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
>  				    &gsi);
>  	if (irq <= 0)
> -		return -EINVAL;
> +		goto out;
>  
>  	/* Set irq type if specified and different than the current one */
>  	if (irq_type != IRQ_TYPE_NONE &&
>  		irq_type != irq_get_trigger_type(irq))
>  		irq_set_irq_type(irq, irq_type);
> -	return irq;
> +
> +out:
> +	mutex_unlock(&gsi_mutex);
> +	return irq > 0 ? irq : -EINVAL;
>  }
>  EXPORT_SYMBOL_GPL(acpi_register_gsi);
>  
> @@ -96,8 +101,12 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
>   */
>  void acpi_unregister_gsi(u32 gsi)
>  {
> -	int irq = irq_find_mapping(acpi_irq_domain, gsi);
> +	int irq;
> +
> +	mutex_lock(&gsi_mutex);
> +	irq = irq_find_mapping(acpi_irq_domain, gsi);
>  
>  	irq_dispose_mapping(irq);
> +	mutex_unlock(&gsi_mutex);
>  }
>  EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
> 

Can you point out why we need this locking? The rest of the kernel seems
to live without it pretty well. And if we really have an issue, I'd
prefer seeing it fixed in the core code rather than in something that is
very much firmware-specific.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 05/11] irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
  2015-05-18 12:59   ` Hanjun Guo
  (?)
@ 2015-06-10 16:27     ` Marc Zyngier
  -1 siblings, 0 replies; 75+ messages in thread
From: Marc Zyngier @ 2015-06-10 16:27 UTC (permalink / raw)
  To: Hanjun Guo, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 18/05/15 13:59, Hanjun Guo wrote:
> Introduce acpi_irq_domain for GICv2 core domain instead of referring
> to the irq_default_domain, based on that, pass gsi as the argument and
> get the gsi in gic_irq_domain_alloc() to add stacked irqdomain support
> for ACPI based GICv2 init.
> 
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/acpi/gsi.c                   | 28 +++++++++++++---------------
>  drivers/irqchip/irq-gic.c            | 32 +++++++++++++++++---------------
>  include/linux/irqchip/arm-gic-acpi.h |  2 ++
>  3 files changed, 32 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
> index 38208f2..55b5f31 100644
> --- a/drivers/acpi/gsi.c
> +++ b/drivers/acpi/gsi.c
> @@ -3,6 +3,7 @@
>   *
>   * Copyright (C) 2015 ARM Ltd.
>   * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> + *         Hanjun Guo <hanjun.guo@linaro.org> for stacked irqdomains support
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
> @@ -13,6 +14,8 @@
>  #include <linux/irqdomain.h>
>  
>  enum acpi_irq_model_id acpi_irq_model;
> +/* ACPI core domian pointing to GICv2/3 core domain */
> +struct irq_domain *acpi_irq_domain __read_mostly;

How is a single domain pointer going to work when you will have several
domains (GICv2m, ITS)? Crucially, how are you going to perform the
matching of a device with its irq domain?

	M.

>  
>  static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>  {
> @@ -45,12 +48,7 @@ static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>   */
>  int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
>  {
> -	/*
> -	 * Only default domain is supported at present, always find
> -	 * the mapping corresponding to default domain by passing NULL
> -	 * as irq_domain parameter
> -	 */
> -	*irq = irq_find_mapping(NULL, gsi);
> +	*irq = irq_find_mapping(acpi_irq_domain, gsi);
>  	/*
>  	 * *irq == 0 means no mapping, that should
>  	 * be reported as a failure
> @@ -72,16 +70,16 @@ EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
>  int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
>  		      int polarity)
>  {
> -	unsigned int irq;
> +	int irq;
>  	unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
>  
> -	/*
> -	 * There is no way at present to look-up the IRQ domain on ACPI,
> -	 * hence always create mapping referring to the default domain
> -	 * by passing NULL as irq_domain parameter
> -	 */
> -	irq = irq_create_mapping(NULL, gsi);
> -	if (!irq)
> +	irq = irq_find_mapping(acpi_irq_domain, gsi);
> +	if (irq > 0)
> +		return irq;
> +
> +	irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
> +				    &gsi);
> +	if (irq <= 0)
>  		return -EINVAL;
>  
>  	/* Set irq type if specified and different than the current one */
> @@ -98,7 +96,7 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
>   */
>  void acpi_unregister_gsi(u32 gsi)
>  {
> -	int irq = irq_find_mapping(NULL, gsi);
> +	int irq = irq_find_mapping(acpi_irq_domain, gsi);
>  
>  	irq_dispose_mapping(irq);
>  }
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index fefbcb5..869a69f 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -851,15 +851,22 @@ static struct notifier_block gic_cpu_notifier = {
>  static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
>  				unsigned int nr_irqs, void *arg)
>  {
> -	int i, ret;
> +	int i;
>  	irq_hw_number_t hwirq;
> -	unsigned int type = IRQ_TYPE_NONE;
> -	struct of_phandle_args *irq_data = arg;
>  
> -	ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args,
> -				   irq_data->args_count, &hwirq, &type);
> -	if (ret)
> -		return ret;
> +	if (domain->of_node) {	/* DT case */
> +		int ret;
> +		unsigned int type = IRQ_TYPE_NONE;
> +		struct of_phandle_args *irq_data = arg;
> +
> +		ret = gic_irq_domain_xlate(domain, irq_data->np,
> +					irq_data->args,
> +					irq_data->args_count, &hwirq, &type);
> +		if (ret)
> +			return ret;
> +	} else {	/* ACPI case */
> +		hwirq = (irq_hw_number_t)*(u32 *)arg;
> +	}
>  
>  	for (i = 0; i < nr_irqs; i++)
>  		gic_irq_domain_map(domain, virq + i, hwirq + i);
> @@ -945,11 +952,11 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>  		gic_irqs = 1020;
>  	gic->gic_irqs = gic_irqs;
>  
> -	if (node) {		/* DT case */
> +	if (node || !acpi_disabled) {		/* DT or ACPI case */
>  		gic->domain = irq_domain_add_linear(node, gic_irqs,
>  						    &gic_irq_domain_hierarchy_ops,
>  						    gic);
> -	} else {		/* Non-DT case */
> +	} else {		/* Non-DT and ACPI case */
>  		/*
>  		 * For primary GICs, skip over SGIs.
>  		 * For secondary GICs, skip over PPIs, too.
> @@ -1133,13 +1140,8 @@ gic_v2_acpi_init(struct acpi_table_header *table)
>  		return -ENOMEM;
>  	}
>  
> -	/*
> -	 * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
> -	 * as default IRQ domain to allow for GSI registration and GSI to IRQ
> -	 * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()).
> -	 */
>  	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
> -	irq_set_default_host(gic_data[0].domain);
> +	acpi_irq_domain = gic_data[0].domain;
>  
>  	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
>  	return 0;
> diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
> index 021e8e8..245386d 100644
> --- a/include/linux/irqchip/arm-gic-acpi.h
> +++ b/include/linux/irqchip/arm-gic-acpi.h
> @@ -21,6 +21,8 @@
>  #define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)
>  #define ACPI_GICV3_DIST_MEM_SIZE	(SZ_64K)
>  
> +extern struct irq_domain *acpi_irq_domain;
> +
>  int acpi_gic_version_init(void);
>  u8 acpi_gic_version(void);
>  #endif /* CONFIG_ACPI */
> 


-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 05/11] irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
@ 2015-06-10 16:27     ` Marc Zyngier
  0 siblings, 0 replies; 75+ messages in thread
From: Marc Zyngier @ 2015-06-10 16:27 UTC (permalink / raw)
  To: Hanjun Guo, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 18/05/15 13:59, Hanjun Guo wrote:
> Introduce acpi_irq_domain for GICv2 core domain instead of referring
> to the irq_default_domain, based on that, pass gsi as the argument and
> get the gsi in gic_irq_domain_alloc() to add stacked irqdomain support
> for ACPI based GICv2 init.
> 
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/acpi/gsi.c                   | 28 +++++++++++++---------------
>  drivers/irqchip/irq-gic.c            | 32 +++++++++++++++++---------------
>  include/linux/irqchip/arm-gic-acpi.h |  2 ++
>  3 files changed, 32 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
> index 38208f2..55b5f31 100644
> --- a/drivers/acpi/gsi.c
> +++ b/drivers/acpi/gsi.c
> @@ -3,6 +3,7 @@
>   *
>   * Copyright (C) 2015 ARM Ltd.
>   * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> + *         Hanjun Guo <hanjun.guo@linaro.org> for stacked irqdomains support
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
> @@ -13,6 +14,8 @@
>  #include <linux/irqdomain.h>
>  
>  enum acpi_irq_model_id acpi_irq_model;
> +/* ACPI core domian pointing to GICv2/3 core domain */
> +struct irq_domain *acpi_irq_domain __read_mostly;

How is a single domain pointer going to work when you will have several
domains (GICv2m, ITS)? Crucially, how are you going to perform the
matching of a device with its irq domain?

	M.

>  
>  static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>  {
> @@ -45,12 +48,7 @@ static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>   */
>  int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
>  {
> -	/*
> -	 * Only default domain is supported at present, always find
> -	 * the mapping corresponding to default domain by passing NULL
> -	 * as irq_domain parameter
> -	 */
> -	*irq = irq_find_mapping(NULL, gsi);
> +	*irq = irq_find_mapping(acpi_irq_domain, gsi);
>  	/*
>  	 * *irq == 0 means no mapping, that should
>  	 * be reported as a failure
> @@ -72,16 +70,16 @@ EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
>  int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
>  		      int polarity)
>  {
> -	unsigned int irq;
> +	int irq;
>  	unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
>  
> -	/*
> -	 * There is no way at present to look-up the IRQ domain on ACPI,
> -	 * hence always create mapping referring to the default domain
> -	 * by passing NULL as irq_domain parameter
> -	 */
> -	irq = irq_create_mapping(NULL, gsi);
> -	if (!irq)
> +	irq = irq_find_mapping(acpi_irq_domain, gsi);
> +	if (irq > 0)
> +		return irq;
> +
> +	irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
> +				    &gsi);
> +	if (irq <= 0)
>  		return -EINVAL;
>  
>  	/* Set irq type if specified and different than the current one */
> @@ -98,7 +96,7 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
>   */
>  void acpi_unregister_gsi(u32 gsi)
>  {
> -	int irq = irq_find_mapping(NULL, gsi);
> +	int irq = irq_find_mapping(acpi_irq_domain, gsi);
>  
>  	irq_dispose_mapping(irq);
>  }
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index fefbcb5..869a69f 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -851,15 +851,22 @@ static struct notifier_block gic_cpu_notifier = {
>  static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
>  				unsigned int nr_irqs, void *arg)
>  {
> -	int i, ret;
> +	int i;
>  	irq_hw_number_t hwirq;
> -	unsigned int type = IRQ_TYPE_NONE;
> -	struct of_phandle_args *irq_data = arg;
>  
> -	ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args,
> -				   irq_data->args_count, &hwirq, &type);
> -	if (ret)
> -		return ret;
> +	if (domain->of_node) {	/* DT case */
> +		int ret;
> +		unsigned int type = IRQ_TYPE_NONE;
> +		struct of_phandle_args *irq_data = arg;
> +
> +		ret = gic_irq_domain_xlate(domain, irq_data->np,
> +					irq_data->args,
> +					irq_data->args_count, &hwirq, &type);
> +		if (ret)
> +			return ret;
> +	} else {	/* ACPI case */
> +		hwirq = (irq_hw_number_t)*(u32 *)arg;
> +	}
>  
>  	for (i = 0; i < nr_irqs; i++)
>  		gic_irq_domain_map(domain, virq + i, hwirq + i);
> @@ -945,11 +952,11 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>  		gic_irqs = 1020;
>  	gic->gic_irqs = gic_irqs;
>  
> -	if (node) {		/* DT case */
> +	if (node || !acpi_disabled) {		/* DT or ACPI case */
>  		gic->domain = irq_domain_add_linear(node, gic_irqs,
>  						    &gic_irq_domain_hierarchy_ops,
>  						    gic);
> -	} else {		/* Non-DT case */
> +	} else {		/* Non-DT and ACPI case */
>  		/*
>  		 * For primary GICs, skip over SGIs.
>  		 * For secondary GICs, skip over PPIs, too.
> @@ -1133,13 +1140,8 @@ gic_v2_acpi_init(struct acpi_table_header *table)
>  		return -ENOMEM;
>  	}
>  
> -	/*
> -	 * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
> -	 * as default IRQ domain to allow for GSI registration and GSI to IRQ
> -	 * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()).
> -	 */
>  	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
> -	irq_set_default_host(gic_data[0].domain);
> +	acpi_irq_domain = gic_data[0].domain;
>  
>  	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
>  	return 0;
> diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
> index 021e8e8..245386d 100644
> --- a/include/linux/irqchip/arm-gic-acpi.h
> +++ b/include/linux/irqchip/arm-gic-acpi.h
> @@ -21,6 +21,8 @@
>  #define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)
>  #define ACPI_GICV3_DIST_MEM_SIZE	(SZ_64K)
>  
> +extern struct irq_domain *acpi_irq_domain;
> +
>  int acpi_gic_version_init(void);
>  u8 acpi_gic_version(void);
>  #endif /* CONFIG_ACPI */
> 


-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 05/11] irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
@ 2015-06-10 16:27     ` Marc Zyngier
  0 siblings, 0 replies; 75+ messages in thread
From: Marc Zyngier @ 2015-06-10 16:27 UTC (permalink / raw)
  To: linux-arm-kernel

On 18/05/15 13:59, Hanjun Guo wrote:
> Introduce acpi_irq_domain for GICv2 core domain instead of referring
> to the irq_default_domain, based on that, pass gsi as the argument and
> get the gsi in gic_irq_domain_alloc() to add stacked irqdomain support
> for ACPI based GICv2 init.
> 
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/acpi/gsi.c                   | 28 +++++++++++++---------------
>  drivers/irqchip/irq-gic.c            | 32 +++++++++++++++++---------------
>  include/linux/irqchip/arm-gic-acpi.h |  2 ++
>  3 files changed, 32 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
> index 38208f2..55b5f31 100644
> --- a/drivers/acpi/gsi.c
> +++ b/drivers/acpi/gsi.c
> @@ -3,6 +3,7 @@
>   *
>   * Copyright (C) 2015 ARM Ltd.
>   * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> + *         Hanjun Guo <hanjun.guo@linaro.org> for stacked irqdomains support
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
> @@ -13,6 +14,8 @@
>  #include <linux/irqdomain.h>
>  
>  enum acpi_irq_model_id acpi_irq_model;
> +/* ACPI core domian pointing to GICv2/3 core domain */
> +struct irq_domain *acpi_irq_domain __read_mostly;

How is a single domain pointer going to work when you will have several
domains (GICv2m, ITS)? Crucially, how are you going to perform the
matching of a device with its irq domain?

	M.

>  
>  static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>  {
> @@ -45,12 +48,7 @@ static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>   */
>  int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
>  {
> -	/*
> -	 * Only default domain is supported at present, always find
> -	 * the mapping corresponding to default domain by passing NULL
> -	 * as irq_domain parameter
> -	 */
> -	*irq = irq_find_mapping(NULL, gsi);
> +	*irq = irq_find_mapping(acpi_irq_domain, gsi);
>  	/*
>  	 * *irq == 0 means no mapping, that should
>  	 * be reported as a failure
> @@ -72,16 +70,16 @@ EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
>  int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
>  		      int polarity)
>  {
> -	unsigned int irq;
> +	int irq;
>  	unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
>  
> -	/*
> -	 * There is no way at present to look-up the IRQ domain on ACPI,
> -	 * hence always create mapping referring to the default domain
> -	 * by passing NULL as irq_domain parameter
> -	 */
> -	irq = irq_create_mapping(NULL, gsi);
> -	if (!irq)
> +	irq = irq_find_mapping(acpi_irq_domain, gsi);
> +	if (irq > 0)
> +		return irq;
> +
> +	irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
> +				    &gsi);
> +	if (irq <= 0)
>  		return -EINVAL;
>  
>  	/* Set irq type if specified and different than the current one */
> @@ -98,7 +96,7 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
>   */
>  void acpi_unregister_gsi(u32 gsi)
>  {
> -	int irq = irq_find_mapping(NULL, gsi);
> +	int irq = irq_find_mapping(acpi_irq_domain, gsi);
>  
>  	irq_dispose_mapping(irq);
>  }
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index fefbcb5..869a69f 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -851,15 +851,22 @@ static struct notifier_block gic_cpu_notifier = {
>  static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
>  				unsigned int nr_irqs, void *arg)
>  {
> -	int i, ret;
> +	int i;
>  	irq_hw_number_t hwirq;
> -	unsigned int type = IRQ_TYPE_NONE;
> -	struct of_phandle_args *irq_data = arg;
>  
> -	ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args,
> -				   irq_data->args_count, &hwirq, &type);
> -	if (ret)
> -		return ret;
> +	if (domain->of_node) {	/* DT case */
> +		int ret;
> +		unsigned int type = IRQ_TYPE_NONE;
> +		struct of_phandle_args *irq_data = arg;
> +
> +		ret = gic_irq_domain_xlate(domain, irq_data->np,
> +					irq_data->args,
> +					irq_data->args_count, &hwirq, &type);
> +		if (ret)
> +			return ret;
> +	} else {	/* ACPI case */
> +		hwirq = (irq_hw_number_t)*(u32 *)arg;
> +	}
>  
>  	for (i = 0; i < nr_irqs; i++)
>  		gic_irq_domain_map(domain, virq + i, hwirq + i);
> @@ -945,11 +952,11 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>  		gic_irqs = 1020;
>  	gic->gic_irqs = gic_irqs;
>  
> -	if (node) {		/* DT case */
> +	if (node || !acpi_disabled) {		/* DT or ACPI case */
>  		gic->domain = irq_domain_add_linear(node, gic_irqs,
>  						    &gic_irq_domain_hierarchy_ops,
>  						    gic);
> -	} else {		/* Non-DT case */
> +	} else {		/* Non-DT and ACPI case */
>  		/*
>  		 * For primary GICs, skip over SGIs.
>  		 * For secondary GICs, skip over PPIs, too.
> @@ -1133,13 +1140,8 @@ gic_v2_acpi_init(struct acpi_table_header *table)
>  		return -ENOMEM;
>  	}
>  
> -	/*
> -	 * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
> -	 * as default IRQ domain to allow for GSI registration and GSI to IRQ
> -	 * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()).
> -	 */
>  	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
> -	irq_set_default_host(gic_data[0].domain);
> +	acpi_irq_domain = gic_data[0].domain;
>  
>  	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
>  	return 0;
> diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
> index 021e8e8..245386d 100644
> --- a/include/linux/irqchip/arm-gic-acpi.h
> +++ b/include/linux/irqchip/arm-gic-acpi.h
> @@ -21,6 +21,8 @@
>  #define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)
>  #define ACPI_GICV3_DIST_MEM_SIZE	(SZ_64K)
>  
> +extern struct irq_domain *acpi_irq_domain;
> +
>  int acpi_gic_version_init(void);
>  u8 acpi_gic_version(void);
>  #endif /* CONFIG_ACPI */
> 


-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 10/11] irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
  2015-05-21 14:27       ` Hanjun Guo
  (?)
@ 2015-06-10 16:29         ` Marc Zyngier
  -1 siblings, 0 replies; 75+ messages in thread
From: Marc Zyngier @ 2015-06-10 16:29 UTC (permalink / raw)
  To: Hanjun Guo, Tomasz Nowicki, Jason Cooper, Will Deacon,
	Catalin Marinas, Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, grant.likely,
	Thomas Gleixner, Olof Johansson, linux-arm-kernel, linux-acpi,
	linux-kernel, linaro-acpi

On 21/05/15 15:27, Hanjun Guo wrote:
> On 2015年05月21日 04:44, Tomasz Nowicki wrote:
>> Hi Hanjun,
>>
>> On 05/18/2015 02:59 PM, Hanjun Guo wrote:
>>> Move GICv2 ACPI related init code in irq-gic.c to irq-gic-acpi.c,
>>> this can make the ACPI related GIC init code slef-contained.
>>>
>>> Introduce set_acpi_core_irqdomain() to set acpi_irqdomain then
>>> it will be no need to make gic_data[] as a global value, and
>>> it will save the confilcts with GICv3's gic_data in the later
>>> patch.
>>>
>>> acpi_gic_parse_distributor() have the same function as
>>> gic_acpi_parse_madt_distributor() to get the GIC distributor
>>> physical base address, so just remove the duplicate one, and
>>> only get the GIC version when it is unknown.
>>>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>   drivers/irqchip/irq-gic-acpi.c       |  95
>>> +++++++++++++++++++++++++++++++-
>>>   drivers/irqchip/irq-gic.c            | 103
>>> +----------------------------------
>>>   include/linux/irqchip/arm-gic-acpi.h |   5 ++
>>>   3 files changed, 101 insertions(+), 102 deletions(-)
>>>
>>> diff --git a/drivers/irqchip/irq-gic-acpi.c
>>> b/drivers/irqchip/irq-gic-acpi.c
>>> index 1388d9e..8463e48 100644
>>> --- a/drivers/irqchip/irq-gic-acpi.c
>>> +++ b/drivers/irqchip/irq-gic-acpi.c
>>> @@ -13,12 +13,16 @@
>>>
>>>   #include <linux/acpi.h>
>>>   #include <linux/init.h>
>>> +#include <linux/irqchip/arm-gic.h>
>>>   #include <linux/irqchip/arm-gic-acpi.h>
>>>   #include <linux/irqchip/arm-gic-v3.h>
>>
>> arm-gic.h and arm-gic-v3.h describe register map for respective drivers
>> and should be used separately within parent driver only.
> 
> Seems that there is no duplicate macros in that two head
> file, but yes, it will confuse people.
> 
> Consolidating all ACPI GIC code is an improvement to make
> ACPI related code self-contained, but also have some drawbacks,
> 
> Marc, what do you think?

What I think is "Over my dead body".

These include files are private to the respective interrupt controller
code, and the only reason they are in linux/irqchip is because the
corresponding KVM support code uses them too.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 10/11] irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
@ 2015-06-10 16:29         ` Marc Zyngier
  0 siblings, 0 replies; 75+ messages in thread
From: Marc Zyngier @ 2015-06-10 16:29 UTC (permalink / raw)
  To: Hanjun Guo, Tomasz Nowicki, Jason Cooper, Will Deacon,
	Catalin Marinas, Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, grant.likely,
	Thomas Gleixner, Olof Johansson, linux-arm-kernel, linux-acpi,
	linux-kernel, linaro-acpi

On 21/05/15 15:27, Hanjun Guo wrote:
> On 2015年05月21日 04:44, Tomasz Nowicki wrote:
>> Hi Hanjun,
>>
>> On 05/18/2015 02:59 PM, Hanjun Guo wrote:
>>> Move GICv2 ACPI related init code in irq-gic.c to irq-gic-acpi.c,
>>> this can make the ACPI related GIC init code slef-contained.
>>>
>>> Introduce set_acpi_core_irqdomain() to set acpi_irqdomain then
>>> it will be no need to make gic_data[] as a global value, and
>>> it will save the confilcts with GICv3's gic_data in the later
>>> patch.
>>>
>>> acpi_gic_parse_distributor() have the same function as
>>> gic_acpi_parse_madt_distributor() to get the GIC distributor
>>> physical base address, so just remove the duplicate one, and
>>> only get the GIC version when it is unknown.
>>>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>   drivers/irqchip/irq-gic-acpi.c       |  95
>>> +++++++++++++++++++++++++++++++-
>>>   drivers/irqchip/irq-gic.c            | 103
>>> +----------------------------------
>>>   include/linux/irqchip/arm-gic-acpi.h |   5 ++
>>>   3 files changed, 101 insertions(+), 102 deletions(-)
>>>
>>> diff --git a/drivers/irqchip/irq-gic-acpi.c
>>> b/drivers/irqchip/irq-gic-acpi.c
>>> index 1388d9e..8463e48 100644
>>> --- a/drivers/irqchip/irq-gic-acpi.c
>>> +++ b/drivers/irqchip/irq-gic-acpi.c
>>> @@ -13,12 +13,16 @@
>>>
>>>   #include <linux/acpi.h>
>>>   #include <linux/init.h>
>>> +#include <linux/irqchip/arm-gic.h>
>>>   #include <linux/irqchip/arm-gic-acpi.h>
>>>   #include <linux/irqchip/arm-gic-v3.h>
>>
>> arm-gic.h and arm-gic-v3.h describe register map for respective drivers
>> and should be used separately within parent driver only.
> 
> Seems that there is no duplicate macros in that two head
> file, but yes, it will confuse people.
> 
> Consolidating all ACPI GIC code is an improvement to make
> ACPI related code self-contained, but also have some drawbacks,
> 
> Marc, what do you think?

What I think is "Over my dead body".

These include files are private to the respective interrupt controller
code, and the only reason they are in linux/irqchip is because the
corresponding KVM support code uses them too.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 10/11] irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
@ 2015-06-10 16:29         ` Marc Zyngier
  0 siblings, 0 replies; 75+ messages in thread
From: Marc Zyngier @ 2015-06-10 16:29 UTC (permalink / raw)
  To: linux-arm-kernel

On 21/05/15 15:27, Hanjun Guo wrote:
> On 2015?05?21? 04:44, Tomasz Nowicki wrote:
>> Hi Hanjun,
>>
>> On 05/18/2015 02:59 PM, Hanjun Guo wrote:
>>> Move GICv2 ACPI related init code in irq-gic.c to irq-gic-acpi.c,
>>> this can make the ACPI related GIC init code slef-contained.
>>>
>>> Introduce set_acpi_core_irqdomain() to set acpi_irqdomain then
>>> it will be no need to make gic_data[] as a global value, and
>>> it will save the confilcts with GICv3's gic_data in the later
>>> patch.
>>>
>>> acpi_gic_parse_distributor() have the same function as
>>> gic_acpi_parse_madt_distributor() to get the GIC distributor
>>> physical base address, so just remove the duplicate one, and
>>> only get the GIC version when it is unknown.
>>>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>   drivers/irqchip/irq-gic-acpi.c       |  95
>>> +++++++++++++++++++++++++++++++-
>>>   drivers/irqchip/irq-gic.c            | 103
>>> +----------------------------------
>>>   include/linux/irqchip/arm-gic-acpi.h |   5 ++
>>>   3 files changed, 101 insertions(+), 102 deletions(-)
>>>
>>> diff --git a/drivers/irqchip/irq-gic-acpi.c
>>> b/drivers/irqchip/irq-gic-acpi.c
>>> index 1388d9e..8463e48 100644
>>> --- a/drivers/irqchip/irq-gic-acpi.c
>>> +++ b/drivers/irqchip/irq-gic-acpi.c
>>> @@ -13,12 +13,16 @@
>>>
>>>   #include <linux/acpi.h>
>>>   #include <linux/init.h>
>>> +#include <linux/irqchip/arm-gic.h>
>>>   #include <linux/irqchip/arm-gic-acpi.h>
>>>   #include <linux/irqchip/arm-gic-v3.h>
>>
>> arm-gic.h and arm-gic-v3.h describe register map for respective drivers
>> and should be used separately within parent driver only.
> 
> Seems that there is no duplicate macros in that two head
> file, but yes, it will confuse people.
> 
> Consolidating all ACPI GIC code is an improvement to make
> ACPI related code self-contained, but also have some drawbacks,
> 
> Marc, what do you think?

What I think is "Over my dead body".

These include files are private to the respective interrupt controller
code, and the only reason they are in linux/irqchip is because the
corresponding KVM support code uses them too.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 02/11] ACPI / irqchip: Add self-probe infrastructure to initialize IRQ controller
  2015-06-10 15:33     ` Marc Zyngier
  (?)
@ 2015-06-11 12:55       ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-11 12:55 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Lorenzo Pieralisi, Arnd Bergmann, linux-acpi, linaro-acpi,
	linux-kernel, Tomasz Nowicki, Olof Johansson, grant.likely,
	Thomas Gleixner, Jiang Liu, linux-arm-kernel

Hi Marc,

On 06/10/2015 11:33 PM, Marc Zyngier wrote:
> Hi Hanjun,
>
> On 18/05/15 13:59, Hanjun Guo wrote:
>> From: Tomasz Nowicki <tomasz.nowicki@linaro.org>
>>
>> This self-probe infrastructure works in the similar way as OF,
>> but there is some different in the mechanism:
>>
>> For OF, the init fn will be called once it finds comptiable strings
>> in DT,  but for ACPI, we init irqchips by static tables, and in
>> static ACPI tables, there are no comptiable strings to indicate
>> irqchips, so every init function with IRQCHIP_ACPI_DECLARE in the
>> same table will be called, but thanks to the GIC version presented
>> in ACPI table, we can init different GIC irqchips with this framework.
>
> This triggers an immediate question: If we can find out the GIC version
> in the ACPI tables, which can't we just call the irqchips that implement
> the support for this version?

This is really a good question and triggers me to rethink about
the implementation.

>
> i.e: the GICv2 irqchip code would have a line like:
>
> IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_GIC_VER_V2, gic_v2_acpi_init);
>
> and the probing code would simply call the drivers that have declared
> their interest for this version code.

if we want to achieve this, we can redefine the strut for acpi_table_id:

#define ACPI_TABLE_ID_LEN	5

struct acpi_table_id {
	__u8 id[ACPI_TABLE_ID_LEN];
	const void *handler;
	kernel_ulong_t driver_data;
};

then pass the ACPI_MADT_GIC_VER_V2 as the driver_data, it will
work as you suggested.

>
> Having code that tests for the version in each driver is not an option
> (this is exactly what we're trying to avoid).

I also think it's awkward to do that in each driver, thanks for the
suggestion!

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 02/11] ACPI / irqchip: Add self-probe infrastructure to initialize IRQ controller
@ 2015-06-11 12:55       ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-11 12:55 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

Hi Marc,

On 06/10/2015 11:33 PM, Marc Zyngier wrote:
> Hi Hanjun,
>
> On 18/05/15 13:59, Hanjun Guo wrote:
>> From: Tomasz Nowicki <tomasz.nowicki@linaro.org>
>>
>> This self-probe infrastructure works in the similar way as OF,
>> but there is some different in the mechanism:
>>
>> For OF, the init fn will be called once it finds comptiable strings
>> in DT,  but for ACPI, we init irqchips by static tables, and in
>> static ACPI tables, there are no comptiable strings to indicate
>> irqchips, so every init function with IRQCHIP_ACPI_DECLARE in the
>> same table will be called, but thanks to the GIC version presented
>> in ACPI table, we can init different GIC irqchips with this framework.
>
> This triggers an immediate question: If we can find out the GIC version
> in the ACPI tables, which can't we just call the irqchips that implement
> the support for this version?

This is really a good question and triggers me to rethink about
the implementation.

>
> i.e: the GICv2 irqchip code would have a line like:
>
> IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_GIC_VER_V2, gic_v2_acpi_init);
>
> and the probing code would simply call the drivers that have declared
> their interest for this version code.

if we want to achieve this, we can redefine the strut for acpi_table_id:

#define ACPI_TABLE_ID_LEN	5

struct acpi_table_id {
	__u8 id[ACPI_TABLE_ID_LEN];
	const void *handler;
	kernel_ulong_t driver_data;
};

then pass the ACPI_MADT_GIC_VER_V2 as the driver_data, it will
work as you suggested.

>
> Having code that tests for the version in each driver is not an option
> (this is exactly what we're trying to avoid).

I also think it's awkward to do that in each driver, thanks for the
suggestion!

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 02/11] ACPI / irqchip: Add self-probe infrastructure to initialize IRQ controller
@ 2015-06-11 12:55       ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-11 12:55 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marc,

On 06/10/2015 11:33 PM, Marc Zyngier wrote:
> Hi Hanjun,
>
> On 18/05/15 13:59, Hanjun Guo wrote:
>> From: Tomasz Nowicki <tomasz.nowicki@linaro.org>
>>
>> This self-probe infrastructure works in the similar way as OF,
>> but there is some different in the mechanism:
>>
>> For OF, the init fn will be called once it finds comptiable strings
>> in DT,  but for ACPI, we init irqchips by static tables, and in
>> static ACPI tables, there are no comptiable strings to indicate
>> irqchips, so every init function with IRQCHIP_ACPI_DECLARE in the
>> same table will be called, but thanks to the GIC version presented
>> in ACPI table, we can init different GIC irqchips with this framework.
>
> This triggers an immediate question: If we can find out the GIC version
> in the ACPI tables, which can't we just call the irqchips that implement
> the support for this version?

This is really a good question and triggers me to rethink about
the implementation.

>
> i.e: the GICv2 irqchip code would have a line like:
>
> IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_GIC_VER_V2, gic_v2_acpi_init);
>
> and the probing code would simply call the drivers that have declared
> their interest for this version code.

if we want to achieve this, we can redefine the strut for acpi_table_id:

#define ACPI_TABLE_ID_LEN	5

struct acpi_table_id {
	__u8 id[ACPI_TABLE_ID_LEN];
	const void *handler;
	kernel_ulong_t driver_data;
};

then pass the ACPI_MADT_GIC_VER_V2 as the driver_data, it will
work as you suggested.

>
> Having code that tests for the version in each driver is not an option
> (this is exactly what we're trying to avoid).

I also think it's awkward to do that in each driver, thanks for the
suggestion!

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 06/11] ACPI / gsi: Add gsi_mutex to synchronize acpi_register_gsi()/acpi_unregister_gsi()
  2015-06-10 15:58     ` Marc Zyngier
  (?)
@ 2015-06-11 13:16       ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-11 13:16 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 06/10/2015 11:58 PM, Marc Zyngier wrote:
> On 18/05/15 13:59, Hanjun Guo wrote:
>> Add a mutex for acpi_register_gsi()/acpi_unregister_gsi() to avoid
>> concurrency issues.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   drivers/acpi/gsi.c | 17 +++++++++++++----
>>   1 file changed, 13 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
>> index 55b5f31..ab0dcb4 100644
>> --- a/drivers/acpi/gsi.c
>> +++ b/drivers/acpi/gsi.c
>> @@ -16,6 +16,7 @@
>>   enum acpi_irq_model_id acpi_irq_model;
>>   /* ACPI core domian pointing to GICv2/3 core domain */
>>   struct irq_domain *acpi_irq_domain __read_mostly;
>> +static DEFINE_MUTEX(gsi_mutex);
>>
>>   static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>>   {
>> @@ -73,20 +74,24 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
>>   	int irq;
>>   	unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
>>
>> +	mutex_lock(&gsi_mutex);
>>   	irq = irq_find_mapping(acpi_irq_domain, gsi);
>>   	if (irq > 0)
>> -		return irq;
>> +		goto out;
>>
>>   	irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
>>   				    &gsi);
>>   	if (irq <= 0)
>> -		return -EINVAL;
>> +		goto out;
>>
>>   	/* Set irq type if specified and different than the current one */
>>   	if (irq_type != IRQ_TYPE_NONE &&
>>   		irq_type != irq_get_trigger_type(irq))
>>   		irq_set_irq_type(irq, irq_type);
>> -	return irq;
>> +
>> +out:
>> +	mutex_unlock(&gsi_mutex);
>> +	return irq > 0 ? irq : -EINVAL;
>>   }
>>   EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>
>> @@ -96,8 +101,12 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>    */
>>   void acpi_unregister_gsi(u32 gsi)
>>   {
>> -	int irq = irq_find_mapping(acpi_irq_domain, gsi);
>> +	int irq;
>> +
>> +	mutex_lock(&gsi_mutex);
>> +	irq = irq_find_mapping(acpi_irq_domain, gsi);
>>
>>   	irq_dispose_mapping(irq);
>> +	mutex_unlock(&gsi_mutex);
>>   }
>>   EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
>>
>
> Can you point out why we need this locking? The rest of the kernel seems
> to live without it pretty well. And if we really have an issue, I'd

Hmm, I'm not so sure, I will look deep into that and come back later.

> prefer seeing it fixed in the core code rather than in something that is
> very much firmware-specific.

I agree if there are real issues.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 06/11] ACPI / gsi: Add gsi_mutex to synchronize acpi_register_gsi()/acpi_unregister_gsi()
@ 2015-06-11 13:16       ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-11 13:16 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 06/10/2015 11:58 PM, Marc Zyngier wrote:
> On 18/05/15 13:59, Hanjun Guo wrote:
>> Add a mutex for acpi_register_gsi()/acpi_unregister_gsi() to avoid
>> concurrency issues.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   drivers/acpi/gsi.c | 17 +++++++++++++----
>>   1 file changed, 13 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
>> index 55b5f31..ab0dcb4 100644
>> --- a/drivers/acpi/gsi.c
>> +++ b/drivers/acpi/gsi.c
>> @@ -16,6 +16,7 @@
>>   enum acpi_irq_model_id acpi_irq_model;
>>   /* ACPI core domian pointing to GICv2/3 core domain */
>>   struct irq_domain *acpi_irq_domain __read_mostly;
>> +static DEFINE_MUTEX(gsi_mutex);
>>
>>   static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>>   {
>> @@ -73,20 +74,24 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
>>   	int irq;
>>   	unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
>>
>> +	mutex_lock(&gsi_mutex);
>>   	irq = irq_find_mapping(acpi_irq_domain, gsi);
>>   	if (irq > 0)
>> -		return irq;
>> +		goto out;
>>
>>   	irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
>>   				    &gsi);
>>   	if (irq <= 0)
>> -		return -EINVAL;
>> +		goto out;
>>
>>   	/* Set irq type if specified and different than the current one */
>>   	if (irq_type != IRQ_TYPE_NONE &&
>>   		irq_type != irq_get_trigger_type(irq))
>>   		irq_set_irq_type(irq, irq_type);
>> -	return irq;
>> +
>> +out:
>> +	mutex_unlock(&gsi_mutex);
>> +	return irq > 0 ? irq : -EINVAL;
>>   }
>>   EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>
>> @@ -96,8 +101,12 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>    */
>>   void acpi_unregister_gsi(u32 gsi)
>>   {
>> -	int irq = irq_find_mapping(acpi_irq_domain, gsi);
>> +	int irq;
>> +
>> +	mutex_lock(&gsi_mutex);
>> +	irq = irq_find_mapping(acpi_irq_domain, gsi);
>>
>>   	irq_dispose_mapping(irq);
>> +	mutex_unlock(&gsi_mutex);
>>   }
>>   EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
>>
>
> Can you point out why we need this locking? The rest of the kernel seems
> to live without it pretty well. And if we really have an issue, I'd

Hmm, I'm not so sure, I will look deep into that and come back later.

> prefer seeing it fixed in the core code rather than in something that is
> very much firmware-specific.

I agree if there are real issues.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 06/11] ACPI / gsi: Add gsi_mutex to synchronize acpi_register_gsi()/acpi_unregister_gsi()
@ 2015-06-11 13:16       ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-11 13:16 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/10/2015 11:58 PM, Marc Zyngier wrote:
> On 18/05/15 13:59, Hanjun Guo wrote:
>> Add a mutex for acpi_register_gsi()/acpi_unregister_gsi() to avoid
>> concurrency issues.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   drivers/acpi/gsi.c | 17 +++++++++++++----
>>   1 file changed, 13 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
>> index 55b5f31..ab0dcb4 100644
>> --- a/drivers/acpi/gsi.c
>> +++ b/drivers/acpi/gsi.c
>> @@ -16,6 +16,7 @@
>>   enum acpi_irq_model_id acpi_irq_model;
>>   /* ACPI core domian pointing to GICv2/3 core domain */
>>   struct irq_domain *acpi_irq_domain __read_mostly;
>> +static DEFINE_MUTEX(gsi_mutex);
>>
>>   static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>>   {
>> @@ -73,20 +74,24 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
>>   	int irq;
>>   	unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
>>
>> +	mutex_lock(&gsi_mutex);
>>   	irq = irq_find_mapping(acpi_irq_domain, gsi);
>>   	if (irq > 0)
>> -		return irq;
>> +		goto out;
>>
>>   	irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
>>   				    &gsi);
>>   	if (irq <= 0)
>> -		return -EINVAL;
>> +		goto out;
>>
>>   	/* Set irq type if specified and different than the current one */
>>   	if (irq_type != IRQ_TYPE_NONE &&
>>   		irq_type != irq_get_trigger_type(irq))
>>   		irq_set_irq_type(irq, irq_type);
>> -	return irq;
>> +
>> +out:
>> +	mutex_unlock(&gsi_mutex);
>> +	return irq > 0 ? irq : -EINVAL;
>>   }
>>   EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>
>> @@ -96,8 +101,12 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>    */
>>   void acpi_unregister_gsi(u32 gsi)
>>   {
>> -	int irq = irq_find_mapping(acpi_irq_domain, gsi);
>> +	int irq;
>> +
>> +	mutex_lock(&gsi_mutex);
>> +	irq = irq_find_mapping(acpi_irq_domain, gsi);
>>
>>   	irq_dispose_mapping(irq);
>> +	mutex_unlock(&gsi_mutex);
>>   }
>>   EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
>>
>
> Can you point out why we need this locking? The rest of the kernel seems
> to live without it pretty well. And if we really have an issue, I'd

Hmm, I'm not so sure, I will look deep into that and come back later.

> prefer seeing it fixed in the core code rather than in something that is
> very much firmware-specific.

I agree if there are real issues.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 05/11] irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
  2015-06-10 16:27     ` Marc Zyngier
  (?)
@ 2015-06-11 13:22       ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-11 13:22 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 06/11/2015 12:27 AM, Marc Zyngier wrote:
> On 18/05/15 13:59, Hanjun Guo wrote:
>> Introduce acpi_irq_domain for GICv2 core domain instead of referring
>> to the irq_default_domain, based on that, pass gsi as the argument and
>> get the gsi in gic_irq_domain_alloc() to add stacked irqdomain support
>> for ACPI based GICv2 init.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   drivers/acpi/gsi.c                   | 28 +++++++++++++---------------
>>   drivers/irqchip/irq-gic.c            | 32 +++++++++++++++++---------------
>>   include/linux/irqchip/arm-gic-acpi.h |  2 ++
>>   3 files changed, 32 insertions(+), 30 deletions(-)
>>
>> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
>> index 38208f2..55b5f31 100644
>> --- a/drivers/acpi/gsi.c
>> +++ b/drivers/acpi/gsi.c
>> @@ -3,6 +3,7 @@
>>    *
>>    * Copyright (C) 2015 ARM Ltd.
>>    * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> + *         Hanjun Guo <hanjun.guo@linaro.org> for stacked irqdomains support
>>    *
>>    * This program is free software; you can redistribute it and/or modify
>>    * it under the terms of the GNU General Public License version 2 as
>> @@ -13,6 +14,8 @@
>>   #include <linux/irqdomain.h>
>>
>>   enum acpi_irq_model_id acpi_irq_model;
>> +/* ACPI core domian pointing to GICv2/3 core domain */
>> +struct irq_domain *acpi_irq_domain __read_mostly;
>
> How is a single domain pointer going to work when you will have several
> domains (GICv2m, ITS)?

This acpi_irq_domain is the core domain which is the parent domain
of GICv2m or ITS.

acpi_irq_domain points to GICv2 or GICv3 domain when the GIC
is initialized.

> Crucially, how are you going to perform the
> matching of a device with its irq domain?

since every ITS will have a domain, and there is a mapping
from device id to ITS ID in IORT table, then we can match the
device with the ITS irq domain, does it make sense?

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 05/11] irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
@ 2015-06-11 13:22       ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-11 13:22 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 06/11/2015 12:27 AM, Marc Zyngier wrote:
> On 18/05/15 13:59, Hanjun Guo wrote:
>> Introduce acpi_irq_domain for GICv2 core domain instead of referring
>> to the irq_default_domain, based on that, pass gsi as the argument and
>> get the gsi in gic_irq_domain_alloc() to add stacked irqdomain support
>> for ACPI based GICv2 init.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   drivers/acpi/gsi.c                   | 28 +++++++++++++---------------
>>   drivers/irqchip/irq-gic.c            | 32 +++++++++++++++++---------------
>>   include/linux/irqchip/arm-gic-acpi.h |  2 ++
>>   3 files changed, 32 insertions(+), 30 deletions(-)
>>
>> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
>> index 38208f2..55b5f31 100644
>> --- a/drivers/acpi/gsi.c
>> +++ b/drivers/acpi/gsi.c
>> @@ -3,6 +3,7 @@
>>    *
>>    * Copyright (C) 2015 ARM Ltd.
>>    * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> + *         Hanjun Guo <hanjun.guo@linaro.org> for stacked irqdomains support
>>    *
>>    * This program is free software; you can redistribute it and/or modify
>>    * it under the terms of the GNU General Public License version 2 as
>> @@ -13,6 +14,8 @@
>>   #include <linux/irqdomain.h>
>>
>>   enum acpi_irq_model_id acpi_irq_model;
>> +/* ACPI core domian pointing to GICv2/3 core domain */
>> +struct irq_domain *acpi_irq_domain __read_mostly;
>
> How is a single domain pointer going to work when you will have several
> domains (GICv2m, ITS)?

This acpi_irq_domain is the core domain which is the parent domain
of GICv2m or ITS.

acpi_irq_domain points to GICv2 or GICv3 domain when the GIC
is initialized.

> Crucially, how are you going to perform the
> matching of a device with its irq domain?

since every ITS will have a domain, and there is a mapping
from device id to ITS ID in IORT table, then we can match the
device with the ITS irq domain, does it make sense?

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 05/11] irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
@ 2015-06-11 13:22       ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-11 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/11/2015 12:27 AM, Marc Zyngier wrote:
> On 18/05/15 13:59, Hanjun Guo wrote:
>> Introduce acpi_irq_domain for GICv2 core domain instead of referring
>> to the irq_default_domain, based on that, pass gsi as the argument and
>> get the gsi in gic_irq_domain_alloc() to add stacked irqdomain support
>> for ACPI based GICv2 init.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   drivers/acpi/gsi.c                   | 28 +++++++++++++---------------
>>   drivers/irqchip/irq-gic.c            | 32 +++++++++++++++++---------------
>>   include/linux/irqchip/arm-gic-acpi.h |  2 ++
>>   3 files changed, 32 insertions(+), 30 deletions(-)
>>
>> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
>> index 38208f2..55b5f31 100644
>> --- a/drivers/acpi/gsi.c
>> +++ b/drivers/acpi/gsi.c
>> @@ -3,6 +3,7 @@
>>    *
>>    * Copyright (C) 2015 ARM Ltd.
>>    * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> + *         Hanjun Guo <hanjun.guo@linaro.org> for stacked irqdomains support
>>    *
>>    * This program is free software; you can redistribute it and/or modify
>>    * it under the terms of the GNU General Public License version 2 as
>> @@ -13,6 +14,8 @@
>>   #include <linux/irqdomain.h>
>>
>>   enum acpi_irq_model_id acpi_irq_model;
>> +/* ACPI core domian pointing to GICv2/3 core domain */
>> +struct irq_domain *acpi_irq_domain __read_mostly;
>
> How is a single domain pointer going to work when you will have several
> domains (GICv2m, ITS)?

This acpi_irq_domain is the core domain which is the parent domain
of GICv2m or ITS.

acpi_irq_domain points to GICv2 or GICv3 domain when the GIC
is initialized.

> Crucially, how are you going to perform the
> matching of a device with its irq domain?

since every ITS will have a domain, and there is a mapping
from device id to ITS ID in IORT table, then we can match the
device with the ITS irq domain, does it make sense?

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 10/11] irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
  2015-06-10 16:29         ` Marc Zyngier
  (?)
@ 2015-06-11 13:25           ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-11 13:25 UTC (permalink / raw)
  To: Marc Zyngier, Tomasz Nowicki, Jason Cooper, Will Deacon,
	Catalin Marinas, Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, grant.likely,
	Thomas Gleixner, Olof Johansson, linux-arm-kernel, linux-acpi,
	linux-kernel, linaro-acpi

Hi Marc,

On 06/11/2015 12:29 AM, Marc Zyngier wrote:
> On 21/05/15 15:27, Hanjun Guo wrote:
>> On 2015年05月21日 04:44, Tomasz Nowicki wrote:
>>> Hi Hanjun,
>>>
>>> On 05/18/2015 02:59 PM, Hanjun Guo wrote:
>>>> Move GICv2 ACPI related init code in irq-gic.c to irq-gic-acpi.c,
>>>> this can make the ACPI related GIC init code slef-contained.
>>>>
>>>> Introduce set_acpi_core_irqdomain() to set acpi_irqdomain then
>>>> it will be no need to make gic_data[] as a global value, and
>>>> it will save the confilcts with GICv3's gic_data in the later
>>>> patch.
>>>>
>>>> acpi_gic_parse_distributor() have the same function as
>>>> gic_acpi_parse_madt_distributor() to get the GIC distributor
>>>> physical base address, so just remove the duplicate one, and
>>>> only get the GIC version when it is unknown.
>>>>
>>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>>> ---
>>>>    drivers/irqchip/irq-gic-acpi.c       |  95
>>>> +++++++++++++++++++++++++++++++-
>>>>    drivers/irqchip/irq-gic.c            | 103
>>>> +----------------------------------
>>>>    include/linux/irqchip/arm-gic-acpi.h |   5 ++
>>>>    3 files changed, 101 insertions(+), 102 deletions(-)
>>>>
>>>> diff --git a/drivers/irqchip/irq-gic-acpi.c
>>>> b/drivers/irqchip/irq-gic-acpi.c
>>>> index 1388d9e..8463e48 100644
>>>> --- a/drivers/irqchip/irq-gic-acpi.c
>>>> +++ b/drivers/irqchip/irq-gic-acpi.c
>>>> @@ -13,12 +13,16 @@
>>>>
>>>>    #include <linux/acpi.h>
>>>>    #include <linux/init.h>
>>>> +#include <linux/irqchip/arm-gic.h>
>>>>    #include <linux/irqchip/arm-gic-acpi.h>
>>>>    #include <linux/irqchip/arm-gic-v3.h>
>>>
>>> arm-gic.h and arm-gic-v3.h describe register map for respective drivers
>>> and should be used separately within parent driver only.
>>
>> Seems that there is no duplicate macros in that two head
>> file, but yes, it will confuse people.
>>
>> Consolidating all ACPI GIC code is an improvement to make
>> ACPI related code self-contained, but also have some drawbacks,
>>
>> Marc, what do you think?
>
> What I think is "Over my dead body".
>
> These include files are private to the respective interrupt controller
> code, and the only reason they are in linux/irqchip is because the
> corresponding KVM support code uses them too.

So for this patch, we are totally in the wrong direction, I will
remove the last two patches in next version.

Thanks for your constructive comments, much appreciated :)

Thanks
Hanjun
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 10/11] irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
@ 2015-06-11 13:25           ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-11 13:25 UTC (permalink / raw)
  To: Marc Zyngier, Tomasz Nowicki, Jason Cooper, Will Deacon,
	Catalin Marinas, Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, grant.likely,
	Thomas Gleixner, Olof Johansson, linux-arm-kernel, linux-acpi,
	linux-kernel, linaro-acpi

Hi Marc,

On 06/11/2015 12:29 AM, Marc Zyngier wrote:
> On 21/05/15 15:27, Hanjun Guo wrote:
>> On 2015年05月21日 04:44, Tomasz Nowicki wrote:
>>> Hi Hanjun,
>>>
>>> On 05/18/2015 02:59 PM, Hanjun Guo wrote:
>>>> Move GICv2 ACPI related init code in irq-gic.c to irq-gic-acpi.c,
>>>> this can make the ACPI related GIC init code slef-contained.
>>>>
>>>> Introduce set_acpi_core_irqdomain() to set acpi_irqdomain then
>>>> it will be no need to make gic_data[] as a global value, and
>>>> it will save the confilcts with GICv3's gic_data in the later
>>>> patch.
>>>>
>>>> acpi_gic_parse_distributor() have the same function as
>>>> gic_acpi_parse_madt_distributor() to get the GIC distributor
>>>> physical base address, so just remove the duplicate one, and
>>>> only get the GIC version when it is unknown.
>>>>
>>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>>> ---
>>>>    drivers/irqchip/irq-gic-acpi.c       |  95
>>>> +++++++++++++++++++++++++++++++-
>>>>    drivers/irqchip/irq-gic.c            | 103
>>>> +----------------------------------
>>>>    include/linux/irqchip/arm-gic-acpi.h |   5 ++
>>>>    3 files changed, 101 insertions(+), 102 deletions(-)
>>>>
>>>> diff --git a/drivers/irqchip/irq-gic-acpi.c
>>>> b/drivers/irqchip/irq-gic-acpi.c
>>>> index 1388d9e..8463e48 100644
>>>> --- a/drivers/irqchip/irq-gic-acpi.c
>>>> +++ b/drivers/irqchip/irq-gic-acpi.c
>>>> @@ -13,12 +13,16 @@
>>>>
>>>>    #include <linux/acpi.h>
>>>>    #include <linux/init.h>
>>>> +#include <linux/irqchip/arm-gic.h>
>>>>    #include <linux/irqchip/arm-gic-acpi.h>
>>>>    #include <linux/irqchip/arm-gic-v3.h>
>>>
>>> arm-gic.h and arm-gic-v3.h describe register map for respective drivers
>>> and should be used separately within parent driver only.
>>
>> Seems that there is no duplicate macros in that two head
>> file, but yes, it will confuse people.
>>
>> Consolidating all ACPI GIC code is an improvement to make
>> ACPI related code self-contained, but also have some drawbacks,
>>
>> Marc, what do you think?
>
> What I think is "Over my dead body".
>
> These include files are private to the respective interrupt controller
> code, and the only reason they are in linux/irqchip is because the
> corresponding KVM support code uses them too.

So for this patch, we are totally in the wrong direction, I will
remove the last two patches in next version.

Thanks for your constructive comments, much appreciated :)

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 10/11] irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code
@ 2015-06-11 13:25           ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-11 13:25 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marc,

On 06/11/2015 12:29 AM, Marc Zyngier wrote:
> On 21/05/15 15:27, Hanjun Guo wrote:
>> On 2015?05?21? 04:44, Tomasz Nowicki wrote:
>>> Hi Hanjun,
>>>
>>> On 05/18/2015 02:59 PM, Hanjun Guo wrote:
>>>> Move GICv2 ACPI related init code in irq-gic.c to irq-gic-acpi.c,
>>>> this can make the ACPI related GIC init code slef-contained.
>>>>
>>>> Introduce set_acpi_core_irqdomain() to set acpi_irqdomain then
>>>> it will be no need to make gic_data[] as a global value, and
>>>> it will save the confilcts with GICv3's gic_data in the later
>>>> patch.
>>>>
>>>> acpi_gic_parse_distributor() have the same function as
>>>> gic_acpi_parse_madt_distributor() to get the GIC distributor
>>>> physical base address, so just remove the duplicate one, and
>>>> only get the GIC version when it is unknown.
>>>>
>>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>>> ---
>>>>    drivers/irqchip/irq-gic-acpi.c       |  95
>>>> +++++++++++++++++++++++++++++++-
>>>>    drivers/irqchip/irq-gic.c            | 103
>>>> +----------------------------------
>>>>    include/linux/irqchip/arm-gic-acpi.h |   5 ++
>>>>    3 files changed, 101 insertions(+), 102 deletions(-)
>>>>
>>>> diff --git a/drivers/irqchip/irq-gic-acpi.c
>>>> b/drivers/irqchip/irq-gic-acpi.c
>>>> index 1388d9e..8463e48 100644
>>>> --- a/drivers/irqchip/irq-gic-acpi.c
>>>> +++ b/drivers/irqchip/irq-gic-acpi.c
>>>> @@ -13,12 +13,16 @@
>>>>
>>>>    #include <linux/acpi.h>
>>>>    #include <linux/init.h>
>>>> +#include <linux/irqchip/arm-gic.h>
>>>>    #include <linux/irqchip/arm-gic-acpi.h>
>>>>    #include <linux/irqchip/arm-gic-v3.h>
>>>
>>> arm-gic.h and arm-gic-v3.h describe register map for respective drivers
>>> and should be used separately within parent driver only.
>>
>> Seems that there is no duplicate macros in that two head
>> file, but yes, it will confuse people.
>>
>> Consolidating all ACPI GIC code is an improvement to make
>> ACPI related code self-contained, but also have some drawbacks,
>>
>> Marc, what do you think?
>
> What I think is "Over my dead body".
>
> These include files are private to the respective interrupt controller
> code, and the only reason they are in linux/irqchip is because the
> corresponding KVM support code uses them too.

So for this patch, we are totally in the wrong direction, I will
remove the last two patches in next version.

Thanks for your constructive comments, much appreciated :)

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 05/11] irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
  2015-06-11 13:22       ` Hanjun Guo
  (?)
@ 2015-06-18 23:25         ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-18 23:25 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 06/11/2015 09:22 PM, Hanjun Guo wrote:
> On 06/11/2015 12:27 AM, Marc Zyngier wrote:
>> On 18/05/15 13:59, Hanjun Guo wrote:
>>> Introduce acpi_irq_domain for GICv2 core domain instead of referring
>>> to the irq_default_domain, based on that, pass gsi as the argument and
>>> get the gsi in gic_irq_domain_alloc() to add stacked irqdomain support
>>> for ACPI based GICv2 init.
>>>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>   drivers/acpi/gsi.c                   | 28 +++++++++++++---------------
>>>   drivers/irqchip/irq-gic.c            | 32
>>> +++++++++++++++++---------------
>>>   include/linux/irqchip/arm-gic-acpi.h |  2 ++
>>>   3 files changed, 32 insertions(+), 30 deletions(-)
>>>
[...]
>>>
>>>   enum acpi_irq_model_id acpi_irq_model;
>>> +/* ACPI core domian pointing to GICv2/3 core domain */
>>> +struct irq_domain *acpi_irq_domain __read_mostly;
>>
>> How is a single domain pointer going to work when you will have several
>> domains (GICv2m, ITS)?
>
> This acpi_irq_domain is the core domain which is the parent domain
> of GICv2m or ITS.
>
> acpi_irq_domain points to GICv2 or GICv3 domain when the GIC
> is initialized.
>
>> Crucially, how are you going to perform the
>> matching of a device with its irq domain?
>
> since every ITS will have a domain, and there is a mapping
> from device id to ITS ID in IORT table, then we can match the
> device with the ITS irq domain, does it make sense?

Sorry, I misunderstood the question here, I thought "its" here
means ITS (interrupt translation service), but actually I think
you mean how to match a device to the device's irq domain.

So the stacked irq domain will be:

     acpi_irq_domain == gicv2 or gicv3 core domain
                    ^
                    |   (parent)
                    |
        ITS domain or GIv2m domain
                    ^
                    |
                    |
            MSI chip irq domain

Since there is one GICD supported for now, so there will be only
one irqdomain created for all the wired hardware irqs for PPI, SGI
and SPI, and PPI, SGI and SPI will have unique hardware irq number
(GSI), so we can match the device to the acpi_irq_domain with unique
GSI and it will works. If there will be multi GICD in the future, this
will still works to follow the solution for x86 of ACPI (mutil IOAPICs).

MSI will match itself (device id) to its MSI irqdomain and it will
handled by core code (dynamicly allocated hw irq number), so all
the interrupts will be handled probably in ACPI way.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 05/11] irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
@ 2015-06-18 23:25         ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-18 23:25 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 06/11/2015 09:22 PM, Hanjun Guo wrote:
> On 06/11/2015 12:27 AM, Marc Zyngier wrote:
>> On 18/05/15 13:59, Hanjun Guo wrote:
>>> Introduce acpi_irq_domain for GICv2 core domain instead of referring
>>> to the irq_default_domain, based on that, pass gsi as the argument and
>>> get the gsi in gic_irq_domain_alloc() to add stacked irqdomain support
>>> for ACPI based GICv2 init.
>>>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>   drivers/acpi/gsi.c                   | 28 +++++++++++++---------------
>>>   drivers/irqchip/irq-gic.c            | 32
>>> +++++++++++++++++---------------
>>>   include/linux/irqchip/arm-gic-acpi.h |  2 ++
>>>   3 files changed, 32 insertions(+), 30 deletions(-)
>>>
[...]
>>>
>>>   enum acpi_irq_model_id acpi_irq_model;
>>> +/* ACPI core domian pointing to GICv2/3 core domain */
>>> +struct irq_domain *acpi_irq_domain __read_mostly;
>>
>> How is a single domain pointer going to work when you will have several
>> domains (GICv2m, ITS)?
>
> This acpi_irq_domain is the core domain which is the parent domain
> of GICv2m or ITS.
>
> acpi_irq_domain points to GICv2 or GICv3 domain when the GIC
> is initialized.
>
>> Crucially, how are you going to perform the
>> matching of a device with its irq domain?
>
> since every ITS will have a domain, and there is a mapping
> from device id to ITS ID in IORT table, then we can match the
> device with the ITS irq domain, does it make sense?

Sorry, I misunderstood the question here, I thought "its" here
means ITS (interrupt translation service), but actually I think
you mean how to match a device to the device's irq domain.

So the stacked irq domain will be:

     acpi_irq_domain == gicv2 or gicv3 core domain
                    ^
                    |   (parent)
                    |
        ITS domain or GIv2m domain
                    ^
                    |
                    |
            MSI chip irq domain

Since there is one GICD supported for now, so there will be only
one irqdomain created for all the wired hardware irqs for PPI, SGI
and SPI, and PPI, SGI and SPI will have unique hardware irq number
(GSI), so we can match the device to the acpi_irq_domain with unique
GSI and it will works. If there will be multi GICD in the future, this
will still works to follow the solution for x86 of ACPI (mutil IOAPICs).

MSI will match itself (device id) to its MSI irqdomain and it will
handled by core code (dynamicly allocated hw irq number), so all
the interrupts will be handled probably in ACPI way.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 05/11] irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init
@ 2015-06-18 23:25         ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-18 23:25 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/11/2015 09:22 PM, Hanjun Guo wrote:
> On 06/11/2015 12:27 AM, Marc Zyngier wrote:
>> On 18/05/15 13:59, Hanjun Guo wrote:
>>> Introduce acpi_irq_domain for GICv2 core domain instead of referring
>>> to the irq_default_domain, based on that, pass gsi as the argument and
>>> get the gsi in gic_irq_domain_alloc() to add stacked irqdomain support
>>> for ACPI based GICv2 init.
>>>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>   drivers/acpi/gsi.c                   | 28 +++++++++++++---------------
>>>   drivers/irqchip/irq-gic.c            | 32
>>> +++++++++++++++++---------------
>>>   include/linux/irqchip/arm-gic-acpi.h |  2 ++
>>>   3 files changed, 32 insertions(+), 30 deletions(-)
>>>
[...]
>>>
>>>   enum acpi_irq_model_id acpi_irq_model;
>>> +/* ACPI core domian pointing to GICv2/3 core domain */
>>> +struct irq_domain *acpi_irq_domain __read_mostly;
>>
>> How is a single domain pointer going to work when you will have several
>> domains (GICv2m, ITS)?
>
> This acpi_irq_domain is the core domain which is the parent domain
> of GICv2m or ITS.
>
> acpi_irq_domain points to GICv2 or GICv3 domain when the GIC
> is initialized.
>
>> Crucially, how are you going to perform the
>> matching of a device with its irq domain?
>
> since every ITS will have a domain, and there is a mapping
> from device id to ITS ID in IORT table, then we can match the
> device with the ITS irq domain, does it make sense?

Sorry, I misunderstood the question here, I thought "its" here
means ITS (interrupt translation service), but actually I think
you mean how to match a device to the device's irq domain.

So the stacked irq domain will be:

     acpi_irq_domain == gicv2 or gicv3 core domain
                    ^
                    |   (parent)
                    |
        ITS domain or GIv2m domain
                    ^
                    |
                    |
            MSI chip irq domain

Since there is one GICD supported for now, so there will be only
one irqdomain created for all the wired hardware irqs for PPI, SGI
and SPI, and PPI, SGI and SPI will have unique hardware irq number
(GSI), so we can match the device to the acpi_irq_domain with unique
GSI and it will works. If there will be multi GICD in the future, this
will still works to follow the solution for x86 of ACPI (mutil IOAPICs).

MSI will match itself (device id) to its MSI irqdomain and it will
handled by core code (dynamicly allocated hw irq number), so all
the interrupts will be handled probably in ACPI way.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 06/11] ACPI / gsi: Add gsi_mutex to synchronize acpi_register_gsi()/acpi_unregister_gsi()
  2015-06-11 13:16       ` Hanjun Guo
  (?)
@ 2015-06-19  7:31         ` Hanjun Guo
  -1 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-19  7:31 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 06/11/2015 09:16 PM, Hanjun Guo wrote:
> On 06/10/2015 11:58 PM, Marc Zyngier wrote:
>> On 18/05/15 13:59, Hanjun Guo wrote:
>>> Add a mutex for acpi_register_gsi()/acpi_unregister_gsi() to avoid
>>> concurrency issues.
>>>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>   drivers/acpi/gsi.c | 17 +++++++++++++----
>>>   1 file changed, 13 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
>>> index 55b5f31..ab0dcb4 100644
>>> --- a/drivers/acpi/gsi.c
>>> +++ b/drivers/acpi/gsi.c
>>> @@ -16,6 +16,7 @@
>>>   enum acpi_irq_model_id acpi_irq_model;
>>>   /* ACPI core domian pointing to GICv2/3 core domain */
>>>   struct irq_domain *acpi_irq_domain __read_mostly;
>>> +static DEFINE_MUTEX(gsi_mutex);
>>>
>>>   static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>>>   {
>>> @@ -73,20 +74,24 @@ int acpi_register_gsi(struct device *dev, u32
>>> gsi, int trigger,
>>>       int irq;
>>>       unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
>>>
>>> +    mutex_lock(&gsi_mutex);
>>>       irq = irq_find_mapping(acpi_irq_domain, gsi);
>>>       if (irq > 0)
>>> -        return irq;
>>> +        goto out;
>>>
>>>       irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
>>>                       &gsi);
>>>       if (irq <= 0)
>>> -        return -EINVAL;
>>> +        goto out;
>>>
>>>       /* Set irq type if specified and different than the current one */
>>>       if (irq_type != IRQ_TYPE_NONE &&
>>>           irq_type != irq_get_trigger_type(irq))
>>>           irq_set_irq_type(irq, irq_type);
>>> -    return irq;
>>> +
>>> +out:
>>> +    mutex_unlock(&gsi_mutex);
>>> +    return irq > 0 ? irq : -EINVAL;
>>>   }
>>>   EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>>
>>> @@ -96,8 +101,12 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>>    */
>>>   void acpi_unregister_gsi(u32 gsi)
>>>   {
>>> -    int irq = irq_find_mapping(acpi_irq_domain, gsi);
>>> +    int irq;
>>> +
>>> +    mutex_lock(&gsi_mutex);
>>> +    irq = irq_find_mapping(acpi_irq_domain, gsi);
>>>
>>>       irq_dispose_mapping(irq);
>>> +    mutex_unlock(&gsi_mutex);
>>>   }
>>>   EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
>>>
>>
>> Can you point out why we need this locking? The rest of the kernel seems
>> to live without it pretty well. And if we really have an issue, I'd
>
> Hmm, I'm not so sure, I will look deep into that and come back later.

Sorry for the late reply, I finally recalled that why I introduced
the lock here.

The lock introduced here is because of I assume ACPI based container
(such as CPU socket) hotplug will be available on ARM64 in the future,
then we may online/offline a irqchip at the same time (similar way of
IOAPIC hotplug which introduced by Jiang Liu), it turns out that only
one GICD for now so it's not the case for ARM64 in the near future,
I will drop this patch in next version.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 06/11] ACPI / gsi: Add gsi_mutex to synchronize acpi_register_gsi()/acpi_unregister_gsi()
@ 2015-06-19  7:31         ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-19  7:31 UTC (permalink / raw)
  To: Marc Zyngier, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 06/11/2015 09:16 PM, Hanjun Guo wrote:
> On 06/10/2015 11:58 PM, Marc Zyngier wrote:
>> On 18/05/15 13:59, Hanjun Guo wrote:
>>> Add a mutex for acpi_register_gsi()/acpi_unregister_gsi() to avoid
>>> concurrency issues.
>>>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>   drivers/acpi/gsi.c | 17 +++++++++++++----
>>>   1 file changed, 13 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
>>> index 55b5f31..ab0dcb4 100644
>>> --- a/drivers/acpi/gsi.c
>>> +++ b/drivers/acpi/gsi.c
>>> @@ -16,6 +16,7 @@
>>>   enum acpi_irq_model_id acpi_irq_model;
>>>   /* ACPI core domian pointing to GICv2/3 core domain */
>>>   struct irq_domain *acpi_irq_domain __read_mostly;
>>> +static DEFINE_MUTEX(gsi_mutex);
>>>
>>>   static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>>>   {
>>> @@ -73,20 +74,24 @@ int acpi_register_gsi(struct device *dev, u32
>>> gsi, int trigger,
>>>       int irq;
>>>       unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
>>>
>>> +    mutex_lock(&gsi_mutex);
>>>       irq = irq_find_mapping(acpi_irq_domain, gsi);
>>>       if (irq > 0)
>>> -        return irq;
>>> +        goto out;
>>>
>>>       irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
>>>                       &gsi);
>>>       if (irq <= 0)
>>> -        return -EINVAL;
>>> +        goto out;
>>>
>>>       /* Set irq type if specified and different than the current one */
>>>       if (irq_type != IRQ_TYPE_NONE &&
>>>           irq_type != irq_get_trigger_type(irq))
>>>           irq_set_irq_type(irq, irq_type);
>>> -    return irq;
>>> +
>>> +out:
>>> +    mutex_unlock(&gsi_mutex);
>>> +    return irq > 0 ? irq : -EINVAL;
>>>   }
>>>   EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>>
>>> @@ -96,8 +101,12 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>>    */
>>>   void acpi_unregister_gsi(u32 gsi)
>>>   {
>>> -    int irq = irq_find_mapping(acpi_irq_domain, gsi);
>>> +    int irq;
>>> +
>>> +    mutex_lock(&gsi_mutex);
>>> +    irq = irq_find_mapping(acpi_irq_domain, gsi);
>>>
>>>       irq_dispose_mapping(irq);
>>> +    mutex_unlock(&gsi_mutex);
>>>   }
>>>   EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
>>>
>>
>> Can you point out why we need this locking? The rest of the kernel seems
>> to live without it pretty well. And if we really have an issue, I'd
>
> Hmm, I'm not so sure, I will look deep into that and come back later.

Sorry for the late reply, I finally recalled that why I introduced
the lock here.

The lock introduced here is because of I assume ACPI based container
(such as CPU socket) hotplug will be available on ARM64 in the future,
then we may online/offline a irqchip at the same time (similar way of
IOAPIC hotplug which introduced by Jiang Liu), it turns out that only
one GICD for now so it's not the case for ARM64 in the near future,
I will drop this patch in next version.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 06/11] ACPI / gsi: Add gsi_mutex to synchronize acpi_register_gsi()/acpi_unregister_gsi()
@ 2015-06-19  7:31         ` Hanjun Guo
  0 siblings, 0 replies; 75+ messages in thread
From: Hanjun Guo @ 2015-06-19  7:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/11/2015 09:16 PM, Hanjun Guo wrote:
> On 06/10/2015 11:58 PM, Marc Zyngier wrote:
>> On 18/05/15 13:59, Hanjun Guo wrote:
>>> Add a mutex for acpi_register_gsi()/acpi_unregister_gsi() to avoid
>>> concurrency issues.
>>>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>   drivers/acpi/gsi.c | 17 +++++++++++++----
>>>   1 file changed, 13 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
>>> index 55b5f31..ab0dcb4 100644
>>> --- a/drivers/acpi/gsi.c
>>> +++ b/drivers/acpi/gsi.c
>>> @@ -16,6 +16,7 @@
>>>   enum acpi_irq_model_id acpi_irq_model;
>>>   /* ACPI core domian pointing to GICv2/3 core domain */
>>>   struct irq_domain *acpi_irq_domain __read_mostly;
>>> +static DEFINE_MUTEX(gsi_mutex);
>>>
>>>   static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>>>   {
>>> @@ -73,20 +74,24 @@ int acpi_register_gsi(struct device *dev, u32
>>> gsi, int trigger,
>>>       int irq;
>>>       unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
>>>
>>> +    mutex_lock(&gsi_mutex);
>>>       irq = irq_find_mapping(acpi_irq_domain, gsi);
>>>       if (irq > 0)
>>> -        return irq;
>>> +        goto out;
>>>
>>>       irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
>>>                       &gsi);
>>>       if (irq <= 0)
>>> -        return -EINVAL;
>>> +        goto out;
>>>
>>>       /* Set irq type if specified and different than the current one */
>>>       if (irq_type != IRQ_TYPE_NONE &&
>>>           irq_type != irq_get_trigger_type(irq))
>>>           irq_set_irq_type(irq, irq_type);
>>> -    return irq;
>>> +
>>> +out:
>>> +    mutex_unlock(&gsi_mutex);
>>> +    return irq > 0 ? irq : -EINVAL;
>>>   }
>>>   EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>>
>>> @@ -96,8 +101,12 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>>    */
>>>   void acpi_unregister_gsi(u32 gsi)
>>>   {
>>> -    int irq = irq_find_mapping(acpi_irq_domain, gsi);
>>> +    int irq;
>>> +
>>> +    mutex_lock(&gsi_mutex);
>>> +    irq = irq_find_mapping(acpi_irq_domain, gsi);
>>>
>>>       irq_dispose_mapping(irq);
>>> +    mutex_unlock(&gsi_mutex);
>>>   }
>>>   EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
>>>
>>
>> Can you point out why we need this locking? The rest of the kernel seems
>> to live without it pretty well. And if we really have an issue, I'd
>
> Hmm, I'm not so sure, I will look deep into that and come back later.

Sorry for the late reply, I finally recalled that why I introduced
the lock here.

The lock introduced here is because of I assume ACPI based container
(such as CPU socket) hotplug will be available on ARM64 in the future,
then we may online/offline a irqchip at the same time (similar way of
IOAPIC hotplug which introduced by Jiang Liu), it turns out that only
one GICD for now so it's not the case for ARM64 in the near future,
I will drop this patch in next version.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 06/11] ACPI / gsi: Add gsi_mutex to synchronize acpi_register_gsi()/acpi_unregister_gsi()
  2015-06-19  7:31         ` Hanjun Guo
  (?)
@ 2015-06-19  9:49           ` Marc Zyngier
  -1 siblings, 0 replies; 75+ messages in thread
From: Marc Zyngier @ 2015-06-19  9:49 UTC (permalink / raw)
  To: Hanjun Guo, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 19/06/15 08:31, Hanjun Guo wrote:
> On 06/11/2015 09:16 PM, Hanjun Guo wrote:
>> On 06/10/2015 11:58 PM, Marc Zyngier wrote:
>>> On 18/05/15 13:59, Hanjun Guo wrote:
>>>> Add a mutex for acpi_register_gsi()/acpi_unregister_gsi() to avoid
>>>> concurrency issues.
>>>>
>>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>>> ---
>>>>   drivers/acpi/gsi.c | 17 +++++++++++++----
>>>>   1 file changed, 13 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
>>>> index 55b5f31..ab0dcb4 100644
>>>> --- a/drivers/acpi/gsi.c
>>>> +++ b/drivers/acpi/gsi.c
>>>> @@ -16,6 +16,7 @@
>>>>   enum acpi_irq_model_id acpi_irq_model;
>>>>   /* ACPI core domian pointing to GICv2/3 core domain */
>>>>   struct irq_domain *acpi_irq_domain __read_mostly;
>>>> +static DEFINE_MUTEX(gsi_mutex);
>>>>
>>>>   static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>>>>   {
>>>> @@ -73,20 +74,24 @@ int acpi_register_gsi(struct device *dev, u32
>>>> gsi, int trigger,
>>>>       int irq;
>>>>       unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
>>>>
>>>> +    mutex_lock(&gsi_mutex);
>>>>       irq = irq_find_mapping(acpi_irq_domain, gsi);
>>>>       if (irq > 0)
>>>> -        return irq;
>>>> +        goto out;
>>>>
>>>>       irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
>>>>                       &gsi);
>>>>       if (irq <= 0)
>>>> -        return -EINVAL;
>>>> +        goto out;
>>>>
>>>>       /* Set irq type if specified and different than the current one */
>>>>       if (irq_type != IRQ_TYPE_NONE &&
>>>>           irq_type != irq_get_trigger_type(irq))
>>>>           irq_set_irq_type(irq, irq_type);
>>>> -    return irq;
>>>> +
>>>> +out:
>>>> +    mutex_unlock(&gsi_mutex);
>>>> +    return irq > 0 ? irq : -EINVAL;
>>>>   }
>>>>   EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>>>
>>>> @@ -96,8 +101,12 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>>>    */
>>>>   void acpi_unregister_gsi(u32 gsi)
>>>>   {
>>>> -    int irq = irq_find_mapping(acpi_irq_domain, gsi);
>>>> +    int irq;
>>>> +
>>>> +    mutex_lock(&gsi_mutex);
>>>> +    irq = irq_find_mapping(acpi_irq_domain, gsi);
>>>>
>>>>       irq_dispose_mapping(irq);
>>>> +    mutex_unlock(&gsi_mutex);
>>>>   }
>>>>   EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
>>>>
>>>
>>> Can you point out why we need this locking? The rest of the kernel seems
>>> to live without it pretty well. And if we really have an issue, I'd
>>
>> Hmm, I'm not so sure, I will look deep into that and come back later.
> 
> Sorry for the late reply, I finally recalled that why I introduced
> the lock here.
> 
> The lock introduced here is because of I assume ACPI based container
> (such as CPU socket) hotplug will be available on ARM64 in the future,
> then we may online/offline a irqchip at the same time (similar way of
> IOAPIC hotplug which introduced by Jiang Liu), it turns out that only
> one GICD for now so it's not the case for ARM64 in the near future,

Well, there can only be one GICD, or at least only one that is visible.
If the HW uses multiple GICDs (one per socket?), it must make ensure
that they are all synchronized transparently. That's a strong
requirement from the architecture. Otherwise, we enter the FrankeinGIC
realm, and ACPI has no business with it.

> I will drop this patch in next version.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [PATCH 06/11] ACPI / gsi: Add gsi_mutex to synchronize acpi_register_gsi()/acpi_unregister_gsi()
@ 2015-06-19  9:49           ` Marc Zyngier
  0 siblings, 0 replies; 75+ messages in thread
From: Marc Zyngier @ 2015-06-19  9:49 UTC (permalink / raw)
  To: Hanjun Guo, Jason Cooper, Will Deacon, Catalin Marinas,
	Rafael J. Wysocki
  Cc: Jiang Liu, Lorenzo Pieralisi, Arnd Bergmann, Tomasz Nowicki,
	grant.likely, Thomas Gleixner, Olof Johansson, linux-arm-kernel,
	linux-acpi, linux-kernel, linaro-acpi

On 19/06/15 08:31, Hanjun Guo wrote:
> On 06/11/2015 09:16 PM, Hanjun Guo wrote:
>> On 06/10/2015 11:58 PM, Marc Zyngier wrote:
>>> On 18/05/15 13:59, Hanjun Guo wrote:
>>>> Add a mutex for acpi_register_gsi()/acpi_unregister_gsi() to avoid
>>>> concurrency issues.
>>>>
>>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>>> ---
>>>>   drivers/acpi/gsi.c | 17 +++++++++++++----
>>>>   1 file changed, 13 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
>>>> index 55b5f31..ab0dcb4 100644
>>>> --- a/drivers/acpi/gsi.c
>>>> +++ b/drivers/acpi/gsi.c
>>>> @@ -16,6 +16,7 @@
>>>>   enum acpi_irq_model_id acpi_irq_model;
>>>>   /* ACPI core domian pointing to GICv2/3 core domain */
>>>>   struct irq_domain *acpi_irq_domain __read_mostly;
>>>> +static DEFINE_MUTEX(gsi_mutex);
>>>>
>>>>   static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>>>>   {
>>>> @@ -73,20 +74,24 @@ int acpi_register_gsi(struct device *dev, u32
>>>> gsi, int trigger,
>>>>       int irq;
>>>>       unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
>>>>
>>>> +    mutex_lock(&gsi_mutex);
>>>>       irq = irq_find_mapping(acpi_irq_domain, gsi);
>>>>       if (irq > 0)
>>>> -        return irq;
>>>> +        goto out;
>>>>
>>>>       irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
>>>>                       &gsi);
>>>>       if (irq <= 0)
>>>> -        return -EINVAL;
>>>> +        goto out;
>>>>
>>>>       /* Set irq type if specified and different than the current one */
>>>>       if (irq_type != IRQ_TYPE_NONE &&
>>>>           irq_type != irq_get_trigger_type(irq))
>>>>           irq_set_irq_type(irq, irq_type);
>>>> -    return irq;
>>>> +
>>>> +out:
>>>> +    mutex_unlock(&gsi_mutex);
>>>> +    return irq > 0 ? irq : -EINVAL;
>>>>   }
>>>>   EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>>>
>>>> @@ -96,8 +101,12 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>>>    */
>>>>   void acpi_unregister_gsi(u32 gsi)
>>>>   {
>>>> -    int irq = irq_find_mapping(acpi_irq_domain, gsi);
>>>> +    int irq;
>>>> +
>>>> +    mutex_lock(&gsi_mutex);
>>>> +    irq = irq_find_mapping(acpi_irq_domain, gsi);
>>>>
>>>>       irq_dispose_mapping(irq);
>>>> +    mutex_unlock(&gsi_mutex);
>>>>   }
>>>>   EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
>>>>
>>>
>>> Can you point out why we need this locking? The rest of the kernel seems
>>> to live without it pretty well. And if we really have an issue, I'd
>>
>> Hmm, I'm not so sure, I will look deep into that and come back later.
> 
> Sorry for the late reply, I finally recalled that why I introduced
> the lock here.
> 
> The lock introduced here is because of I assume ACPI based container
> (such as CPU socket) hotplug will be available on ARM64 in the future,
> then we may online/offline a irqchip at the same time (similar way of
> IOAPIC hotplug which introduced by Jiang Liu), it turns out that only
> one GICD for now so it's not the case for ARM64 in the near future,

Well, there can only be one GICD, or at least only one that is visible.
If the HW uses multiple GICDs (one per socket?), it must make ensure
that they are all synchronized transparently. That's a strong
requirement from the architecture. Otherwise, we enter the FrankeinGIC
realm, and ACPI has no business with it.

> I will drop this patch in next version.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [PATCH 06/11] ACPI / gsi: Add gsi_mutex to synchronize acpi_register_gsi()/acpi_unregister_gsi()
@ 2015-06-19  9:49           ` Marc Zyngier
  0 siblings, 0 replies; 75+ messages in thread
From: Marc Zyngier @ 2015-06-19  9:49 UTC (permalink / raw)
  To: linux-arm-kernel

On 19/06/15 08:31, Hanjun Guo wrote:
> On 06/11/2015 09:16 PM, Hanjun Guo wrote:
>> On 06/10/2015 11:58 PM, Marc Zyngier wrote:
>>> On 18/05/15 13:59, Hanjun Guo wrote:
>>>> Add a mutex for acpi_register_gsi()/acpi_unregister_gsi() to avoid
>>>> concurrency issues.
>>>>
>>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>>> ---
>>>>   drivers/acpi/gsi.c | 17 +++++++++++++----
>>>>   1 file changed, 13 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
>>>> index 55b5f31..ab0dcb4 100644
>>>> --- a/drivers/acpi/gsi.c
>>>> +++ b/drivers/acpi/gsi.c
>>>> @@ -16,6 +16,7 @@
>>>>   enum acpi_irq_model_id acpi_irq_model;
>>>>   /* ACPI core domian pointing to GICv2/3 core domain */
>>>>   struct irq_domain *acpi_irq_domain __read_mostly;
>>>> +static DEFINE_MUTEX(gsi_mutex);
>>>>
>>>>   static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity)
>>>>   {
>>>> @@ -73,20 +74,24 @@ int acpi_register_gsi(struct device *dev, u32
>>>> gsi, int trigger,
>>>>       int irq;
>>>>       unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity);
>>>>
>>>> +    mutex_lock(&gsi_mutex);
>>>>       irq = irq_find_mapping(acpi_irq_domain, gsi);
>>>>       if (irq > 0)
>>>> -        return irq;
>>>> +        goto out;
>>>>
>>>>       irq = irq_domain_alloc_irqs(acpi_irq_domain, 1, dev_to_node(dev),
>>>>                       &gsi);
>>>>       if (irq <= 0)
>>>> -        return -EINVAL;
>>>> +        goto out;
>>>>
>>>>       /* Set irq type if specified and different than the current one */
>>>>       if (irq_type != IRQ_TYPE_NONE &&
>>>>           irq_type != irq_get_trigger_type(irq))
>>>>           irq_set_irq_type(irq, irq_type);
>>>> -    return irq;
>>>> +
>>>> +out:
>>>> +    mutex_unlock(&gsi_mutex);
>>>> +    return irq > 0 ? irq : -EINVAL;
>>>>   }
>>>>   EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>>>
>>>> @@ -96,8 +101,12 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi);
>>>>    */
>>>>   void acpi_unregister_gsi(u32 gsi)
>>>>   {
>>>> -    int irq = irq_find_mapping(acpi_irq_domain, gsi);
>>>> +    int irq;
>>>> +
>>>> +    mutex_lock(&gsi_mutex);
>>>> +    irq = irq_find_mapping(acpi_irq_domain, gsi);
>>>>
>>>>       irq_dispose_mapping(irq);
>>>> +    mutex_unlock(&gsi_mutex);
>>>>   }
>>>>   EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
>>>>
>>>
>>> Can you point out why we need this locking? The rest of the kernel seems
>>> to live without it pretty well. And if we really have an issue, I'd
>>
>> Hmm, I'm not so sure, I will look deep into that and come back later.
> 
> Sorry for the late reply, I finally recalled that why I introduced
> the lock here.
> 
> The lock introduced here is because of I assume ACPI based container
> (such as CPU socket) hotplug will be available on ARM64 in the future,
> then we may online/offline a irqchip at the same time (similar way of
> IOAPIC hotplug which introduced by Jiang Liu), it turns out that only
> one GICD for now so it's not the case for ARM64 in the near future,

Well, there can only be one GICD, or at least only one that is visible.
If the HW uses multiple GICDs (one per socket?), it must make ensure
that they are all synchronized transparently. That's a strong
requirement from the architecture. Otherwise, we enter the FrankeinGIC
realm, and ACPI has no business with it.

> I will drop this patch in next version.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 75+ messages in thread

end of thread, other threads:[~2015-06-19  9:49 UTC | newest]

Thread overview: 75+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-18 12:59 [PATCH 00/11] Add self-probe infrastructure and stacked irqdomain support for ACPI based GICv2/3 init Hanjun Guo
2015-05-18 12:59 ` Hanjun Guo
2015-05-18 12:59 ` [PATCH 01/11] ACPICA: Introduce GIC version for arm based system Hanjun Guo
2015-05-18 12:59   ` Hanjun Guo
2015-05-18 12:59 ` [PATCH 02/11] ACPI / irqchip: Add self-probe infrastructure to initialize IRQ controller Hanjun Guo
2015-05-18 12:59   ` Hanjun Guo
2015-06-10 15:33   ` Marc Zyngier
2015-06-10 15:33     ` Marc Zyngier
2015-06-10 15:33     ` Marc Zyngier
2015-06-11 12:55     ` Hanjun Guo
2015-06-11 12:55       ` Hanjun Guo
2015-06-11 12:55       ` Hanjun Guo
2015-05-18 12:59 ` [PATCH 03/11] irqchip / GIC: Add GIC version support in ACPI MADT Hanjun Guo
2015-05-18 12:59   ` Hanjun Guo
2015-05-20 20:02   ` Thomas Gleixner
2015-05-20 20:02     ` Thomas Gleixner
2015-05-21 14:19     ` Hanjun Guo
2015-05-21 14:19       ` Hanjun Guo
2015-05-21 14:19       ` Hanjun Guo
2015-05-21 14:39       ` Thomas Gleixner
2015-05-21 14:39         ` Thomas Gleixner
2015-05-21 15:04         ` Hanjun Guo
2015-05-21 15:04           ` Hanjun Guo
2015-05-21 15:04           ` Hanjun Guo
2015-05-18 12:59 ` [PATCH 04/11] irqchip / GIC / ACPI: Use IRQCHIP_ACPI_DECLARE to simplify GICv2 init code Hanjun Guo
2015-05-18 12:59   ` Hanjun Guo
2015-05-18 12:59 ` [PATCH 05/11] irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init Hanjun Guo
2015-05-18 12:59   ` Hanjun Guo
2015-06-10 16:27   ` Marc Zyngier
2015-06-10 16:27     ` Marc Zyngier
2015-06-10 16:27     ` Marc Zyngier
2015-06-11 13:22     ` Hanjun Guo
2015-06-11 13:22       ` Hanjun Guo
2015-06-11 13:22       ` Hanjun Guo
2015-06-18 23:25       ` Hanjun Guo
2015-06-18 23:25         ` Hanjun Guo
2015-06-18 23:25         ` Hanjun Guo
2015-05-18 12:59 ` [PATCH 06/11] ACPI / gsi: Add gsi_mutex to synchronize acpi_register_gsi()/acpi_unregister_gsi() Hanjun Guo
2015-05-18 12:59   ` Hanjun Guo
2015-06-10 15:58   ` Marc Zyngier
2015-06-10 15:58     ` Marc Zyngier
2015-06-10 15:58     ` Marc Zyngier
2015-06-11 13:16     ` Hanjun Guo
2015-06-11 13:16       ` Hanjun Guo
2015-06-11 13:16       ` Hanjun Guo
2015-06-19  7:31       ` Hanjun Guo
2015-06-19  7:31         ` Hanjun Guo
2015-06-19  7:31         ` Hanjun Guo
2015-06-19  9:49         ` Marc Zyngier
2015-06-19  9:49           ` Marc Zyngier
2015-06-19  9:49           ` Marc Zyngier
2015-05-18 12:59 ` [PATCH 07/11] irqchip / GICv3: Refactor gic_of_init() for GICv3 driver Hanjun Guo
2015-05-18 12:59   ` Hanjun Guo
2015-05-18 12:59 ` [PATCH 08/11] irqchip / GICv3: Add ACPI support for GICv3+ initialization Hanjun Guo
2015-05-18 12:59   ` Hanjun Guo
2015-05-18 12:59 ` [PATCH 09/11] irqchip / GICv3: Add stacked irqdomain support for ACPI based init Hanjun Guo
2015-05-18 12:59   ` Hanjun Guo
2015-05-18 12:59 ` [PATCH 10/11] irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code Hanjun Guo
2015-05-18 12:59   ` Hanjun Guo
2015-05-20 20:44   ` Tomasz Nowicki
2015-05-20 20:44     ` Tomasz Nowicki
2015-05-21 14:27     ` Hanjun Guo
2015-05-21 14:27       ` Hanjun Guo
2015-05-21 14:27       ` Hanjun Guo
2015-06-10 16:29       ` Marc Zyngier
2015-06-10 16:29         ` Marc Zyngier
2015-06-10 16:29         ` Marc Zyngier
2015-06-11 13:25         ` Hanjun Guo
2015-06-11 13:25           ` Hanjun Guo
2015-06-11 13:25           ` Hanjun Guo
2015-05-18 12:59 ` [PATCH 11/11] irqchip / GICv3 / ACPI: Consolidate GICv3 " Hanjun Guo
2015-05-18 12:59   ` Hanjun Guo
2015-06-02 12:24 ` [PATCH 00/11] Add self-probe infrastructure and stacked irqdomain support for ACPI based GICv2/3 init Hanjun Guo
2015-06-02 12:24   ` Hanjun Guo
2015-06-02 12:24   ` Hanjun Guo

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.