summaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/leon_kernel.c
diff options
context:
space:
mode:
authorAndreas Larsson <andreas@gaisler.com>2013-04-21 23:23:06 +0200
committerDavid S. Miller <davem@davemloft.net>2013-05-05 02:38:18 +0200
commit6e4741e73b266f02e4b6d166ac278afd86c4dceb (patch)
tree847c53a68bc766158812f782fc538de04e67b4eb /arch/sparc/kernel/leon_kernel.c
parentsparc/kernel/vio.c: add put_device() after device_find_child() (diff)
downloadlinux-6e4741e73b266f02e4b6d166ac278afd86c4dceb.tar.xz
linux-6e4741e73b266f02e4b6d166ac278afd86c4dceb.zip
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/kernel/leon_kernel.c')
-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,
{
unsigned int irq;
unsigned long mask;
+ struct irq_desc *desc;
irq = 0;
mask = leon_get_irqmask(real_irq);
@@ -226,9 +227,12 @@ unsigned int leon_build_device_irq(unsigned int real_irq,
if (do_ack)
mask |= LEON_DO_ACK_HW;
- irq_set_chip_and_handler_name(irq, &leon_irq,
- flow_handler, name);
- irq_set_chip_data(irq, (void *)mask);
+ desc = irq_to_desc(irq);
+ if (!desc || !desc->handle_irq || desc->handle_irq == handle_bad_irq) {
+ irq_set_chip_and_handler_name(irq, &leon_irq,
+ flow_handler, name);
+ irq_set_chip_data(irq, (void *)mask);
+ }
out:
return irq;