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
next prev 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).