From: Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> To: Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org> Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Subject: [PATCH v4 3/5] ARM: tegra: Initialize interrupt controller from DT Date: Thu, 28 Aug 2014 17:31:17 +0200 [thread overview] Message-ID: <1409239879-12376-3-git-send-email-thierry.reding@gmail.com> (raw) In-Reply-To: <1409239879-12376-1-git-send-email-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> Obtains the register ranges for the legacy interrupt controller from DT and provide hard-coded values as fallback. Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> --- Changes in v4: - check for Tegra20 in non-DT fallback using of_machine_is_compatible() - cleanup warning messages Changes in v3: - fixup subject prefix Changes in v2: - check for the exact number of controllers expected - fallback to tegra_chip_id for non-DT - warn on parsing errors arch/arm/mach-tegra/iomap.h | 18 ------- arch/arm/mach-tegra/irq.c | 122 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 101 insertions(+), 39 deletions(-) diff --git a/arch/arm/mach-tegra/iomap.h b/arch/arm/mach-tegra/iomap.h index ee79808e93a3..52bbb5c8fe84 100644 --- a/arch/arm/mach-tegra/iomap.h +++ b/arch/arm/mach-tegra/iomap.h @@ -28,24 +28,6 @@ #define TEGRA_ARM_PERIF_BASE 0x50040000 #define TEGRA_ARM_PERIF_SIZE SZ_8K -#define TEGRA_ARM_INT_DIST_BASE 0x50041000 -#define TEGRA_ARM_INT_DIST_SIZE SZ_4K - -#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000 -#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64 - -#define TEGRA_SECONDARY_ICTLR_BASE 0x60004100 -#define TEGRA_SECONDARY_ICTLR_SIZE SZ_64 - -#define TEGRA_TERTIARY_ICTLR_BASE 0x60004200 -#define TEGRA_TERTIARY_ICTLR_SIZE SZ_64 - -#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300 -#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64 - -#define TEGRA_QUINARY_ICTLR_BASE 0x60004400 -#define TEGRA_QUINARY_ICTLR_SIZE SZ_64 - #define TEGRA_TMR1_BASE 0x60005000 #define TEGRA_TMR1_SIZE SZ_8 diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index da7be13aecce..636ebfd466cb 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -27,8 +27,7 @@ #include <linux/of.h> #include <linux/syscore_ops.h> -#include "board.h" -#include "iomap.h" +#include <soc/tegra/fuse.h> #define ICTLR_CPU_IEP_VFIQ 0x08 #define ICTLR_CPU_IEP_FIR 0x14 @@ -52,13 +51,7 @@ static int num_ictlrs; -static void __iomem *ictlr_reg_base[] = { - IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE), -}; +static void __iomem *ictlr_reg_base[] = { NULL, NULL, NULL, NULL, NULL }; #ifdef CONFIG_PM_SLEEP static u32 cop_ier[TEGRA_MAX_NUM_ICTLRS]; @@ -70,10 +63,11 @@ static u32 ictlr_wake_mask[TEGRA_MAX_NUM_ICTLRS]; static void __iomem *tegra_gic_cpu_base; #endif +static void __iomem *distbase; + bool tegra_pending_sgi(void) { u32 pending_set; - void __iomem *distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE); pending_set = readl_relaxed(distbase + GIC_DIST_PENDING_SET); @@ -255,24 +249,109 @@ static void tegra114_gic_cpu_pm_registration(void) static void tegra114_gic_cpu_pm_registration(void) { } #endif +static struct resource ictlr_regs[] = { + { .start = 0x60004000, .end = 0x6000403f, .flags = IORESOURCE_MEM }, + { .start = 0x60004100, .end = 0x6000413f, .flags = IORESOURCE_MEM }, + { .start = 0x60004200, .end = 0x6000423f, .flags = IORESOURCE_MEM }, + { .start = 0x60004300, .end = 0x6000433f, .flags = IORESOURCE_MEM }, + { .start = 0x60004400, .end = 0x6000443f, .flags = IORESOURCE_MEM }, +}; + +struct tegra_ictlr_soc { + unsigned int num_ictlrs; +}; + +static const struct tegra_ictlr_soc tegra20_ictlr_soc = { + .num_ictlrs = 4, +}; + +static const struct tegra_ictlr_soc tegra30_ictlr_soc = { + .num_ictlrs = 5, +}; + +static const struct of_device_id ictlr_matches[] = { + { .compatible = "nvidia,tegra30-ictlr", .data = &tegra30_ictlr_soc }, + { .compatible = "nvidia,tegra20-ictlr", .data = &tegra20_ictlr_soc }, + { } +}; + +static const struct of_device_id gic_matches[] = { + { .compatible = "arm,cortex-a15-gic", }, + { .compatible = "arm,cortex-a9-gic", }, + { } +}; + void __init tegra_init_irq(void) { - int i; - void __iomem *distbase; + unsigned int max_ictlrs = ARRAY_SIZE(ictlr_regs), i; + const struct of_device_id *match; + struct device_node *np; + struct resource res; + + np = of_find_matching_node_and_match(NULL, ictlr_matches, &match); + if (np) { + const struct tegra_ictlr_soc *soc = match->data; + + for (i = 0; i < soc->num_ictlrs; i++) { + if (of_address_to_resource(np, i, &res) < 0) + break; + + ictlr_regs[i] = res; + } + + WARN(i != soc->num_ictlrs, + "Found %u interrupt controllers in DT; expected %u.\n", + i, soc->num_ictlrs); + + max_ictlrs = soc->num_ictlrs; + of_node_put(np); + } else { + /* + * If no matching device node was found, fall back to using + * the chip ID. + */ + + /* Tegra30 and later have five interrupt controllers, ... */ + max_ictlrs = ARRAY_SIZE(ictlr_regs); + + /* ..., but Tegra20 only has four. */ + if (of_machine_is_compatible("nvidia,tegra20")) + max_ictlrs--; + } - distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE); + memset(&res, 0, sizeof(res)); + + np = of_find_matching_node(NULL, gic_matches); + if (np) { + if (of_address_to_resource(np, 0, &res) < 0) + WARN(1, "GIC registers are missing from DT\n"); + + of_node_put(np); + } + + if (res.start == 0 || res.end == 0) { + res.start = 0x50041000; + res.end = 0x50041fff; + res.flags = IORESOURCE_MEM; + } + + distbase = ioremap_nocache(res.start, resource_size(&res)); num_ictlrs = readl_relaxed(distbase + GIC_DIST_CTR) & 0x1f; - if (num_ictlrs > ARRAY_SIZE(ictlr_reg_base)) { - WARN(1, "Too many (%d) interrupt controllers found. Maximum is %d.", - num_ictlrs, ARRAY_SIZE(ictlr_reg_base)); - num_ictlrs = ARRAY_SIZE(ictlr_reg_base); + if (num_ictlrs != max_ictlrs) { + WARN(1, "Found %u interrupt controllers; expected %u.\n", + num_ictlrs, max_ictlrs); + num_ictlrs = max_ictlrs; } for (i = 0; i < num_ictlrs; i++) { - void __iomem *ictlr = ictlr_reg_base[i]; + struct resource *regs = &ictlr_regs[i]; + void __iomem *ictlr; + + ictlr = ioremap_nocache(regs->start, resource_size(regs)); writel(~0, ictlr + ICTLR_CPU_IER_CLR); writel(0, ictlr + ICTLR_CPU_IEP_CLASS); + ictlr_reg_base[i] = ictlr; } gic_arch_extn.irq_ack = tegra_ack; @@ -287,9 +366,10 @@ void __init tegra_init_irq(void) * Check if there is a devicetree present, since the GIC will be * initialized elsewhere under DT. */ - if (!of_have_populated_dt()) - gic_init(0, 29, distbase, - IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); + if (!of_have_populated_dt()) { + void __iomem *cpubase = ioremap_nocache(0x50040000, 0x2000); + gic_init(0, 29, distbase, cpubase); + } tegra114_gic_cpu_pm_registration(); } -- 2.0.4
WARNING: multiple messages have this Message-ID (diff)
From: thierry.reding@gmail.com (Thierry Reding) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v4 3/5] ARM: tegra: Initialize interrupt controller from DT Date: Thu, 28 Aug 2014 17:31:17 +0200 [thread overview] Message-ID: <1409239879-12376-3-git-send-email-thierry.reding@gmail.com> (raw) In-Reply-To: <1409239879-12376-1-git-send-email-thierry.reding@gmail.com> From: Thierry Reding <treding@nvidia.com> Obtains the register ranges for the legacy interrupt controller from DT and provide hard-coded values as fallback. Signed-off-by: Thierry Reding <treding@nvidia.com> --- Changes in v4: - check for Tegra20 in non-DT fallback using of_machine_is_compatible() - cleanup warning messages Changes in v3: - fixup subject prefix Changes in v2: - check for the exact number of controllers expected - fallback to tegra_chip_id for non-DT - warn on parsing errors arch/arm/mach-tegra/iomap.h | 18 ------- arch/arm/mach-tegra/irq.c | 122 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 101 insertions(+), 39 deletions(-) diff --git a/arch/arm/mach-tegra/iomap.h b/arch/arm/mach-tegra/iomap.h index ee79808e93a3..52bbb5c8fe84 100644 --- a/arch/arm/mach-tegra/iomap.h +++ b/arch/arm/mach-tegra/iomap.h @@ -28,24 +28,6 @@ #define TEGRA_ARM_PERIF_BASE 0x50040000 #define TEGRA_ARM_PERIF_SIZE SZ_8K -#define TEGRA_ARM_INT_DIST_BASE 0x50041000 -#define TEGRA_ARM_INT_DIST_SIZE SZ_4K - -#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000 -#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64 - -#define TEGRA_SECONDARY_ICTLR_BASE 0x60004100 -#define TEGRA_SECONDARY_ICTLR_SIZE SZ_64 - -#define TEGRA_TERTIARY_ICTLR_BASE 0x60004200 -#define TEGRA_TERTIARY_ICTLR_SIZE SZ_64 - -#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300 -#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64 - -#define TEGRA_QUINARY_ICTLR_BASE 0x60004400 -#define TEGRA_QUINARY_ICTLR_SIZE SZ_64 - #define TEGRA_TMR1_BASE 0x60005000 #define TEGRA_TMR1_SIZE SZ_8 diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index da7be13aecce..636ebfd466cb 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -27,8 +27,7 @@ #include <linux/of.h> #include <linux/syscore_ops.h> -#include "board.h" -#include "iomap.h" +#include <soc/tegra/fuse.h> #define ICTLR_CPU_IEP_VFIQ 0x08 #define ICTLR_CPU_IEP_FIR 0x14 @@ -52,13 +51,7 @@ static int num_ictlrs; -static void __iomem *ictlr_reg_base[] = { - IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE), -}; +static void __iomem *ictlr_reg_base[] = { NULL, NULL, NULL, NULL, NULL }; #ifdef CONFIG_PM_SLEEP static u32 cop_ier[TEGRA_MAX_NUM_ICTLRS]; @@ -70,10 +63,11 @@ static u32 ictlr_wake_mask[TEGRA_MAX_NUM_ICTLRS]; static void __iomem *tegra_gic_cpu_base; #endif +static void __iomem *distbase; + bool tegra_pending_sgi(void) { u32 pending_set; - void __iomem *distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE); pending_set = readl_relaxed(distbase + GIC_DIST_PENDING_SET); @@ -255,24 +249,109 @@ static void tegra114_gic_cpu_pm_registration(void) static void tegra114_gic_cpu_pm_registration(void) { } #endif +static struct resource ictlr_regs[] = { + { .start = 0x60004000, .end = 0x6000403f, .flags = IORESOURCE_MEM }, + { .start = 0x60004100, .end = 0x6000413f, .flags = IORESOURCE_MEM }, + { .start = 0x60004200, .end = 0x6000423f, .flags = IORESOURCE_MEM }, + { .start = 0x60004300, .end = 0x6000433f, .flags = IORESOURCE_MEM }, + { .start = 0x60004400, .end = 0x6000443f, .flags = IORESOURCE_MEM }, +}; + +struct tegra_ictlr_soc { + unsigned int num_ictlrs; +}; + +static const struct tegra_ictlr_soc tegra20_ictlr_soc = { + .num_ictlrs = 4, +}; + +static const struct tegra_ictlr_soc tegra30_ictlr_soc = { + .num_ictlrs = 5, +}; + +static const struct of_device_id ictlr_matches[] = { + { .compatible = "nvidia,tegra30-ictlr", .data = &tegra30_ictlr_soc }, + { .compatible = "nvidia,tegra20-ictlr", .data = &tegra20_ictlr_soc }, + { } +}; + +static const struct of_device_id gic_matches[] = { + { .compatible = "arm,cortex-a15-gic", }, + { .compatible = "arm,cortex-a9-gic", }, + { } +}; + void __init tegra_init_irq(void) { - int i; - void __iomem *distbase; + unsigned int max_ictlrs = ARRAY_SIZE(ictlr_regs), i; + const struct of_device_id *match; + struct device_node *np; + struct resource res; + + np = of_find_matching_node_and_match(NULL, ictlr_matches, &match); + if (np) { + const struct tegra_ictlr_soc *soc = match->data; + + for (i = 0; i < soc->num_ictlrs; i++) { + if (of_address_to_resource(np, i, &res) < 0) + break; + + ictlr_regs[i] = res; + } + + WARN(i != soc->num_ictlrs, + "Found %u interrupt controllers in DT; expected %u.\n", + i, soc->num_ictlrs); + + max_ictlrs = soc->num_ictlrs; + of_node_put(np); + } else { + /* + * If no matching device node was found, fall back to using + * the chip ID. + */ + + /* Tegra30 and later have five interrupt controllers, ... */ + max_ictlrs = ARRAY_SIZE(ictlr_regs); + + /* ..., but Tegra20 only has four. */ + if (of_machine_is_compatible("nvidia,tegra20")) + max_ictlrs--; + } - distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE); + memset(&res, 0, sizeof(res)); + + np = of_find_matching_node(NULL, gic_matches); + if (np) { + if (of_address_to_resource(np, 0, &res) < 0) + WARN(1, "GIC registers are missing from DT\n"); + + of_node_put(np); + } + + if (res.start == 0 || res.end == 0) { + res.start = 0x50041000; + res.end = 0x50041fff; + res.flags = IORESOURCE_MEM; + } + + distbase = ioremap_nocache(res.start, resource_size(&res)); num_ictlrs = readl_relaxed(distbase + GIC_DIST_CTR) & 0x1f; - if (num_ictlrs > ARRAY_SIZE(ictlr_reg_base)) { - WARN(1, "Too many (%d) interrupt controllers found. Maximum is %d.", - num_ictlrs, ARRAY_SIZE(ictlr_reg_base)); - num_ictlrs = ARRAY_SIZE(ictlr_reg_base); + if (num_ictlrs != max_ictlrs) { + WARN(1, "Found %u interrupt controllers; expected %u.\n", + num_ictlrs, max_ictlrs); + num_ictlrs = max_ictlrs; } for (i = 0; i < num_ictlrs; i++) { - void __iomem *ictlr = ictlr_reg_base[i]; + struct resource *regs = &ictlr_regs[i]; + void __iomem *ictlr; + + ictlr = ioremap_nocache(regs->start, resource_size(regs)); writel(~0, ictlr + ICTLR_CPU_IER_CLR); writel(0, ictlr + ICTLR_CPU_IEP_CLASS); + ictlr_reg_base[i] = ictlr; } gic_arch_extn.irq_ack = tegra_ack; @@ -287,9 +366,10 @@ void __init tegra_init_irq(void) * Check if there is a devicetree present, since the GIC will be * initialized elsewhere under DT. */ - if (!of_have_populated_dt()) - gic_init(0, 29, distbase, - IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); + if (!of_have_populated_dt()) { + void __iomem *cpubase = ioremap_nocache(0x50040000, 0x2000); + gic_init(0, 29, distbase, cpubase); + } tegra114_gic_cpu_pm_registration(); } -- 2.0.4
next prev parent reply other threads:[~2014-08-28 15:31 UTC|newest] Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top 2014-08-28 15:31 [PATCH v4 1/5] of: Add NVIDIA Tegra Legacy Interrupt Controller binding Thierry Reding 2014-08-28 15:31 ` Thierry Reding [not found] ` <1409239879-12376-1-git-send-email-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2014-08-28 15:31 ` [PATCH v4 2/5] ARM: tegra: Add legacy interrupt controller nodes Thierry Reding 2014-08-28 15:31 ` Thierry Reding [not found] ` <1409239879-12376-2-git-send-email-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2014-08-28 16:11 ` Arnd Bergmann 2014-08-28 16:11 ` Arnd Bergmann 2014-09-01 8:16 ` Peter De Schrijver 2014-09-01 8:16 ` Peter De Schrijver 2014-08-28 15:31 ` Thierry Reding [this message] 2014-08-28 15:31 ` [PATCH v4 3/5] ARM: tegra: Initialize interrupt controller from DT Thierry Reding [not found] ` <1409239879-12376-3-git-send-email-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2014-08-28 16:10 ` Arnd Bergmann 2014-08-28 16:10 ` Arnd Bergmann 2014-08-29 7:31 ` Thierry Reding 2014-08-29 7:31 ` Thierry Reding 2014-08-29 14:24 ` Thierry Reding 2014-08-29 14:24 ` Thierry Reding 2014-08-29 15:04 ` Thierry Reding 2014-08-29 15:04 ` Thierry Reding 2014-08-29 19:53 ` Arnd Bergmann 2014-08-29 19:53 ` Arnd Bergmann 2014-08-30 15:54 ` Jason Cooper 2014-08-30 15:54 ` Jason Cooper [not found] ` <20140830155459.GI3683-u4khhh1J0LxI1Ri9qeTfzeTW4wlIGRCZ@public.gmane.org> 2014-09-01 8:45 ` Arnd Bergmann 2014-09-01 8:45 ` Arnd Bergmann 2014-09-01 8:47 ` Thierry Reding 2014-09-01 8:47 ` Thierry Reding 2014-08-29 3:27 ` Varka Bhadram 2014-08-29 3:27 ` Varka Bhadram [not found] ` <53FFF335.1020402-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2014-08-29 7:29 ` Thierry Reding 2014-08-29 7:29 ` Thierry Reding 2014-08-28 15:31 ` [PATCH v4 4/5] ARM: tegra: Remove unused GIC initialization Thierry Reding 2014-08-28 15:31 ` Thierry Reding 2014-08-28 15:31 ` [PATCH v4 5/5] ARM: tegra: Remove unused defines Thierry Reding 2014-08-28 15:31 ` Thierry Reding
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=1409239879-12376-3-git-send-email-thierry.reding@gmail.com \ --to=thierry.reding-re5jqeeqqe8avxtiumwx3w@public.gmane.org \ --cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \ --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \ --cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \ --cc=swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.