NAND: chip->state does not always get set.
[platform/kernel/u-boot.git] / lib_sparc / 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  * See file CREDITS for list of people who contributed to this
12  * project.
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License as
16  * published by the Free Software Foundation; either version 2 of
17  * the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27  * MA 02111-1307 USA
28  */
29
30 #include <common.h>
31 #include <asm/processor.h>
32 #include <asm/irq.h>
33
34 /* Implemented by SPARC CPUs */
35 extern int interrupt_init_cpu(void);
36 extern void timer_interrupt_cpu(void *arg);
37 extern int timer_interrupt_init_cpu(void);
38
39 int intLock(void)
40 {
41         unsigned int pil;
42
43         pil = get_pil();
44
45         /* set PIL to 15 ==> no pending interrupts will interrupt CPU */
46         set_pil(15);
47
48         return pil;
49 }
50
51 void intUnlock(int oldLevel)
52 {
53         set_pil(oldLevel);
54 }
55
56 void enable_interrupts(void)
57 {
58         set_pil(0);             /* enable all interrupts */
59 }
60
61 int disable_interrupts(void)
62 {
63         return intLock();
64 }
65
66 int interrupt_init(void)
67 {
68         int ret;
69
70         /* call cpu specific function from $(CPU)/interrupts.c */
71         ret = interrupt_init_cpu();
72
73         /* enable global interrupts */
74         enable_interrupts();
75
76         return ret;
77 }
78
79 /* timer interrupt/overflow counter */
80 static volatile ulong timestamp = 0;
81
82 /* regs can not be used here! regs is actually the pointer given in
83  * irq_install_handler
84  */
85 void timer_interrupt(struct pt_regs *regs)
86 {
87         /* call cpu specific function from $(CPU)/interrupts.c */
88         timer_interrupt_cpu((void *)regs);
89
90         timestamp++;
91 }
92
93 void reset_timer(void)
94 {
95         timestamp = 0;
96 }
97
98 ulong get_timer(ulong base)
99 {
100         return (timestamp - base);
101 }
102
103 void set_timer(ulong t)
104 {
105         timestamp = t;
106 }
107
108 void timer_interrupt_init(void)
109 {
110         int irq;
111
112         reset_timer();
113
114         irq = timer_interrupt_init_cpu();
115
116         if (irq < 0) {
117                 /* cpu specific code handled the interrupt registration it self */
118                 return;
119         }
120         /* register interrupt handler for timer */
121         irq_install_handler(irq, (void (*)(void *))timer_interrupt, NULL);
122 }