1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com) 4*4882a593Smuzhiyun */ 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun #ifndef __ASM_IRQFLAGS_ARCV2_H 7*4882a593Smuzhiyun #define __ASM_IRQFLAGS_ARCV2_H 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #include <asm/arcregs.h> 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun /* status32 Bits */ 12*4882a593Smuzhiyun #define STATUS_AD_BIT 19 /* Disable Align chk: core supports non-aligned */ 13*4882a593Smuzhiyun #define STATUS_IE_BIT 31 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun #define STATUS_AD_MASK (1<<STATUS_AD_BIT) 16*4882a593Smuzhiyun #define STATUS_IE_MASK (1<<STATUS_IE_BIT) 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun /* status32 Bits as encoded/expected by CLRI/SETI */ 19*4882a593Smuzhiyun #define CLRI_STATUS_IE_BIT 4 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun #define CLRI_STATUS_E_MASK 0xF 22*4882a593Smuzhiyun #define CLRI_STATUS_IE_MASK (1 << CLRI_STATUS_IE_BIT) 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun #define AUX_USER_SP 0x00D 25*4882a593Smuzhiyun #define AUX_IRQ_CTRL 0x00E 26*4882a593Smuzhiyun #define AUX_IRQ_ACT 0x043 /* Active Intr across all levels */ 27*4882a593Smuzhiyun #define AUX_IRQ_LVL_PEND 0x200 /* Pending Intr across all levels */ 28*4882a593Smuzhiyun #define AUX_IRQ_HINT 0x201 /* For generating Soft Interrupts */ 29*4882a593Smuzhiyun #define AUX_IRQ_PRIORITY 0x206 30*4882a593Smuzhiyun #define ICAUSE 0x40a 31*4882a593Smuzhiyun #define AUX_IRQ_SELECT 0x40b 32*4882a593Smuzhiyun #define AUX_IRQ_ENABLE 0x40c 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun /* Was Intr taken in User Mode */ 35*4882a593Smuzhiyun #define AUX_IRQ_ACT_BIT_U 31 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun /* 38*4882a593Smuzhiyun * Hardware supports 16 priorities (0 highest, 15 lowest) 39*4882a593Smuzhiyun * Linux by default runs at 1, priority 0 reserved for NMI style interrupts 40*4882a593Smuzhiyun */ 41*4882a593Smuzhiyun #define ARCV2_IRQ_DEF_PRIO 1 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun /* seed value for status register */ 44*4882a593Smuzhiyun #ifdef CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS 45*4882a593Smuzhiyun #define __AD_ENB STATUS_AD_MASK 46*4882a593Smuzhiyun #else 47*4882a593Smuzhiyun #define __AD_ENB 0 48*4882a593Smuzhiyun #endif 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun #define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | __AD_ENB | \ 51*4882a593Smuzhiyun (ARCV2_IRQ_DEF_PRIO << 1)) 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun #ifndef __ASSEMBLY__ 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun /* 56*4882a593Smuzhiyun * Save IRQ state and disable IRQs 57*4882a593Smuzhiyun */ arch_local_irq_save(void)58*4882a593Smuzhiyunstatic inline long arch_local_irq_save(void) 59*4882a593Smuzhiyun { 60*4882a593Smuzhiyun unsigned long flags; 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun __asm__ __volatile__(" clri %0 \n" : "=r" (flags) : : "memory"); 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun return flags; 65*4882a593Smuzhiyun } 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun /* 68*4882a593Smuzhiyun * restore saved IRQ state 69*4882a593Smuzhiyun */ arch_local_irq_restore(unsigned long flags)70*4882a593Smuzhiyunstatic inline void arch_local_irq_restore(unsigned long flags) 71*4882a593Smuzhiyun { 72*4882a593Smuzhiyun __asm__ __volatile__(" seti %0 \n" : : "r" (flags) : "memory"); 73*4882a593Smuzhiyun } 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun /* 76*4882a593Smuzhiyun * Unconditionally Enable IRQs 77*4882a593Smuzhiyun */ arch_local_irq_enable(void)78*4882a593Smuzhiyunstatic inline void arch_local_irq_enable(void) 79*4882a593Smuzhiyun { 80*4882a593Smuzhiyun unsigned int irqact = read_aux_reg(AUX_IRQ_ACT); 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun if (irqact & 0xffff) 83*4882a593Smuzhiyun write_aux_reg(AUX_IRQ_ACT, irqact & ~0xffff); 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun __asm__ __volatile__(" seti \n" : : : "memory"); 86*4882a593Smuzhiyun } 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun /* 89*4882a593Smuzhiyun * Unconditionally Disable IRQs 90*4882a593Smuzhiyun */ arch_local_irq_disable(void)91*4882a593Smuzhiyunstatic inline void arch_local_irq_disable(void) 92*4882a593Smuzhiyun { 93*4882a593Smuzhiyun __asm__ __volatile__(" clri \n" : : : "memory"); 94*4882a593Smuzhiyun } 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun /* 97*4882a593Smuzhiyun * save IRQ state 98*4882a593Smuzhiyun */ arch_local_save_flags(void)99*4882a593Smuzhiyunstatic inline long arch_local_save_flags(void) 100*4882a593Smuzhiyun { 101*4882a593Smuzhiyun unsigned long temp; 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun __asm__ __volatile__( 104*4882a593Smuzhiyun " lr %0, [status32] \n" 105*4882a593Smuzhiyun : "=&r"(temp) 106*4882a593Smuzhiyun : 107*4882a593Smuzhiyun : "memory"); 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun /* To be compatible with irq_save()/irq_restore() 110*4882a593Smuzhiyun * encode the irq bits as expected by CLRI/SETI 111*4882a593Smuzhiyun * (this was needed to make CONFIG_TRACE_IRQFLAGS work) 112*4882a593Smuzhiyun */ 113*4882a593Smuzhiyun temp = (1 << 5) | 114*4882a593Smuzhiyun ((!!(temp & STATUS_IE_MASK)) << CLRI_STATUS_IE_BIT) | 115*4882a593Smuzhiyun ((temp >> 1) & CLRI_STATUS_E_MASK); 116*4882a593Smuzhiyun return temp; 117*4882a593Smuzhiyun } 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun /* 120*4882a593Smuzhiyun * Query IRQ state 121*4882a593Smuzhiyun */ arch_irqs_disabled_flags(unsigned long flags)122*4882a593Smuzhiyunstatic inline int arch_irqs_disabled_flags(unsigned long flags) 123*4882a593Smuzhiyun { 124*4882a593Smuzhiyun return !(flags & CLRI_STATUS_IE_MASK); 125*4882a593Smuzhiyun } 126*4882a593Smuzhiyun arch_irqs_disabled(void)127*4882a593Smuzhiyunstatic inline int arch_irqs_disabled(void) 128*4882a593Smuzhiyun { 129*4882a593Smuzhiyun return arch_irqs_disabled_flags(arch_local_save_flags()); 130*4882a593Smuzhiyun } 131*4882a593Smuzhiyun arc_softirq_trigger(int irq)132*4882a593Smuzhiyunstatic inline void arc_softirq_trigger(int irq) 133*4882a593Smuzhiyun { 134*4882a593Smuzhiyun write_aux_reg(AUX_IRQ_HINT, irq); 135*4882a593Smuzhiyun } 136*4882a593Smuzhiyun arc_softirq_clear(int irq)137*4882a593Smuzhiyunstatic inline void arc_softirq_clear(int irq) 138*4882a593Smuzhiyun { 139*4882a593Smuzhiyun write_aux_reg(AUX_IRQ_HINT, 0); 140*4882a593Smuzhiyun } 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun #else 143*4882a593Smuzhiyun 144*4882a593Smuzhiyun #ifdef CONFIG_TRACE_IRQFLAGS 145*4882a593Smuzhiyun 146*4882a593Smuzhiyun .macro TRACE_ASM_IRQ_DISABLE 147*4882a593Smuzhiyun bl trace_hardirqs_off 148*4882a593Smuzhiyun .endm 149*4882a593Smuzhiyun 150*4882a593Smuzhiyun .macro TRACE_ASM_IRQ_ENABLE 151*4882a593Smuzhiyun bl trace_hardirqs_on 152*4882a593Smuzhiyun .endm 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun #else 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun .macro TRACE_ASM_IRQ_DISABLE 157*4882a593Smuzhiyun .endm 158*4882a593Smuzhiyun 159*4882a593Smuzhiyun .macro TRACE_ASM_IRQ_ENABLE 160*4882a593Smuzhiyun .endm 161*4882a593Smuzhiyun 162*4882a593Smuzhiyun #endif 163*4882a593Smuzhiyun .macro IRQ_DISABLE scratch 164*4882a593Smuzhiyun clri 165*4882a593Smuzhiyun TRACE_ASM_IRQ_DISABLE 166*4882a593Smuzhiyun .endm 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun .macro IRQ_ENABLE scratch 169*4882a593Smuzhiyun TRACE_ASM_IRQ_ENABLE 170*4882a593Smuzhiyun seti 171*4882a593Smuzhiyun .endm 172*4882a593Smuzhiyun 173*4882a593Smuzhiyun #endif /* __ASSEMBLY__ */ 174*4882a593Smuzhiyun 175*4882a593Smuzhiyun #endif 176