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