linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: hanjun.guo@linaro.org (Hanjun Guo)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 11/11] irqchip / GICv3 / ACPI: Consolidate GICv3 ACPI related init code
Date: Mon, 18 May 2015 20:59:21 +0800	[thread overview]
Message-ID: <1431953961-22706-12-git-send-email-hanjun.guo@linaro.org> (raw)
In-Reply-To: <1431953961-22706-1-git-send-email-hanjun.guo@linaro.org>

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

  parent reply	other threads:[~2015-05-18 12:59 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 ` [PATCH 01/11] ACPICA: Introduce GIC version for arm based system Hanjun Guo
2015-05-18 12:59 ` [PATCH 02/11] ACPI / irqchip: Add self-probe infrastructure to initialize IRQ controller Hanjun Guo
2015-06-10 15:33   ` Marc Zyngier
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-20 20:02   ` Thomas Gleixner
2015-05-21 14:19     ` Hanjun Guo
2015-05-21 14:39       ` Thomas Gleixner
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 ` [PATCH 05/11] irqchip / gic: Add stacked irqdomain support for ACPI based GICv2 init Hanjun Guo
2015-06-10 16:27   ` Marc Zyngier
2015-06-11 13:22     ` 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-06-10 15:58   ` Marc Zyngier
2015-06-11 13:16     ` Hanjun Guo
2015-06-19  7:31       ` Hanjun Guo
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 ` [PATCH 08/11] irqchip / GICv3: Add ACPI support for GICv3+ initialization 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 ` [PATCH 10/11] irqchip / GICv2 / ACPI: Consolidate GICv2 ACPI related init code Hanjun Guo
2015-05-20 20:44   ` Tomasz Nowicki
2015-05-21 14:27     ` Hanjun Guo
2015-06-10 16:29       ` Marc Zyngier
2015-06-11 13:25         ` Hanjun Guo
2015-05-18 12:59 ` Hanjun Guo [this message]
2015-06-02 12:24 ` [PATCH 00/11] Add self-probe infrastructure and stacked irqdomain support for ACPI based GICv2/3 init Hanjun Guo

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=1431953961-22706-12-git-send-email-hanjun.guo@linaro.org \
    --to=hanjun.guo@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).