dts: imx6ul: Update alias to support DM
[oweals/u-boot.git] / arch / nios2 / cpu / interrupts.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2000-2002
4  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5  *
6  * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
7  * Scott McNutt <smcnutt@psyent.com>
8  */
9
10 #include <common.h>
11 #include <command.h>
12 #include <asm/nios2.h>
13 #include <asm/types.h>
14 #include <asm/io.h>
15 #include <asm/ptrace.h>
16
17 /*************************************************************************/
18 struct  irq_action {
19         interrupt_handler_t *handler;
20         void *arg;
21         int count;
22 };
23
24 static struct irq_action vecs[32];
25
26 int disable_interrupts (void)
27 {
28         int val = rdctl (CTL_STATUS);
29         wrctl (CTL_STATUS, val & ~STATUS_IE);
30         return (val & STATUS_IE);
31 }
32
33 void enable_interrupts( void )
34 {
35         int val = rdctl (CTL_STATUS);
36         wrctl (CTL_STATUS, val | STATUS_IE);
37 }
38
39 void external_interrupt (struct pt_regs *regs)
40 {
41         unsigned irqs;
42         struct irq_action *act;
43
44         /* Evaluate only irqs that are both enabled AND pending */
45         irqs = rdctl (CTL_IENABLE) & rdctl (CTL_IPENDING);
46         act = vecs;
47
48         /* Assume (as does the Nios2 HAL) that bit 0 is highest
49          * priority. NOTE: There is ALWAYS a handler assigned
50          * (the default if no other).
51          */
52         while (irqs) {
53                 if (irqs & 1) {
54                         act->handler (act->arg);
55                         act->count++;
56                 }
57                 irqs >>=1;
58                 act++;
59         }
60 }
61
62 static void def_hdlr (void *arg)
63 {
64         unsigned irqs = rdctl (CTL_IENABLE);
65
66         /* Disable the individual interrupt -- with gratuitous
67          * warning.
68          */
69         irqs &= ~(1 << (int)arg);
70         wrctl (CTL_IENABLE, irqs);
71         printf ("WARNING: Disabling unhandled interrupt: %d\n",
72                         (int)arg);
73 }
74
75 /*************************************************************************/
76 void irq_install_handler (int irq, interrupt_handler_t *hdlr, void *arg)
77 {
78
79         int flag;
80         struct irq_action *act;
81         unsigned ena = rdctl (CTL_IENABLE);
82
83         if ((irq < 0) || (irq > 31))
84                 return;
85         act = &vecs[irq];
86
87         flag = disable_interrupts ();
88         if (hdlr) {
89                 act->handler = hdlr;
90                 act->arg = arg;
91                 ena |= (1 << irq);              /* enable */
92         } else {
93                 act->handler = def_hdlr;
94                 act->arg = (void *)irq;
95                 ena &= ~(1 << irq);             /* disable */
96         }
97         wrctl (CTL_IENABLE, ena);
98         if (flag) enable_interrupts ();
99 }
100
101
102 int interrupt_init (void)
103 {
104         int i;
105
106         /* Assign the default handler to all */
107         for (i = 0; i < 32; i++) {
108                 vecs[i].handler = def_hdlr;
109                 vecs[i].arg = (void *)i;
110                 vecs[i].count = 0;
111         }
112
113         enable_interrupts ();
114         return (0);
115 }
116
117
118 /*************************************************************************/
119 #if defined(CONFIG_CMD_IRQ)
120 int do_irqinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
121 {
122         int i;
123         struct irq_action *act = vecs;
124
125         printf ("\nInterrupt-Information:\n\n");
126         printf ("Nr  Routine   Arg       Count\n");
127         printf ("-----------------------------\n");
128
129         for (i=0; i<32; i++) {
130                 if (act->handler != def_hdlr) {
131                         printf ("%02d  %08lx  %08lx  %d\n",
132                                 i,
133                                 (ulong)act->handler,
134                                 (ulong)act->arg,
135                                 act->count);
136                 }
137                 act++;
138         }
139         printf ("\n");
140
141         return (0);
142 }
143 #endif