mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Tomasz Nowicki <tn@semihalf.com>
To: marc.zyngier@arm.com, tglx@linutronix.de, jason@lakedaemon.net,
	rjw@rjwysocki.net, lorenzo.pieralisi@arm.com,
	robert.richter@caviumnetworks.com, shijie.huang@arm.com,
	guohanjun@huawei.com, Suravee.Suthikulpanit@amd.com
Cc: mw@semihalf.com, graeme.gregory@linaro.org,
	Catalin.Marinas@arm.com, will.deacon@arm.com,
	linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org,
	hanjun.guo@linaro.org, linux-arm-kernel@lists.infradead.org,
	ddaney.cavm@gmail.com, Tomasz Nowicki <tn@semihalf.com>,
	Tomasz Nowicki <tomasz.nowicki@linaro.org>
Subject: [PATCH V2 01/10] irqchip / GICv3: Refactor gic_of_init() for GICv3 driver
Date: Thu, 17 Dec 2015 12:52:04 +0100	[thread overview]
Message-ID: <1450353133-15992-2-git-send-email-tn@semihalf.com> (raw)
In-Reply-To: <1450353133-15992-1-git-send-email-tn@semihalf.com>

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 | 130 ++++++++++++++++++++++++++-----------------
 1 file changed, 78 insertions(+), 52 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index d7be6dd..31205c7 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -811,59 +811,16 @@ static void gicv3_enable_quirks(void)
 #endif
 }
 
-static int __init gic_of_init(struct device_node *node, struct device_node *parent)
+static int __init gic_init_bases(void __iomem *dist_base,
+				 struct redist_region *rdist_regs,
+				 u32 nr_redist_regions,
+				 u64 redist_stride,
+				 struct fwnode_handle *handle)
 {
-	void __iomem *dist_base;
-	struct redist_region *rdist_regs;
-	u64 redist_stride;
-	u32 nr_redist_regions;
+	struct device_node *node;
 	u32 typer;
-	u32 reg;
 	int gic_irqs;
 	int err;
-	int i;
-
-	dist_base = of_iomap(node, 0);
-	if (!dist_base) {
-		pr_err("%s: unable to map gic dist registers\n",
-			node->full_name);
-		return -ENXIO;
-	}
-
-	reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
-	if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4) {
-		pr_err("%s: no distributor detected, giving up\n",
-			node->full_name);
-		err = -ENODEV;
-		goto out_unmap_dist;
-	}
-
-	if (of_property_read_u32(node, "#redistributor-regions", &nr_redist_regions))
-		nr_redist_regions = 1;
-
-	rdist_regs = kzalloc(sizeof(*rdist_regs) * nr_redist_regions, GFP_KERNEL);
-	if (!rdist_regs) {
-		err = -ENOMEM;
-		goto out_unmap_dist;
-	}
-
-	for (i = 0; i < nr_redist_regions; i++) {
-		struct resource res;
-		int ret;
-
-		ret = of_address_to_resource(node, 1 + i, &res);
-		rdist_regs[i].redist_base = of_iomap(node, 1 + i);
-		if (ret || !rdist_regs[i].redist_base) {
-			pr_err("%s: couldn't map region %d\n",
-			       node->full_name, i);
-			err = -ENODEV;
-			goto out_unmap_rdist;
-		}
-		rdist_regs[i].phys_base = res.start;
-	}
-
-	if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
-		redist_stride = 0;
 
 	if (!is_hyp_mode_available())
 		static_key_slow_dec(&supports_deactivate);
@@ -889,8 +846,8 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 		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.domain = irq_domain_create_tree(handle, &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)) {
@@ -900,7 +857,9 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 
 	set_handle_irq(gic_handle_irq);
 
-	if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
+	node = to_of_node(handle);
+	if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis() &&
+	    node) /* Temp hack to prevent ITS init for ACPI */
 		its_init(node, &gic_data.rdists, gic_data.domain);
 
 	gic_smp_init();
@@ -914,6 +873,73 @@ out_free:
 	if (gic_data.domain)
 		irq_domain_remove(gic_data.domain);
 	free_percpu(gic_data.rdists.rdist);
+	return err;
+}
+
+static int __init gic_validate_dist_version(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;
+}
+
+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;
+	int err, i;
+
+	dist_base = of_iomap(node, 0);
+	if (!dist_base) {
+		pr_err("%s: unable to map gic dist registers\n",
+			node->full_name);
+		return -ENXIO;
+	}
+
+	err = gic_validate_dist_version(dist_base);
+	if (err) {
+		pr_err("%s: no distributor detected, giving up\n",
+			node->full_name);
+		goto out_unmap_dist;
+	}
+
+	if (of_property_read_u32(node, "#redistributor-regions", &nr_redist_regions))
+		nr_redist_regions = 1;
+
+	rdist_regs = kzalloc(sizeof(*rdist_regs) * nr_redist_regions, GFP_KERNEL);
+	if (!rdist_regs) {
+		err = -ENOMEM;
+		goto out_unmap_dist;
+	}
+
+	for (i = 0; i < nr_redist_regions; i++) {
+		struct resource res;
+		int ret;
+
+		ret = of_address_to_resource(node, 1 + i, &res);
+		rdist_regs[i].redist_base = of_iomap(node, 1 + i);
+		if (ret || !rdist_regs[i].redist_base) {
+			pr_err("%s: couldn't map region %d\n",
+			       node->full_name, i);
+			err = -ENODEV;
+			goto out_unmap_rdist;
+		}
+		rdist_regs[i].phys_base = res.start;
+	}
+
+	if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
+		redist_stride = 0;
+
+	err = gic_init_bases(dist_base, rdist_regs, nr_redist_regions,
+			     redist_stride, &node->fwnode);
+	if (!err)
+		return 0;
+
 out_unmap_rdist:
 	for (i = 0; i < nr_redist_regions; i++)
 		if (rdist_regs[i].redist_base)
-- 
1.9.1


  reply	other threads:[~2015-12-17 11:52 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-17 11:52 [PATCH V2 00/10] Introduce ACPI world to GICv3 & ITS irqchip Tomasz Nowicki
2015-12-17 11:52 ` Tomasz Nowicki [this message]
2015-12-17 11:52 ` [PATCH V2 02/10] irqchip / GICv3: Add ACPI support for GICv3+ initialization Tomasz Nowicki
2015-12-17 13:44   ` kbuild test robot
2015-12-17 15:12     ` Tomasz Nowicki
2015-12-17 11:52 ` [PATCH V2 03/10] irqchip,GICv3,ACPI: Add redistributor support via GICC structures Tomasz Nowicki
2016-01-12 12:03   ` Marc Zyngier
2016-01-12 15:05     ` Hanjun Guo
2016-01-12 16:16       ` Marc Zyngier
2016-01-12 17:14         ` Tomasz Nowicki
2016-01-12 16:45     ` Tomasz Nowicki
2016-01-13  1:52       ` Hanjun Guo
2016-01-13  8:35         ` Marc Zyngier
2016-01-13  9:15           ` Hanjun Guo
2015-12-17 11:52 ` [PATCH V2 04/10] irqchip / GICv3: remove gic root node in ITS Tomasz Nowicki
2015-12-17 11:52 ` [PATCH V2 05/10] irqchip, gicv3, its: Mark its_init() and its children as __init Tomasz Nowicki
2015-12-17 11:52 ` [PATCH V2 06/10] irqchip/GICv3/ITS: Refator ITS dt init code to prepare for ACPI Tomasz Nowicki
2015-12-18 10:57   ` Hanjun Guo
2015-12-18 11:14     ` Tomasz Nowicki
2015-12-17 11:52 ` [PATCH V2 07/10] ARM64, ACPI, PCI: I/O Remapping Table (IORT) initial support Tomasz Nowicki
2015-12-17 13:24   ` Tomasz Nowicki
2015-12-18 12:11     ` Hanjun Guo
2015-12-18 11:18   ` Hanjun Guo
2015-12-17 11:52 ` [PATCH V2 08/10] irqchip, gicv3, its: Probe ITS in the ACPI way Tomasz Nowicki
2015-12-17 11:52 ` [PATCH V2 09/10] acpi, gicv3, msi: Factor out code that might be reused for ACPI equivalent Tomasz Nowicki
2015-12-17 11:52 ` [PATCH V2 10/10] acpi, gicv3, its: Use MADT ITS subtable to do PCI/MSI domain initialization Tomasz Nowicki
2015-12-17 12:46   ` kbuild test robot

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=1450353133-15992-2-git-send-email-tn@semihalf.com \
    --to=tn@semihalf.com \
    --cc=Catalin.Marinas@arm.com \
    --cc=Suravee.Suthikulpanit@amd.com \
    --cc=ddaney.cavm@gmail.com \
    --cc=graeme.gregory@linaro.org \
    --cc=guohanjun@huawei.com \
    --cc=hanjun.guo@linaro.org \
    --cc=jason@lakedaemon.net \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=marc.zyngier@arm.com \
    --cc=mw@semihalf.com \
    --cc=rjw@rjwysocki.net \
    --cc=robert.richter@caviumnetworks.com \
    --cc=shijie.huang@arm.com \
    --cc=tglx@linutronix.de \
    --cc=tomasz.nowicki@linaro.org \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

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

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

Powered by JetHome