diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-01-18 15:12:16 +0530 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-02-11 20:00:30 +0530 |
commit | ac4c244d4e5d914f9a5642cdcc03b18780e55dbc (patch) | |
tree | fbc0a3da0a135dac46883eba654c862119060c3e /arch/arc/kernel/irq.c | |
parent | cfdbc2e16e65c1ec1c23057640607cee98d1a1bd (diff) |
ARC: irqflags - Interrupt enabling/disabling at in-core intc
ARC700 has an in-core intc which provides 2 priorities (a.k.a.) "levels"
of interrupts (per IRQ) hencforth referred to as L1/L2 interrupts.
CPU flags register STATUS32 has Interrupt Enable bits per level (E1/E2)
to globally enable (or disable) all IRQs at a level. Hence the
implementation of arch_local_irq_{save,restore,enable,disable}( )
The STATUS32 reg can be r/w only using the AUX Interface of ARC, hence
the use of LR/SR instructions. Further, E1/E2 bits in there can only be
updated using the FLAG insn.
The intc supports 32 interrupts - and per IRQ enabling is controlled by
a bit in the AUX_IENABLE register, hence the implmentation of
arch_{,un}mask_irq( ) routines.
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/arc/kernel/irq.c')
-rw-r--r-- | arch/arc/kernel/irq.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c new file mode 100644 index 000000000000..c4e9b25d305f --- /dev/null +++ b/arch/arc/kernel/irq.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011-12 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/interrupt.h> +#include <linux/module.h> +#include <asm/irqflags.h> +#include <asm/arcregs.h> + +void arch_local_irq_enable(void) +{ + unsigned long flags; + + /* + * ARC IDE Drivers tries to re-enable interrupts from hard-isr + * context which is simply wrong + */ + if (in_irq()) { + WARN_ONCE(1, "IRQ enabled from hard-isr"); + return; + } + + flags = arch_local_save_flags(); + flags |= (STATUS_E1_MASK | STATUS_E2_MASK); + arch_local_irq_restore(flags); +} +EXPORT_SYMBOL(arch_local_irq_enable); |