]>
Commit | Line | Data |
---|---|---|
8c63d476 | 1 | /* |
dbf7115a GR |
2 | * (C) Copyright 2008,2009 |
3 | * Graeme Russ, <graeme.russ@gmail.com> | |
4 | * | |
8c63d476 | 5 | * (C) Copyright 2002 |
fa82f871 | 6 | * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> |
8c63d476 GR |
7 | * |
8 | * See file CREDITS for list of people who contributed to this | |
9 | * project. | |
10 | * | |
11 | * This program is free software; you can redistribute it and/or | |
12 | * modify it under the terms of the GNU General Public License as | |
13 | * published by the Free Software Foundation; either version 2 of | |
14 | * the License, or (at your option) any later version. | |
15 | * | |
16 | * This program is distributed in the hope that it will be useful, | |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | * GNU General Public License for more details. | |
20 | * | |
21 | * You should have received a copy of the GNU General Public License | |
22 | * along with this program; if not, write to the Free Software | |
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
24 | * MA 02111-1307 USA | |
25 | */ | |
26 | ||
27 | #include <common.h> | |
28 | #include <malloc.h> | |
29 | #include <asm/io.h> | |
30 | #include <asm/i8254.h> | |
31 | #include <asm/ibmpc.h> | |
32 | ||
33 | struct timer_isr_function { | |
34 | struct timer_isr_function *next; | |
35 | timer_fnc_t *isr_func; | |
36 | }; | |
37 | ||
38 | static struct timer_isr_function *first_timer_isr = NULL; | |
39 | static volatile unsigned long system_ticks = 0; | |
40 | ||
41 | /* | |
42 | * register_timer_isr() allows multiple architecture and board specific | |
43 | * functions to be called every millisecond. Keep the execution time of | |
44 | * each function as low as possible | |
45 | */ | |
46 | int register_timer_isr (timer_fnc_t *isr_func) | |
47 | { | |
48 | struct timer_isr_function *new_func; | |
49 | struct timer_isr_function *temp; | |
50 | int flag; | |
51 | ||
52 | new_func = malloc(sizeof(struct timer_isr_function)); | |
53 | ||
54 | if (new_func == NULL) | |
55 | return 1; | |
56 | ||
1c409bc7 | 57 | new_func->isr_func = isr_func; |
8c63d476 GR |
58 | new_func->next = NULL; |
59 | ||
60 | /* | |
61 | * Don't allow timer interrupts while the | |
62 | * linked list is being modified | |
63 | */ | |
64 | flag = disable_interrupts (); | |
65 | ||
66 | if (first_timer_isr == NULL) { | |
67 | first_timer_isr = new_func; | |
68 | } else { | |
69 | temp = first_timer_isr; | |
70 | while (temp->next != NULL) | |
71 | temp = temp->next; | |
72 | temp->next = new_func; | |
73 | } | |
74 | ||
75 | if (flag) | |
76 | enable_interrupts (); | |
77 | ||
78 | return 0; | |
79 | } | |
80 | ||
81 | /* | |
82 | * timer_isr() MUST be the registered interrupt handler for | |
83 | */ | |
84 | void timer_isr(void *unused) | |
85 | { | |
86 | struct timer_isr_function *temp = first_timer_isr; | |
87 | ||
88 | system_ticks++; | |
89 | ||
90 | /* Execute each registered function */ | |
91 | while (temp != NULL) { | |
92 | temp->isr_func (); | |
93 | temp = temp->next; | |
94 | } | |
95 | } | |
96 | ||
8c63d476 GR |
97 | ulong get_timer (ulong base) |
98 | { | |
99 | return (system_ticks - base); | |
100 | } |