fab26c62dd6d12959917077ca9298498e2b13c18
[oweals/u-boot.git] / arch / sparc / lib / interrupts.c
1 /*
2  * (C) Copyright 2000-2002
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * (C) Copyright 2003
6  * Gleb Natapov <gnatapov@mrv.com>
7  *
8  * (C) Copyright 2007
9  * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
10  *
11  * SPDX-License-Identifier:     GPL-2.0+
12  */
13
14 #include <common.h>
15 #include <asm/processor.h>
16 #include <asm/irq.h>
17
18 /* Implemented by SPARC CPUs */
19 extern int interrupt_init_cpu(void);
20 extern void timer_interrupt_cpu(void *arg);
21 extern int timer_interrupt_init_cpu(void);
22
23 int intLock(void)
24 {
25         unsigned int pil;
26
27         pil = get_pil();
28
29         /* set PIL to 15 ==> no pending interrupts will interrupt CPU */
30         set_pil(15);
31
32         return pil;
33 }
34
35 void intUnlock(int oldLevel)
36 {
37         set_pil(oldLevel);
38 }
39
40 void enable_interrupts(void)
41 {
42         set_pil(0);             /* enable all interrupts */
43 }
44
45 int disable_interrupts(void)
46 {
47         return intLock();
48 }
49
50 int interrupt_is_enabled(void)
51 {
52         if (get_pil() == 15)
53                 return 0;
54         return 1;
55 }
56
57 int interrupt_init(void)
58 {
59         int ret;
60
61         /* call cpu specific function from $(CPU)/interrupts.c */
62         ret = interrupt_init_cpu();
63
64         /* enable global interrupts */
65         enable_interrupts();
66
67         return ret;
68 }
69
70 /* timer interrupt/overflow counter */
71 static volatile ulong timestamp = 0;
72
73 /* regs can not be used here! regs is actually the pointer given in
74  * irq_install_handler
75  */
76 void timer_interrupt(struct pt_regs *regs)
77 {
78         /* call cpu specific function from $(CPU)/interrupts.c */
79         timer_interrupt_cpu((void *)regs);
80
81         timestamp++;
82 }
83
84 void timer_interrupt_init(void)
85 {
86         int irq;
87
88         timestamp = 0;
89
90         irq = timer_interrupt_init_cpu();
91
92         if (irq < 0) {
93                 /* cpu specific code handled the interrupt registration it self */
94                 return;
95         }
96         /* register interrupt handler for timer */
97         irq_install_handler(irq, (void (*)(void *))timer_interrupt, NULL);
98 }