diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2013-12-01 12:04:57 +0400 |
---|---|---|
committer | Chris Zankel <chris@zankel.net> | 2014-01-14 10:19:58 -0800 |
commit | 26a8e96a8b37e8070fa9dcb1b7490cf4d4492d50 (patch) | |
tree | 5104a9c1e12dd3728b05db5b21b5033bd7b648d2 /arch | |
parent | bae07f8a9dfaf6268f2fba5522b70bce6fc7d718 (diff) |
xtensa: add MX irqchip
MX is an interrupt distributor used in some SMP-capable xtensa
configurations.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Chris Zankel <chris@zankel.net>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/xtensa/include/asm/irq.h | 1 | ||||
-rw-r--r-- | arch/xtensa/include/asm/mxregs.h | 46 | ||||
-rw-r--r-- | arch/xtensa/include/asm/processor.h | 20 | ||||
-rw-r--r-- | arch/xtensa/kernel/irq.c | 8 |
4 files changed, 75 insertions, 0 deletions
diff --git a/arch/xtensa/include/asm/irq.h b/arch/xtensa/include/asm/irq.h index 16464f2f8ecc..7d194d462150 100644 --- a/arch/xtensa/include/asm/irq.h +++ b/arch/xtensa/include/asm/irq.h @@ -50,5 +50,6 @@ int xtensa_irq_domain_xlate(const u32 *intspec, unsigned int intsize, unsigned long *out_hwirq, unsigned int *out_type); int xtensa_irq_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw); unsigned xtensa_map_ext_irq(unsigned ext_irq); +unsigned xtensa_get_ext_irq_no(unsigned irq); #endif /* _XTENSA_IRQ_H */ diff --git a/arch/xtensa/include/asm/mxregs.h b/arch/xtensa/include/asm/mxregs.h new file mode 100644 index 000000000000..73dcc5456f68 --- /dev/null +++ b/arch/xtensa/include/asm/mxregs.h @@ -0,0 +1,46 @@ +/* + * Xtensa MX interrupt distributor + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 - 2013 Tensilica Inc. + */ + +#ifndef _XTENSA_MXREGS_H +#define _XTENSA_MXREGS_H + +/* + * RER/WER at, as Read/write external register + * at: value + * as: address + * + * Address Value + * 00nn 0...0p..p Interrupt Routing, route IRQ n to processor p + * 01pp 0...0d..d 16 bits (d) 'ored' as single IPI to processor p + * 0180 0...0m..m Clear enable specified by mask (m) + * 0184 0...0m..m Set enable specified by mask (m) + * 0190 0...0x..x 8-bit IPI partition register + * VVVVVVVVPPPPUUUUUUUUUUUUUUUUU + * V (10-bit) Release/Version + * P ( 4-bit) Number of cores - 1 + * U (18-bit) ID + * 01a0 i.......i 32-bit ConfigID + * 0200 0...0m..m RunStall core 'n' + * 0220 c Cache coherency enabled + */ + +#define MIROUT(irq) (0x000 + (irq)) +#define MIPICAUSE(cpu) (0x100 + (cpu)) +#define MIPISET(cause) (0x140 + (cause)) +#define MIENG 0x180 +#define MIENGSET 0x184 +#define MIASG 0x188 /* Read Global Assert Register */ +#define MIASGSET 0x18c /* Set Global Addert Regiter */ +#define MIPIPART 0x190 +#define SYSCFGID 0x1a0 +#define MPSCORE 0x200 +#define CCON 0x220 + +#endif /* _XTENSA_MXREGS_H */ diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index 7e409a5b0ec5..abb59708a3b7 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h @@ -191,5 +191,25 @@ extern unsigned long get_wchan(struct task_struct *p); #define set_sr(x,sr) ({unsigned int v=(unsigned int)x; WSR(v,sr);}) #define get_sr(sr) ({unsigned int v; RSR(v,sr); v; }) +#ifndef XCHAL_HAVE_EXTERN_REGS +#define XCHAL_HAVE_EXTERN_REGS 0 +#endif + +#if XCHAL_HAVE_EXTERN_REGS + +static inline void set_er(unsigned long value, unsigned long addr) +{ + asm volatile ("wer %0, %1" : : "a" (value), "a" (addr) : "memory"); +} + +static inline unsigned long get_er(unsigned long addr) +{ + register unsigned long value; + asm volatile ("rer %0, %1" : "=a" (value) : "a" (addr) : "memory"); + return value; +} + +#endif /* XCHAL_HAVE_EXTERN_REGS */ + #endif /* __ASSEMBLY__ */ #endif /* _XTENSA_PROCESSOR_H */ diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index 3cef58e28332..7d49730f4056 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c @@ -123,6 +123,14 @@ unsigned xtensa_map_ext_irq(unsigned ext_irq) return XCHAL_NUM_INTERRUPTS; } +unsigned xtensa_get_ext_irq_no(unsigned irq) +{ + unsigned mask = (XCHAL_INTTYPE_MASK_EXTERN_EDGE | + XCHAL_INTTYPE_MASK_EXTERN_LEVEL) & + ((1u << irq) - 1); + return hweight32(mask); +} + void __init init_IRQ(void) { #ifdef CONFIG_OF |