MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / drivers / char / fast_timer.c
blob270955f9c2bc7b2102ecab9809bd2a0f05edc068
1 /*
2 * linux/drivers/char/fast_timer.c
4 * Fast timer code for general use, primarily polling network chips
6 * Copyright (c) 2004 SnapGear Inc. <www.snapgear.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/string.h>
17 #include <linux/fast_timer.h>
18 #ifdef CONFIG_SYSCTL
19 #include <linux/sysctl.h>
20 #endif
22 #include <linux/fast_timer.h>
25 struct ftentry {
26 void (*func)(void *);
27 void *arg;
30 #define FAST_TIMER_MAX 8
31 static struct ftentry fast_timer[FAST_TIMER_MAX];
32 static int fast_timers = 0;
33 static spinlock_t fast_timer_lock;
34 static int fast_timer_rate;
36 void fast_timer_add(void (*func)(void *arg), void *arg)
38 int i;
39 unsigned long flags;
41 spin_lock_irqsave(&fast_timer_lock, flags);
42 for (i = 0; i < fast_timers; i++) {
43 if (fast_timer[i].func == func && fast_timer[i].arg == arg) {
44 spin_unlock_irqrestore(&fast_timer_lock, flags);
45 printk(KERN_ERR
46 "fast_timer: entry already exists (0x%x, 0x%x)\n",
47 (unsigned int) func, (unsigned int) arg);
48 return;
52 if (fast_timers >= FAST_TIMER_MAX) {
53 spin_unlock_irqrestore(&fast_timer_lock, flags);
54 printk(KERN_ERR "fast timer: no free slots\n");
55 return;
58 fast_timer[fast_timers].func = func;
59 fast_timer[fast_timers].arg = arg;
60 fast_timers++;
61 spin_unlock_irqrestore(&fast_timer_lock, flags);
64 void fast_timer_remove(void (*func)(void *arg), void *arg)
66 int i;
67 unsigned long flags;
69 spin_lock_irqsave(&fast_timer_lock, flags);
70 for (i = 0; i < fast_timers; i++) {
71 if (fast_timer[i].func == func && fast_timer[i].arg == arg) {
72 memmove(&fast_timer[i], &fast_timer[i+1],
73 sizeof(struct ftentry) * (FAST_TIMER_MAX - (i+1)));
74 fast_timers--;
75 spin_unlock_irqrestore(&fast_timer_lock, flags);
76 return;
79 spin_unlock_irqrestore(&fast_timer_lock, flags);
80 printk(KERN_ERR "fast timer: entry does not exist (0x%x, 0x%x)\n",
81 (unsigned int) func, (unsigned int) arg);
84 static void do_fast_timer(void)
86 int i;
88 for (i = 0; i < fast_timers; i++)
89 (*fast_timer[i].func)(fast_timer[i].arg);
92 #include <asm/fast_timer.h>
94 #ifdef CONFIG_SYSCTL
95 int fast_timer_sysctl(ctl_table *ctl, int write,
96 struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos)
98 int *valp = ctl->data;
99 int val = *valp;
100 int ret;
102 ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
103 if (write && (*valp != val))
104 fast_timer_set();
105 return ret;
108 static ctl_table dev_table[] = {
109 {2, "fast_timer",
110 &fast_timer_rate, sizeof(int), 0644, NULL, &fast_timer_sysctl},
114 static ctl_table root_table[] = {
115 {CTL_DEV, "dev", NULL, 0, 0555, dev_table},
119 static struct ctl_table_header *sysctl_header;
121 static void __init init_sysctl(void)
123 sysctl_header = register_sysctl_table(root_table, 0);
126 static void __exit cleanup_sysctl(void)
128 unregister_sysctl_table(sysctl_header);
131 #else
133 static inline void init_sysctl(void)
137 static inline void cleanup_sysctl(void)
141 #endif
143 static int __init fast_timer_init(void)
145 int ret;
147 spin_lock_init(&fast_timer_lock);
149 ret = fast_timer_setup();
150 if (ret != 0)
151 return ret;
153 init_sysctl();
154 return 0;
157 static void __exit fast_timer_exit(void)
159 cleanup_sysctl();
160 fast_timer_cleanup();
163 module_init(fast_timer_init);
164 module_exit(fast_timer_exit);
165 EXPORT_SYMBOL(fast_timer_add);
166 EXPORT_SYMBOL(fast_timer_remove);
167 MODULE_AUTHOR("Philip Craig <philipc@snapgear.com>");
168 MODULE_DESCRIPTION("Driver for general purpose fast timer");
169 MODULE_LICENSE("GPL");