xref: /OK3568_Linux_fs/kernel/arch/arc/include/asm/irqflags-arcv2.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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*4882a593Smuzhiyun static 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*4882a593Smuzhiyun static 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*4882a593Smuzhiyun static 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*4882a593Smuzhiyun static 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*4882a593Smuzhiyun static 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*4882a593Smuzhiyun static 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*4882a593Smuzhiyun static 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*4882a593Smuzhiyun static 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*4882a593Smuzhiyun static 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