]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
8e585f02 TL |
2 | /* |
3 | * (C) Copyright 2000-2004 | |
4 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
5 | * | |
45a25bfd | 6 | * (C) Copyright 2007 Freescale Semiconductor Inc |
8e585f02 | 7 | * TsiChung Liew (Tsi-Chung.Liew@freescale.com) |
8e585f02 TL |
8 | */ |
9 | ||
10 | #include <common.h> | |
11 | #include <watchdog.h> | |
12 | #include <asm/processor.h> | |
45a25bfd | 13 | #include <asm/immap.h> |
8e585f02 | 14 | |
6d0f6bcf | 15 | #define NR_IRQS (CONFIG_SYS_NUM_IRQS) |
8e585f02 TL |
16 | |
17 | /* | |
18 | * Interrupt vector functions. | |
19 | */ | |
20 | struct interrupt_action { | |
21 | interrupt_handler_t *handler; | |
22 | void *arg; | |
23 | }; | |
24 | ||
25 | static struct interrupt_action irq_vecs[NR_IRQS]; | |
26 | ||
27 | static __inline__ unsigned short get_sr (void) | |
28 | { | |
29 | unsigned short sr; | |
30 | ||
31 | asm volatile ("move.w %%sr,%0":"=r" (sr):); | |
32 | ||
33 | return sr; | |
34 | } | |
35 | ||
36 | static __inline__ void set_sr (unsigned short sr) | |
37 | { | |
38 | asm volatile ("move.w %0,%%sr"::"r" (sr)); | |
39 | } | |
40 | ||
41 | /************************************************************************/ | |
42 | /* | |
43 | * Install and free an interrupt handler | |
44 | */ | |
45 | void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg) | |
46 | { | |
626d0734 | 47 | if ((vec < 0) || (vec >= NR_IRQS)) { |
8e585f02 TL |
48 | printf ("irq_install_handler: wrong interrupt vector %d\n", |
49 | vec); | |
50 | return; | |
51 | } | |
52 | ||
53 | irq_vecs[vec].handler = handler; | |
54 | irq_vecs[vec].arg = arg; | |
55 | } | |
56 | ||
57 | void irq_free_handler (int vec) | |
58 | { | |
626d0734 | 59 | if ((vec < 0) || (vec >= NR_IRQS)) { |
8e585f02 TL |
60 | return; |
61 | } | |
62 | ||
63 | irq_vecs[vec].handler = NULL; | |
64 | irq_vecs[vec].arg = NULL; | |
65 | } | |
66 | ||
67 | void enable_interrupts (void) | |
68 | { | |
69 | unsigned short sr; | |
70 | ||
71 | sr = get_sr (); | |
72 | set_sr (sr & ~0x0700); | |
73 | } | |
74 | ||
75 | int disable_interrupts (void) | |
76 | { | |
77 | unsigned short sr; | |
78 | ||
79 | sr = get_sr (); | |
80 | set_sr (sr | 0x0700); | |
81 | ||
472d5460 | 82 | return ((sr & 0x0700) == 0); /* return true, if interrupts were enabled before */ |
8e585f02 TL |
83 | } |
84 | ||
85 | void int_handler (struct pt_regs *fp) | |
86 | { | |
87 | int vec; | |
88 | ||
89 | vec = (fp->vector >> 2) & 0xff; | |
90 | if (vec > 0x40) | |
91 | vec -= 0x40; | |
8e585f02 TL |
92 | |
93 | if (irq_vecs[vec].handler != NULL) { | |
94 | irq_vecs[vec].handler (irq_vecs[vec].arg); | |
95 | } else { | |
96 | printf ("\nBogus External Interrupt Vector %d\n", vec); | |
97 | } | |
98 | } |