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 /* 35 * User space should be interruptable even by lowest prio interrupt 36 * Safe even if actual interrupt priorities is fewer or even one 37 */ 38 #define ARCV2_IRQ_DEF_PRIO 15 39 40 /* seed value for status register */ 41 #define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | STATUS_AD_MASK | \ 42 (ARCV2_IRQ_DEF_PRIO << 1)) 43 44 /* SLEEP needs default irq priority (<=) which can interrupt the doze */ 45 #define ISA_SLEEP_ARG (0x10 | ARCV2_IRQ_DEF_PRIO) 46 47 #ifndef __ASSEMBLY__ 48 49 /* 50 * Save IRQ state and disable IRQs 51 */ 52 static inline long arch_local_irq_save(void) 53 { 54 unsigned long flags; 55 56 __asm__ __volatile__(" clri %0 \n" : "=r" (flags) : : "memory"); 57 58 return flags; 59 } 60 61 /* 62 * restore saved IRQ state 63 */ 64 static inline void arch_local_irq_restore(unsigned long flags) 65 { 66 __asm__ __volatile__(" seti %0 \n" : : "r" (flags) : "memory"); 67 } 68 69 /* 70 * Unconditionally Enable IRQs 71 */ 72 static inline void arch_local_irq_enable(void) 73 { 74 unsigned int irqact = read_aux_reg(AUX_IRQ_ACT); 75 76 if (irqact & 0xffff) 77 write_aux_reg(AUX_IRQ_ACT, irqact & ~0xffff); 78 79 __asm__ __volatile__(" seti \n" : : : "memory"); 80 } 81 82 /* 83 * Unconditionally Disable IRQs 84 */ 85 static inline void arch_local_irq_disable(void) 86 { 87 __asm__ __volatile__(" clri \n" : : : "memory"); 88 } 89 90 /* 91 * save IRQ state 92 */ 93 static inline long arch_local_save_flags(void) 94 { 95 unsigned long temp; 96 97 __asm__ __volatile__( 98 " lr %0, [status32] \n" 99 : "=&r"(temp) 100 : 101 : "memory"); 102 103 return temp; 104 } 105 106 /* 107 * Query IRQ state 108 */ 109 static inline int arch_irqs_disabled_flags(unsigned long flags) 110 { 111 return !(flags & (STATUS_IE_MASK)); 112 } 113 114 static inline int arch_irqs_disabled(void) 115 { 116 return arch_irqs_disabled_flags(arch_local_save_flags()); 117 } 118 119 static inline void arc_softirq_trigger(int irq) 120 { 121 write_aux_reg(AUX_IRQ_HINT, irq); 122 } 123 124 static inline void arc_softirq_clear(int irq) 125 { 126 write_aux_reg(AUX_IRQ_HINT, 0); 127 } 128 129 #else 130 131 .macro IRQ_DISABLE scratch 132 clri 133 .endm 134 135 .macro IRQ_ENABLE scratch 136 seti 137 .endm 138 139 #endif /* __ASSEMBLY__ */ 140 141 #endif 142