aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
authorPeter De Schrijver <pdeschrijver@nvidia.com>2012-01-04 22:31:45 -0500
committerOlof Johansson <olof@lixom.net>2012-02-06 12:16:14 -0500
commitcaa4868ee07029e60450909960652b96a50ebfbd (patch)
treec23e808d4e10641210039cdf53862cf8e1f1cfe0 /arch/arm/mach-tegra
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>
Diffstat (limited to 'arch/arm/mach-tegra')
-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 19dec3ac0854..67644c905d8e 100644
--- a/arch/arm/mach-tegra/include/mach/iomap.h
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -74,6 +74,9 @@
74#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300 74#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300
75#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64 75#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64
76 76
77#define TEGRA_QUINARY_ICTLR_BASE 0x60004400
78#define TEGRA_QUINARY_ICTLR_SIZE SZ_64
79
77#define TEGRA_TMR1_BASE 0x60005000 80#define TEGRA_TMR1_BASE 0x60005000
78#define TEGRA_TMR1_SIZE SZ_8 81#define TEGRA_TMR1_SIZE SZ_8
79 82
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
index a2146cd6867d..aad1a2c1d714 100644
--- a/arch/arm/mach-tegra/include/mach/irqs.h
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -165,11 +165,12 @@
165#define INT_QUAD_RES_30 (INT_QUAD_BASE + 30) 165#define INT_QUAD_RES_30 (INT_QUAD_BASE + 30)
166#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31) 166#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31)
167 167
168#define INT_MAIN_NR (INT_QUAD_BASE + 32 - INT_PRI_BASE) 168/* Tegra30 has 5 banks of 32 IRQs */
169 169#define INT_MAIN_NR (32 * 5)
170#define INT_GPIO_BASE (INT_PRI_BASE + INT_MAIN_NR) 170#define INT_GPIO_BASE (INT_PRI_BASE + INT_MAIN_NR)
171 171
172#define INT_GPIO_NR (28 * 8) 172/* Tegra30 has 8 banks of 32 GPIOs */
173#define INT_GPIO_NR (32 * 8)
173 174
174#define TEGRA_NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR) 175#define TEGRA_NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR)
175 176
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index 4e1afcd54fae..2f5bd2db8e1f 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -44,14 +44,16 @@
44#define ICTLR_COP_IER_CLR 0x38 44#define ICTLR_COP_IER_CLR 0x38
45#define ICTLR_COP_IEP_CLASS 0x3c 45#define ICTLR_COP_IEP_CLASS 0x3c
46 46
47#define NUM_ICTLRS 4
48#define FIRST_LEGACY_IRQ 32 47#define FIRST_LEGACY_IRQ 32
49 48
49static int num_ictlrs;
50
50static void __iomem *ictlr_reg_base[] = { 51static void __iomem *ictlr_reg_base[] = {
51 IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE), 52 IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE),
52 IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE), 53 IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE),
53 IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE), 54 IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE),
54 IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), 55 IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE),
56 IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE),
55}; 57};
56 58
57static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg) 59static 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)
60 u32 mask; 62 u32 mask;
61 63
62 BUG_ON(irq < FIRST_LEGACY_IRQ || 64 BUG_ON(irq < FIRST_LEGACY_IRQ ||
63 irq >= FIRST_LEGACY_IRQ + NUM_ICTLRS * 32); 65 irq >= FIRST_LEGACY_IRQ + num_ictlrs * 32);
64 66
65 base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32]; 67 base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32];
66 mask = BIT((irq - FIRST_LEGACY_IRQ) % 32); 68 mask = BIT((irq - FIRST_LEGACY_IRQ) % 32);
@@ -113,8 +115,18 @@ static int tegra_retrigger(struct irq_data *d)
113void __init tegra_init_irq(void) 115void __init tegra_init_irq(void)
114{ 116{
115 int i; 117 int i;
118 void __iomem *distbase;
119
120 distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
121 num_ictlrs = readl_relaxed(distbase + GIC_DIST_CTR) & 0x1f;
122
123 if (num_ictlrs > ARRAY_SIZE(ictlr_reg_base)) {
124 WARN(1, "Too many (%d) interrupt controllers found. Maximum is %d.",
125 num_ictlrs, ARRAY_SIZE(ictlr_reg_base));
126 num_ictlrs = ARRAY_SIZE(ictlr_reg_base);
127 }
116 128
117 for (i = 0; i < NUM_ICTLRS; i++) { 129 for (i = 0; i < num_ictlrs; i++) {
118 void __iomem *ictlr = ictlr_reg_base[i]; 130 void __iomem *ictlr = ictlr_reg_base[i];
119 writel(~0, ictlr + ICTLR_CPU_IER_CLR); 131 writel(~0, ictlr + ICTLR_CPU_IER_CLR);
120 writel(0, ictlr + ICTLR_CPU_IEP_CLASS); 132 writel(0, ictlr + ICTLR_CPU_IEP_CLASS);
@@ -131,6 +143,6 @@ void __init tegra_init_irq(void)
131 * initialized elsewhere under DT. 143 * initialized elsewhere under DT.
132 */ 144 */
133 if (!of_have_populated_dt()) 145 if (!of_have_populated_dt())
134 gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), 146 gic_init(0, 29, distbase,
135 IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); 147 IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
136} 148}