blob: 4c73b82a6fd4754c0bb4978c2956f057488c8b15 [file] [log] [blame]
Daniel Hellstrom9d7c6b22008-03-28 09:47:00 +01001/*
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 */
35extern int interrupt_init_cpu(void);
36extern void timer_interrupt_cpu(void *arg);
37extern int timer_interrupt_init_cpu(void);
38
39int 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
51void intUnlock(int oldLevel)
52{
53 set_pil(oldLevel);
54}
55
56void enable_interrupts(void)
57{
58 set_pil(0); /* enable all interrupts */
59}
60
61int disable_interrupts(void)
62{
63 return intLock();
64}
65
66int 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 */
80static volatile ulong timestamp = 0;
81
82/* regs can not be used here! regs is actually the pointer given in
83 * irq_install_handler
84 */
85void 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
93void reset_timer(void)
94{
95 timestamp = 0;
96}
97
98ulong get_timer(ulong base)
99{
100 return (timestamp - base);
101}
102
103void set_timer(ulong t)
104{
105 timestamp = t;
106}
107
108void 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}