aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2014-11-26 12:55:31 -0500
committerArnd Bergmann <arnd@arndb.de>2014-11-27 08:01:55 -0500
commit9a343b9eb8c1f8db9dae804709a6578379a538f3 (patch)
tree524bd793b8f74539cf474d16497a9b200b403d60 /arch/arm/mach-tegra
parent5d01410fe4d92081f349b013a2e7a95429e4f2c9 (diff)
ARM: tegra: irq: fix buggy usage of irq_data irq field
The crazy gic_arch_extn thing that Tegra uses contains multiple references to the irq field in struct irq_data, and uses this to directly poke hardware register. But irq is the *virtual* irq number, something that has nothing to do with the actual HW irq (stored in the hwirq field). And once we put the stacked domain code in action, the whole thing explodes, as these two values are *very* different: root@bacon-fat:~# cat /proc/interrupts CPU0 CPU1 16: 25801 2075 GIC 29 twd 17: 0 0 GIC 73 timer0 112: 0 0 GPIO 58 c8000600.sdhci cd 123: 0 0 GPIO 69 c8000200.sdhci cd 279: 1126 0 GIC 122 serial 281: 0 0 GIC 70 7000c000.i2c 282: 0 0 GIC 116 7000c400.i2c 283: 0 0 GIC 124 7000c500.i2c 284: 300 0 GIC 85 7000d000.i2c [...] Just replacing all instances of irq with hwirq fixes the issue. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Acked-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r--arch/arm/mach-tegra/irq.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index da7be13aecce..ab95f5391a2b 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -99,42 +99,42 @@ static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
99 99
100static void tegra_mask(struct irq_data *d) 100static void tegra_mask(struct irq_data *d)
101{ 101{
102 if (d->irq < FIRST_LEGACY_IRQ) 102 if (d->hwirq < FIRST_LEGACY_IRQ)
103 return; 103 return;
104 104
105 tegra_irq_write_mask(d->irq, ICTLR_CPU_IER_CLR); 105 tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IER_CLR);
106} 106}
107 107
108static void tegra_unmask(struct irq_data *d) 108static void tegra_unmask(struct irq_data *d)
109{ 109{
110 if (d->irq < FIRST_LEGACY_IRQ) 110 if (d->hwirq < FIRST_LEGACY_IRQ)
111 return; 111 return;
112 112
113 tegra_irq_write_mask(d->irq, ICTLR_CPU_IER_SET); 113 tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IER_SET);
114} 114}
115 115
116static void tegra_ack(struct irq_data *d) 116static void tegra_ack(struct irq_data *d)
117{ 117{
118 if (d->irq < FIRST_LEGACY_IRQ) 118 if (d->hwirq < FIRST_LEGACY_IRQ)
119 return; 119 return;
120 120
121 tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_CLR); 121 tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IEP_FIR_CLR);
122} 122}
123 123
124static void tegra_eoi(struct irq_data *d) 124static void tegra_eoi(struct irq_data *d)
125{ 125{
126 if (d->irq < FIRST_LEGACY_IRQ) 126 if (d->hwirq < FIRST_LEGACY_IRQ)
127 return; 127 return;
128 128
129 tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_CLR); 129 tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IEP_FIR_CLR);
130} 130}
131 131
132static int tegra_retrigger(struct irq_data *d) 132static int tegra_retrigger(struct irq_data *d)
133{ 133{
134 if (d->irq < FIRST_LEGACY_IRQ) 134 if (d->hwirq < FIRST_LEGACY_IRQ)
135 return 0; 135 return 0;
136 136
137 tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_SET); 137 tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IEP_FIR_SET);
138 138
139 return 1; 139 return 1;
140} 140}
@@ -142,7 +142,7 @@ static int tegra_retrigger(struct irq_data *d)
142#ifdef CONFIG_PM_SLEEP 142#ifdef CONFIG_PM_SLEEP
143static int tegra_set_wake(struct irq_data *d, unsigned int enable) 143static int tegra_set_wake(struct irq_data *d, unsigned int enable)
144{ 144{
145 u32 irq = d->irq; 145 u32 irq = d->hwirq;
146 u32 index, mask; 146 u32 index, mask;
147 147
148 if (irq < FIRST_LEGACY_IRQ || 148 if (irq < FIRST_LEGACY_IRQ ||