]> git.proxmox.com Git - mirror_ubuntu-kernels.git/blame - arch/cris/include/arch-v32/arch/irq.h
License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[mirror_ubuntu-kernels.git] / arch / cris / include / arch-v32 / arch / irq.h
CommitLineData
b2441318 1/* SPDX-License-Identifier: GPL-2.0 */
51533b61
MS
2#ifndef _ASM_ARCH_IRQ_H
3#define _ASM_ARCH_IRQ_H
4
1e5915b1 5#include <hwregs/intr_vect.h>
51533b61
MS
6
7/* Number of non-cpu interrupts. */
df90c338 8#define NR_IRQS (NBR_INTR_VECT + 256) /* Exceptions + IRQs */
51533b61 9#define FIRST_IRQ 0x31 /* Exception number for first IRQ */
1e5915b1
JN
10#define NR_REAL_IRQS (NBR_INTR_VECT - FIRST_IRQ) /* IRQs */
11#if NR_REAL_IRQS > 32
12#define MACH_IRQS 64
13#else
14#define MACH_IRQS 32
15#endif
51533b61
MS
16
17#ifndef __ASSEMBLY__
18/* Global IRQ vector. */
19typedef void (*irqvectptr)(void);
20
21struct etrax_interrupt_vector {
22 irqvectptr v[256];
23};
24
25extern struct etrax_interrupt_vector *etrax_irv; /* head.S */
26
4150764f
JN
27void crisv32_mask_irq(int irq);
28void crisv32_unmask_irq(int irq);
51533b61
MS
29
30void set_exception_vector(int n, irqvectptr addr);
31
32/* Save registers so that they match pt_regs. */
33#define SAVE_ALL \
34 "subq 12,$sp\n\t" \
35 "move $erp,[$sp]\n\t" \
36 "subq 4,$sp\n\t" \
37 "move $srp,[$sp]\n\t" \
38 "subq 4,$sp\n\t" \
39 "move $ccs,[$sp]\n\t" \
40 "subq 4,$sp\n\t" \
41 "move $spc,[$sp]\n\t" \
42 "subq 4,$sp\n\t" \
43 "move $mof,[$sp]\n\t" \
44 "subq 4,$sp\n\t" \
45 "move $srs,[$sp]\n\t" \
46 "subq 4,$sp\n\t" \
47 "move.d $acr,[$sp]\n\t" \
48 "subq 14*4,$sp\n\t" \
49 "movem $r13,[$sp]\n\t" \
50 "subq 4,$sp\n\t" \
51 "move.d $r10,[$sp]\n"
52
53#define STR2(x) #x
54#define STR(x) STR2(x)
55
56#define IRQ_NAME2(nr) nr##_interrupt(void)
57#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
58
59/*
60 * The reason for setting the S-bit when debugging the kernel is that we want
61 * hardware breakpoints to remain active while we are in an exception handler.
62 * Note that we cannot simply copy S1, since we may come here from user-space,
63 * or any context where the S-bit wasn't set.
64 */
65#ifdef CONFIG_ETRAX_KGDB
66#define KGDB_FIXUP \
67 "move $ccs, $r10\n\t" \
68 "or.d (1<<9), $r10\n\t" \
69 "move $r10, $ccs\n\t"
70#else
71#define KGDB_FIXUP ""
72#endif
73
74/*
75 * Make sure the causing IRQ is blocked, then call do_IRQ. After that, unblock
76 * and jump to ret_from_intr which is found in entry.S.
77 *
78 * The reason for blocking the IRQ is to allow an sti() before the handler,
79 * which will acknowledge the interrupt, is run. The actual blocking is made
80 * by crisv32_do_IRQ.
81 */
1e5915b1 82#define BUILD_IRQ(nr) \
51533b61
MS
83void IRQ_NAME(nr); \
84__asm__ ( \
85 ".text\n\t" \
86 "IRQ" #nr "_interrupt:\n\t" \
87 SAVE_ALL \
88 KGDB_FIXUP \
89 "move.d "#nr",$r10\n\t" \
1e5915b1 90 "move.d $sp, $r12\n\t" \
51533b61
MS
91 "jsr crisv32_do_IRQ\n\t" \
92 "moveq 1, $r11\n\t" \
93 "jump ret_from_intr\n\t" \
94 "nop\n\t");
95/*
96 * This is subtle. The timer interrupt is crucial and it should not be disabled
97 * for too long. However, if it had been a normal interrupt as per BUILD_IRQ, it
98 * would have been BLOCK'ed, and then softirq's are run before we return here to
99 * UNBLOCK. If the softirq's take too much time to run, the timer irq won't run
100 * and the watchdog will kill us.
101 *
102 * Furthermore, if a lot of other irq's occur before we return here, the
103 * multiple_irq handler is run and it prioritizes the timer interrupt. However
104 * if we had BLOCK'edit here, we would not get the multiple_irq at all.
105 *
64d8ad93
MO
106 * The non-blocking here is based on the knowledge that the timer interrupt runs
107 * with interrupts disabled, and therefore there will not be an sti() before the
108 * timer irq handler is run to acknowledge the interrupt.
51533b61
MS
109 */
110#define BUILD_TIMER_IRQ(nr, mask) \
111void IRQ_NAME(nr); \
112__asm__ ( \
113 ".text\n\t" \
114 "IRQ" #nr "_interrupt:\n\t" \
115 SAVE_ALL \
116 KGDB_FIXUP \
117 "move.d "#nr",$r10\n\t" \
118 "move.d $sp,$r12\n\t" \
119 "jsr crisv32_do_IRQ\n\t" \
120 "moveq 0,$r11\n\t" \
121 "jump ret_from_intr\n\t" \
122 "nop\n\t");
123
124#endif /* __ASSEMBLY__ */
125#endif /* _ASM_ARCH_IRQ_H */