diff options
Diffstat (limited to 'arch/arm/mach-tegra/irq.c')
-rw-r--r-- | arch/arm/mach-tegra/irq.c | 20 |
1 files changed, 16 insertions, 4 deletions
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 | ||
49 | static int num_ictlrs; | ||
50 | |||
50 | static void __iomem *ictlr_reg_base[] = { | 51 | static 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 | ||
57 | static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg) | 59 | 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) | |||
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) | |||
113 | void __init tegra_init_irq(void) | 115 | void __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 | } |