aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/irq.c')
-rw-r--r--arch/arm/mach-tegra/irq.c77
1 files changed, 65 insertions, 12 deletions
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index 4fa7a37ea5e4..da1749108c7d 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -18,8 +18,6 @@
18 */ 18 */
19 19
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/delay.h>
22#include <linux/init.h>
23#include <linux/interrupt.h> 21#include <linux/interrupt.h>
24#include <linux/irq.h> 22#include <linux/irq.h>
25#include <linux/io.h> 23#include <linux/io.h>
@@ -27,40 +25,95 @@
27#include <asm/hardware/gic.h> 25#include <asm/hardware/gic.h>
28 26
29#include <mach/iomap.h> 27#include <mach/iomap.h>
30#include <mach/legacy_irq.h>
31 28
32#include "board.h" 29#include "board.h"
33 30
31#define INT_SYS_NR (INT_GPIO_BASE - INT_PRI_BASE)
32#define INT_SYS_SZ (INT_SEC_BASE - INT_PRI_BASE)
33#define PPI_NR ((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ)
34
35#define ICTLR_CPU_IEP_VFIQ 0x08
36#define ICTLR_CPU_IEP_FIR 0x14
37#define ICTLR_CPU_IEP_FIR_SET 0x18
38#define ICTLR_CPU_IEP_FIR_CLR 0x1c
39
40#define ICTLR_CPU_IER 0x20
41#define ICTLR_CPU_IER_SET 0x24
42#define ICTLR_CPU_IER_CLR 0x28
43#define ICTLR_CPU_IEP_CLASS 0x2C
44
45#define ICTLR_COP_IER 0x30
46#define ICTLR_COP_IER_SET 0x34
47#define ICTLR_COP_IER_CLR 0x38
48#define ICTLR_COP_IEP_CLASS 0x3c
49
50#define NUM_ICTLRS 4
51#define FIRST_LEGACY_IRQ 32
52
53static void __iomem *ictlr_reg_base[] = {
54 IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE),
55 IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE),
56 IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE),
57 IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE),
58};
59
60static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
61{
62 void __iomem *base;
63 u32 mask;
64
65 BUG_ON(irq < FIRST_LEGACY_IRQ ||
66 irq >= FIRST_LEGACY_IRQ + NUM_ICTLRS * 32);
67
68 base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32];
69 mask = BIT((irq - FIRST_LEGACY_IRQ) % 32);
70
71 __raw_writel(mask, base + reg);
72}
73
34static void tegra_mask(struct irq_data *d) 74static void tegra_mask(struct irq_data *d)
35{ 75{
36 if (d->irq >= 32) 76 if (d->irq < FIRST_LEGACY_IRQ)
37 tegra_legacy_mask_irq(d->irq); 77 return;
78
79 tegra_irq_write_mask(d->irq, ICTLR_CPU_IER_CLR);
38} 80}
39 81
40static void tegra_unmask(struct irq_data *d) 82static void tegra_unmask(struct irq_data *d)
41{ 83{
42 if (d->irq >= 32) 84 if (d->irq < FIRST_LEGACY_IRQ)
43 tegra_legacy_unmask_irq(d->irq); 85 return;
86
87 tegra_irq_write_mask(d->irq, ICTLR_CPU_IER_SET);
44} 88}
45 89
46static void tegra_ack(struct irq_data *d) 90static void tegra_ack(struct irq_data *d)
47{ 91{
48 if (d->irq >= 32) 92 if (d->irq < FIRST_LEGACY_IRQ)
49 tegra_legacy_force_irq_clr(d->irq); 93 return;
94
95 tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_CLR);
50} 96}
51 97
52static int tegra_retrigger(struct irq_data *d) 98static int tegra_retrigger(struct irq_data *d)
53{ 99{
54 if (d->irq < 32) 100 if (d->irq < FIRST_LEGACY_IRQ)
55 return 0; 101 return 0;
56 102
57 tegra_legacy_force_irq_set(d->irq); 103 tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_SET);
104
58 return 1; 105 return 1;
59} 106}
60 107
61void __init tegra_init_irq(void) 108void __init tegra_init_irq(void)
62{ 109{
63 tegra_init_legacy_irq(); 110 int i;
111
112 for (i = 0; i < NUM_ICTLRS; i++) {
113 void __iomem *ictlr = ictlr_reg_base[i];
114 writel(~0, ictlr + ICTLR_CPU_IER_CLR);
115 writel(0, ictlr + ICTLR_CPU_IEP_CLASS);
116 }
64 117
65 gic_arch_extn.irq_ack = tegra_ack; 118 gic_arch_extn.irq_ack = tegra_ack;
66 gic_arch_extn.irq_mask = tegra_mask; 119 gic_arch_extn.irq_mask = tegra_mask;