aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorAndreas Larsson <andreas@gaisler.com>2013-04-21 17:23:06 -0400
committerDavid S. Miller <davem@davemloft.net>2013-05-04 20:38:18 -0400
commit6e4741e73b266f02e4b6d166ac278afd86c4dceb (patch)
tree847c53a68bc766158812f782fc538de04e67b4eb /arch/sparc
parent75e448036bece2f7dfa96ec4a68410c68208a951 (diff)
sparc32, leon: Do not overwrite previously set irq flow handlers
This is needed because when scan_of_devices finds the GAISLER_GPTIMER core that corresponds to the SMP "ticker" timer, the previously set proper irq flow handler gets overwritten with an incorrect one. This leads to very flaky timer interrupt handling on some hardware. Proper updates to handlers can still be done using leon_update_virq_handling. Signed-off-by: Andreas Larsson <andreas@gaisler.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/kernel/leon_kernel.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 87f60ee65433..7c0231dabe44 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -213,6 +213,7 @@ unsigned int leon_build_device_irq(unsigned int real_irq,
213{ 213{
214 unsigned int irq; 214 unsigned int irq;
215 unsigned long mask; 215 unsigned long mask;
216 struct irq_desc *desc;
216 217
217 irq = 0; 218 irq = 0;
218 mask = leon_get_irqmask(real_irq); 219 mask = leon_get_irqmask(real_irq);
@@ -226,9 +227,12 @@ unsigned int leon_build_device_irq(unsigned int real_irq,
226 if (do_ack) 227 if (do_ack)
227 mask |= LEON_DO_ACK_HW; 228 mask |= LEON_DO_ACK_HW;
228 229
229 irq_set_chip_and_handler_name(irq, &leon_irq, 230 desc = irq_to_desc(irq);
230 flow_handler, name); 231 if (!desc || !desc->handle_irq || desc->handle_irq == handle_bad_irq) {
231 irq_set_chip_data(irq, (void *)mask); 232 irq_set_chip_and_handler_name(irq, &leon_irq,
233 flow_handler, name);
234 irq_set_chip_data(irq, (void *)mask);
235 }
232 236
233out: 237out:
234 return irq; 238 return irq;