aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter De Schrijver <pdeschrijver@nvidia.com>2012-01-05 03:31:45 +0000
committerOlof Johansson <olof@lixom.net>2012-02-06 09:16:14 -0800
commitcaa4868ee07029e60450909960652b96a50ebfbd (patch)
treec23e808d4e10641210039cdf53862cf8e1f1cfe0
parent62aa2b537c6f5957afd98e29f96897419ed5ebab (diff)
ARM: tegra: add support for tegra30 interrupts
Tegra30 has 1 extra legacy interrupt controller. Use the GIC ITLinesNumber field to determine how many interrupt controllers we have and initialize appropriately. Also make room for the extra tegra30 interrupts by moving the GPIO IRQ base. This shouldn't affect existing code as it determines the correct IRQ number for GPIOs using TEGRA_GPIO_TO_IRQ(). Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com> Acked-by: Stephen Warren <swarren@nvidia.com> Tested-by: Stephen Warren <swarren@nvidia.com> Acked-by: Colin Cross <ccross@android.com> Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r--arch/arm/mach-tegra/include/mach/iomap.h3
-rw-r--r--arch/arm/mach-tegra/include/mach/irqs.h7
-rw-r--r--arch/arm/mach-tegra/irq.c20
3 files changed, 23 insertions, 7 deletions
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
index 19dec3ac085..67644c905d8 100644
--- a/arch/arm/mach-tegra/include/mach/iomap.h
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -74,6 +74,9 @@
#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/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
index a2146cd6867..aad1a2c1d71 100644
--- a/arch/arm/mach-tegra/include/mach/irqs.h
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -165,11 +165,12 @@
#define INT_QUAD_RES_30 (INT_QUAD_BASE + 30)
#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31)
-#define INT_MAIN_NR (INT_QUAD_BASE + 32 - INT_PRI_BASE)
-
+/* Tegra30 has 5 banks of 32 IRQs */
+#define INT_MAIN_NR (32 * 5)
#define INT_GPIO_BASE (INT_PRI_BASE + INT_MAIN_NR)
-#define INT_GPIO_NR (28 * 8)
+/* Tegra30 has 8 banks of 32 GPIOs */
+#define INT_GPIO_NR (32 * 8)
#define TEGRA_NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR)
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index 4e1afcd54fa..2f5bd2db8e1 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -44,14 +44,16 @@
#define ICTLR_COP_IER_CLR 0x38
#define ICTLR_COP_IEP_CLASS 0x3c
-#define NUM_ICTLRS 4
#define FIRST_LEGACY_IRQ 32
+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 inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
@@ -60,7 +62,7 @@ static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
u32 mask;
BUG_ON(irq < FIRST_LEGACY_IRQ ||
- irq >= FIRST_LEGACY_IRQ + NUM_ICTLRS * 32);
+ irq >= FIRST_LEGACY_IRQ + num_ictlrs * 32);
base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32];
mask = BIT((irq - FIRST_LEGACY_IRQ) % 32);
@@ -113,8 +115,18 @@ static int tegra_retrigger(struct irq_data *d)
void __init tegra_init_irq(void)
{
int i;
+ void __iomem *distbase;
+
+ distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
+ 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);
+ }
- for (i = 0; i < NUM_ICTLRS; i++) {
+ for (i = 0; i < num_ictlrs; i++) {
void __iomem *ictlr = ictlr_reg_base[i];
writel(~0, ictlr + ICTLR_CPU_IER_CLR);
writel(0, ictlr + ICTLR_CPU_IEP_CLASS);
@@ -131,6 +143,6 @@ void __init tegra_init_irq(void)
* initialized elsewhere under DT.
*/
if (!of_have_populated_dt())
- gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
+ gic_init(0, 29, distbase,
IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
}