1 /* 2 * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com) 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 */ 8 9 #ifndef __ASM_IRQFLAGS_ARCV2_H 10 #define __ASM_IRQFLAGS_ARCV2_H 11 12 #include <asm/arcregs.h> 13 14 /* status32 Bits */ 15 #define STATUS_AD_BIT 19 /* Disable Align chk: core supports non-aligned */ 16 #define STATUS_IE_BIT 31 17 18 #define STATUS_AD_MASK (1<<STATUS_AD_BIT) 19 #define STATUS_IE_MASK (1<<STATUS_IE_BIT) 20 21 #define AUX_USER_SP 0x00D 22 #define AUX_IRQ_CTRL 0x00E 23 #define AUX_IRQ_ACT 0x043 /* Active Intr across all levels */ 24 #define AUX_IRQ_LVL_PEND 0x200 /* Pending Intr across all levels */ 25 #define AUX_IRQ_HINT 0x201 /* For generating Soft Interrupts */ 26 #define AUX_IRQ_PRIORITY 0x206 27 #define ICAUSE 0x40a 28 #define AUX_IRQ_SELECT 0x40b 29 #define AUX_IRQ_ENABLE 0x40c 30 31 /* Was Intr taken in User Mode */ 32 #define AUX_IRQ_ACT_BIT_U 31 33 34 /* 0 is highest level, but taken by FIRQs, if present in design */ 35 #define ARCV2_IRQ_DEF_PRIO 0 36 37 /* seed value for status register */ 38 #define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | STATUS_AD_MASK | \ 39 (ARCV2_IRQ_DEF_PRIO << 1)) 40 41 /* SLEEP needs default irq priority (<=) which can interrupt the doze */ 42 #define ISA_SLEEP_ARG (0x10 | ARCV2_IRQ_DEF_PRIO) 43 44 #ifndef __ASSEMBLY__ 45 46 /* 47 * Save IRQ state and disable IRQs 48 */ arch_local_irq_save(void)49static inline long arch_local_irq_save(void) 50 { 51 unsigned long flags; 52 53 __asm__ __volatile__(" clri %0 \n" : "=r" (flags) : : "memory"); 54 55 return flags; 56 } 57 58 /* 59 * restore saved IRQ state 60 */ arch_local_irq_restore(unsigned long flags)61static inline void arch_local_irq_restore(unsigned long flags) 62 { 63 __asm__ __volatile__(" seti %0 \n" : : "r" (flags) : "memory"); 64 } 65 66 /* 67 * Unconditionally Enable IRQs 68 */ arch_local_irq_enable(void)69static inline void arch_local_irq_enable(void) 70 { 71 unsigned int irqact = read_aux_reg(AUX_IRQ_ACT); 72 73 if (irqact & 0xffff) 74 write_aux_reg(AUX_IRQ_ACT, irqact & ~0xffff); 75 76 __asm__ __volatile__(" seti \n" : : : "memory"); 77 } 78 79 /* 80 * Unconditionally Disable IRQs 81 */ arch_local_irq_disable(void)82static inline void arch_local_irq_disable(void) 83 { 84 __asm__ __volatile__(" clri \n" : : : "memory"); 85 } 86 87 /* 88 * save IRQ state 89 */ arch_local_save_flags(void)90static inline long arch_local_save_flags(void) 91 { 92 unsigned long temp; 93 94 __asm__ __volatile__( 95 " lr %0, [status32] \n" 96 : "=&r"(temp) 97 : 98 : "memory"); 99 100 return temp; 101 } 102 103 /* 104 * Query IRQ state 105 */ arch_irqs_disabled_flags(unsigned long flags)106static inline int arch_irqs_disabled_flags(unsigned long flags) 107 { 108 return !(flags & (STATUS_IE_MASK)); 109 } 110 arch_irqs_disabled(void)111static inline int arch_irqs_disabled(void) 112 { 113 return arch_irqs_disabled_flags(arch_local_save_flags()); 114 } 115 arc_softirq_trigger(int irq)116static inline void arc_softirq_trigger(int irq) 117 { 118 write_aux_reg(AUX_IRQ_HINT, irq); 119 } 120 arc_softirq_clear(int irq)121static inline void arc_softirq_clear(int irq) 122 { 123 write_aux_reg(AUX_IRQ_HINT, 0); 124 } 125 126 #else 127 128 .macro IRQ_DISABLE scratch 129 clri 130 .endm 131 132 .macro IRQ_ENABLE scratch 133 seti 134 .endm 135 136 #endif /* __ASSEMBLY__ */ 137 138 #endif 139