diff options
Diffstat (limited to 'arch/arm/mach-tegra/irq.c')
-rw-r--r-- | arch/arm/mach-tegra/irq.c | 77 |
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 | |||
53 | static 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 | |||
60 | static 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 | |||
34 | static void tegra_mask(struct irq_data *d) | 74 | static 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 | ||
40 | static void tegra_unmask(struct irq_data *d) | 82 | static 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 | ||
46 | static void tegra_ack(struct irq_data *d) | 90 | static 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 | ||
52 | static int tegra_retrigger(struct irq_data *d) | 98 | static 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 | ||
61 | void __init tegra_init_irq(void) | 108 | void __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; |