Coarsly sort out 32-bit-only, 64-bit-only and ``portable'' MIPS lib/
[linux-2.6/linux-mips.git] / drivers / char / upd4990a.c
blobf06f509fb5f8c926cc8df08b3eda9a4b220e2798
1 /*
2 * NEC PC-9800 Real Time Clock interface for Linux
4 * Copyright (C) 1997-2001 Linux/98 project,
5 * Kyoto University Microcomputer Club.
7 * Based on:
8 * drivers/char/rtc.c by Paul Gortmaker
10 * Changes:
11 * 2001-02-09 Call check_region on rtc_init and do not request I/O 0033h.
12 * Call del_timer and release_region on rtc_exit. -- tak
13 * 2001-07-14 Rewrite <linux/upd4990a.h> and split to <linux/upd4990a.h>
14 * and <asm-i386/upd4990a.h>.
15 * Introduce a lot of spin_lock/unlock (&rtc_lock).
18 #define RTC98_VERSION "1.2"
20 #include <linux/module.h>
21 #include <linux/kernel.h>
22 #include <linux/types.h>
23 #include <linux/miscdevice.h>
24 #include <linux/ioport.h>
25 #include <linux/fcntl.h>
26 #include <linux/rtc.h>
27 #include <linux/bcd.h>
28 #include <linux/upd4990a.h>
29 #include <linux/init.h>
30 #include <linux/poll.h>
31 #include <linux/proc_fs.h>
32 #include <linux/spinlock.h>
34 #include <asm/io.h>
35 #include <asm/uaccess.h>
36 #include <asm/system.h>
39 * We sponge a minor off of the misc major. No need slurping
40 * up another valuable major dev number for this. If you add
41 * an ioctl, make sure you don't conflict with SPARC's RTC
42 * ioctls.
45 static struct fasync_struct *rtc_async_queue;
47 static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
49 static struct timer_list rtc_uie_timer;
50 static u8 old_refclk;
52 static int rtc_ioctl(struct inode *inode, struct file *file,
53 unsigned int cmd, unsigned long arg);
55 static int rtc_read_proc(char *page, char **start, off_t off,
56 int count, int *eof, void *data);
59 * Bits in rtc_status. (5 bits of room for future expansion)
62 #define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */
63 #define RTC_TIMER_ON 0x02 /* not used */
64 #define RTC_UIE_TIMER_ON 0x04 /* UIE emulation timer is active */
67 * rtc_status is never changed by rtc_interrupt, and ioctl/open/close is
68 * protected by the big kernel lock. However, ioctl can still disable the timer
69 * in rtc_status and then with del_timer after the interrupt has read
70 * rtc_status but before mod_timer is called, which would then reenable the
71 * timer (but you would need to have an awful timing before you'd trip on it)
73 static unsigned char rtc_status; /* bitmapped status byte. */
74 static unsigned long rtc_irq_data; /* our output to the world */
76 static const unsigned char days_in_mo[] =
77 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
79 extern spinlock_t rtc_lock; /* defined in arch/i386/kernel/time.c */
81 static void rtc_uie_intr(unsigned long data)
83 u8 refclk, tmp;
85 /* Kernel timer does del_timer internally before calling
86 each timer entry, so this is unnecessary.
87 del_timer(&rtc_uie_timer); */
88 spin_lock(&rtc_lock);
90 /* Detect rising edge of 1Hz reference clock. */
91 refclk = UPD4990A_READ_DATA();
92 tmp = old_refclk & refclk;
93 old_refclk = ~refclk;
94 if (!(tmp & 1))
95 rtc_irq_data += 0x100;
97 spin_unlock(&rtc_lock);
99 if (!(tmp & 1)) {
100 /* Now do the rest of the actions */
101 wake_up_interruptible(&rtc_wait);
102 kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
105 rtc_uie_timer.expires = jiffies + 1;
106 add_timer(&rtc_uie_timer);
110 * Now all the various file operations that we export.
113 static ssize_t rtc_read(struct file *file, char *buf,
114 size_t count, loff_t *ppos)
116 DECLARE_WAITQUEUE(wait, current);
117 unsigned long data;
118 ssize_t retval = 0;
120 if (count < sizeof(unsigned long))
121 return -EINVAL;
123 add_wait_queue(&rtc_wait, &wait);
125 set_current_state(TASK_INTERRUPTIBLE);
127 do {
128 /* First make it right. Then make it fast. Putting this whole
129 * block within the parentheses of a while would be too
130 * confusing. And no, xchg() is not the answer. */
131 spin_lock_irq(&rtc_lock);
132 data = rtc_irq_data;
133 rtc_irq_data = 0;
134 spin_unlock_irq(&rtc_lock);
136 if (data != 0)
137 break;
138 if (file->f_flags & O_NONBLOCK) {
139 retval = -EAGAIN;
140 goto out;
142 if (signal_pending(current)) {
143 retval = -ERESTARTSYS;
144 goto out;
146 schedule();
147 } while (1);
149 retval = put_user(data, (unsigned long *)buf);
150 if (!retval)
151 retval = sizeof(unsigned long);
152 out:
153 set_current_state(TASK_RUNNING);
154 remove_wait_queue(&rtc_wait, &wait);
156 return retval;
159 static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
160 unsigned long arg)
162 struct rtc_time wtime;
163 struct upd4990a_raw_data raw;
165 switch (cmd) {
166 case RTC_UIE_OFF: /* Mask ints from RTC updates. */
167 spin_lock_irq(&rtc_lock);
168 if (rtc_status & RTC_UIE_TIMER_ON) {
169 rtc_status &= ~RTC_UIE_TIMER_ON;
170 del_timer(&rtc_uie_timer);
172 spin_unlock_irq(&rtc_lock);
173 return 0;
175 case RTC_UIE_ON: /* Allow ints for RTC updates. */
176 spin_lock_irq(&rtc_lock);
177 rtc_irq_data = 0;
178 if (!(rtc_status & RTC_UIE_TIMER_ON)) {
179 rtc_status |= RTC_UIE_TIMER_ON;
180 rtc_uie_timer.expires = jiffies + 1;
181 add_timer(&rtc_uie_timer);
183 /* Just in case... */
184 upd4990a_serial_command(UPD4990A_REGISTER_HOLD);
185 old_refclk = ~UPD4990A_READ_DATA();
186 spin_unlock_irq(&rtc_lock);
187 return 0;
189 case RTC_RD_TIME: /* Read the time/date from RTC */
190 spin_lock_irq(&rtc_lock);
191 upd4990a_get_time(&raw, 0);
192 spin_unlock_irq(&rtc_lock);
194 wtime.tm_sec = BCD2BIN(raw.sec);
195 wtime.tm_min = BCD2BIN(raw.min);
196 wtime.tm_hour = BCD2BIN(raw.hour);
197 wtime.tm_mday = BCD2BIN(raw.mday);
198 wtime.tm_mon = raw.mon - 1; /* convert to 0-base */
199 wtime.tm_wday = raw.wday;
202 * Account for differences between how the RTC uses the values
203 * and how they are defined in a struct rtc_time;
205 if ((wtime.tm_year = BCD2BIN(raw.year)) < 95)
206 wtime.tm_year += 100;
208 wtime.tm_isdst = 0;
209 break;
211 case RTC_SET_TIME: /* Set the RTC */
213 int leap_yr;
215 if (!capable(CAP_SYS_TIME))
216 return -EACCES;
218 if (copy_from_user(&wtime, (struct rtc_time *) arg,
219 sizeof (struct rtc_time)))
220 return -EFAULT;
222 /* Valid year is 1995 - 2094, inclusive. */
223 if (wtime.tm_year < 95 || wtime.tm_year > 194)
224 return -EINVAL;
226 if (wtime.tm_mon > 11 || wtime.tm_mday == 0)
227 return -EINVAL;
229 /* For acceptable year domain (1995 - 2094),
230 this IS sufficient. */
231 leap_yr = !(wtime.tm_year % 4);
233 if (wtime.tm_mday > (days_in_mo[wtime.tm_mon]
234 + (wtime.tm_mon == 2 && leap_yr)))
235 return -EINVAL;
237 if (wtime.tm_hour >= 24
238 || wtime.tm_min >= 60 || wtime.tm_sec >= 60)
239 return -EINVAL;
241 if (wtime.tm_wday > 6)
242 return -EINVAL;
244 raw.sec = BIN2BCD(wtime.tm_sec);
245 raw.min = BIN2BCD(wtime.tm_min);
246 raw.hour = BIN2BCD(wtime.tm_hour);
247 raw.mday = BIN2BCD(wtime.tm_mday);
248 raw.mon = wtime.tm_mon + 1;
249 raw.wday = wtime.tm_wday;
250 raw.year = BIN2BCD(wtime.tm_year % 100);
252 spin_lock_irq(&rtc_lock);
253 upd4990a_set_time(&raw, 0);
254 spin_unlock_irq(&rtc_lock);
256 return 0;
258 default:
259 return -EINVAL;
261 return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
265 * We enforce only one user at a time here with the open/close.
266 * Also clear the previous interrupt data on an open, and clean
267 * up things on a close.
270 static int rtc_open(struct inode *inode, struct file *file)
272 spin_lock_irq(&rtc_lock);
274 if(rtc_status & RTC_IS_OPEN)
275 goto out_busy;
277 rtc_status |= RTC_IS_OPEN;
279 rtc_irq_data = 0;
280 spin_unlock_irq(&rtc_lock);
281 return 0;
283 out_busy:
284 spin_unlock_irq(&rtc_lock);
285 return -EBUSY;
288 static int rtc_fasync(int fd, struct file *filp, int on)
290 return fasync_helper(fd, filp, on, &rtc_async_queue);
293 static int rtc_release(struct inode *inode, struct file *file)
295 del_timer(&rtc_uie_timer);
297 if (file->f_flags & FASYNC)
298 rtc_fasync(-1, file, 0);
300 rtc_irq_data = 0;
302 /* No need for locking -- nobody else can do anything until this rmw is
303 * committed, and no timer is running. */
304 rtc_status &= ~(RTC_IS_OPEN | RTC_UIE_TIMER_ON);
305 return 0;
308 static unsigned int rtc_poll(struct file *file, poll_table *wait)
310 unsigned long l;
312 poll_wait(file, &rtc_wait, wait);
314 spin_lock_irq(&rtc_lock);
315 l = rtc_irq_data;
316 spin_unlock_irq(&rtc_lock);
318 if (l != 0)
319 return POLLIN | POLLRDNORM;
320 return 0;
324 * The various file operations we support.
327 static struct file_operations rtc_fops = {
328 .owner = THIS_MODULE,
329 .read = rtc_read,
330 .poll = rtc_poll,
331 .ioctl = rtc_ioctl,
332 .open = rtc_open,
333 .release = rtc_release,
334 .fasync = rtc_fasync,
337 static struct miscdevice rtc_dev=
339 .minor = RTC_MINOR,
340 .name = "rtc",
341 .fops = &rtc_fops,
344 static int __init rtc_init(void)
346 int err = 0;
348 if (!request_region(UPD4990A_IO, 1, "rtc")) {
349 printk(KERN_ERR "upd4990a: could not acquire I/O port %#x\n",
350 UPD4990A_IO);
351 return -EBUSY;
354 err = misc_register(&rtc_dev);
355 if (err) {
356 printk(KERN_ERR "upd4990a: can't misc_register() on minor=%d\n",
357 RTC_MINOR);
358 release_region(UPD4990A_IO, 1);
359 return err;
362 #if 0
363 printk(KERN_INFO "\xB6\xDA\xDD\xC0\xDE \xC4\xDE\xB9\xB2 Driver\n"); /* Calender Clock Driver */
364 #else
365 printk(KERN_INFO
366 "Real Time Clock driver for NEC PC-9800 v" RTC98_VERSION "\n");
367 #endif
368 create_proc_read_entry("driver/rtc", 0, NULL, rtc_read_proc, NULL);
370 init_timer(&rtc_uie_timer);
371 rtc_uie_timer.function = rtc_uie_intr;
373 return 0;
376 module_init (rtc_init);
378 static void __exit rtc_exit(void)
380 del_timer(&rtc_uie_timer);
381 release_region(UPD4990A_IO, 1);
382 remove_proc_entry("driver/rtc", NULL);
383 misc_deregister(&rtc_dev);
386 module_exit (rtc_exit);
389 * Info exported via "/proc/driver/rtc".
392 static inline int rtc_get_status(char *buf)
394 char *p;
395 unsigned int year;
396 struct upd4990a_raw_data data;
398 p = buf;
400 upd4990a_get_time(&data, 0);
403 * There is no way to tell if the luser has the RTC set for local
404 * time or for Universal Standard Time (GMT). Probably local though.
406 if ((year = BCD2BIN(data.year) + 1900) < 1995)
407 year += 100;
408 p += sprintf(p,
409 "rtc_time\t: %02d:%02d:%02d\n"
410 "rtc_date\t: %04d-%02d-%02d\n",
411 BCD2BIN(data.hour), BCD2BIN(data.min),
412 BCD2BIN(data.sec),
413 year, data.mon, BCD2BIN(data.mday));
415 return p - buf;
418 static int rtc_read_proc(char *page, char **start, off_t off,
419 int count, int *eof, void *data)
421 int len = rtc_get_status(page);
423 if (len <= off + count)
424 *eof = 1;
425 *start = page + off;
426 len -= off;
427 if (len > count)
428 len = count;
429 if (len < 0)
430 len = 0;
431 return len;