26d15d18237a0717e80e0db147a3bc52c7ad0aac
[davej-history.git] / drivers / char / rtc.c
blob26d15d18237a0717e80e0db147a3bc52c7ad0aac
1 /*
2 * Real Time Clock interface for Linux
4 * Copyright (C) 1996 Paul Gortmaker
6 * This driver allows use of the real time clock (built into
7 * nearly all computers) from user space. It exports the /dev/rtc
8 * interface supporting various ioctl() and also the /proc/rtc
9 * pseudo-file for status information.
11 * The ioctls can be used to set the interrupt behaviour and
12 * generation rate from the RTC via IRQ 8. Then the /dev/rtc
13 * interface can be used to make use of these timer interrupts,
14 * be they interval or alarm based.
16 * The /dev/rtc interface will block on reads until an interrupt
17 * has been received. If a RTC interrupt has already happened,
18 * it will output an unsigned long and then block. The output value
19 * contains the interrupt status in the low byte and the number of
20 * interrupts since the last read in the remaining high bytes. The
21 * /dev/rtc interface can also be used with the select(2) call.
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License
25 * as published by the Free Software Foundation; either version
26 * 2 of the License, or (at your option) any later version.
28 * Based on other minimal char device drivers, like Alan's
29 * watchdog, Ted's random, etc. etc.
31 * 1.07 Paul Gortmaker.
32 * 1.08 Miquel van Smoorenburg: disallow certain things on the
33 * DEC Alpha as the CMOS clock is also used for other things.
34 * 1.09 Nikita Schmidt: epoch support and some Alpha cleanup.
38 #define RTC_VERSION"1.09"
40 #define RTC_IRQ 8/* Can't see this changing soon. */
41 #define RTC_IO_EXTENT 0x10/* Only really two ports, but... */
44 * Note that *all* calls to CMOS_READ and CMOS_WRITE are done with
45 * interrupts disabled. Due to the index-port/data-port (0x70/0x71)
46 * design of the RTC, we don't want two different things trying to
47 * get to it at once. (e.g. the periodic 11 min sync from time.c vs.
48 * this driver.)
51 #include <linux/config.h>
52 #include <linux/types.h>
53 #include <linux/errno.h>
54 #include <linux/miscdevice.h>
55 #include <linux/malloc.h>
56 #include <linux/ioport.h>
57 #include <linux/fcntl.h>
58 #include <linux/mc146818rtc.h>
59 #include <linux/init.h>
60 #include <linux/poll.h>
62 #include <asm/io.h>
63 #include <asm/uaccess.h>
64 #include <asm/system.h>
66 /* Adjust starting epoch if ARC console time is being used */
67 #ifdef CONFIG_RTC_ARC
68 #define ARCFUDGE 20
69 #else
70 #define ARCFUDGE 0
71 #endif
74 * We sponge a minor off of the misc major. No need slurping
75 * up another valuable major dev number for this. If you add
76 * an ioctl, make sure you don't conflict with SPARC's RTC
77 * ioctls.
80 static struct wait_queue *rtc_wait;
82 static struct timer_list rtc_irq_timer;
84 static long longrtc_llseek(struct file *file, loff_t offset,int origin);
86 static ssize_t rtc_read(struct file *file,char*buf,
87 size_t count, loff_t *ppos);
89 static intrtc_ioctl(struct inode *inode,struct file *file,
90 unsigned int cmd,unsigned long arg);
92 static unsigned intrtc_poll(struct file *file, poll_table *wait);
94 voidget_rtc_time(struct rtc_time *rtc_tm);
95 voidget_rtc_alm_time(struct rtc_time *alm_tm);
96 voidrtc_dropped_irq(unsigned long data);
98 voidset_rtc_irq_bit(unsigned char bit);
99 voidmask_rtc_irq_bit(unsigned char bit);
101 staticinlineunsigned charrtc_is_updating(void);
104 * Bits in rtc_status. (7 bits of room for future expansion)
107 #define RTC_IS_OPEN 0x01/* means /dev/rtc is in use */
108 #define RTC_TIMER_ON 0x02/* missed irq timer active */
110 unsigned char rtc_status =0;/* bitmapped status byte. */
111 unsigned long rtc_freq =0;/* Current periodic IRQ rate */
112 unsigned long rtc_irq_data =0;/* our output to the world */
115 * If this driver ever becomes modularised, it will be really nice
116 * to make the epoch retain its value across module reload...
119 static unsigned long epoch =1900;/* year corresponding to 0x00 */
121 unsigned char days_in_mo[] =
122 {0,31,28,31,30,31,30,31,31,30,31,30,31};
125 * A very tiny interrupt handler. It runs with SA_INTERRUPT set,
126 * so that there is no possibility of conflicting with the
127 * set_rtc_mmss() call that happens during some timer interrupts.
128 * (See ./arch/XXXX/kernel/time.c for the set_rtc_mmss() function.)
130 * On Alpha we won't get any interrupts anyway, as they all end up
131 * in the system timer code.
134 #ifndef __alpha__
135 static voidrtc_interrupt(int irq,void*dev_id,struct pt_regs *regs)
138 * Can be an alarm interrupt, update complete interrupt,
139 * or a periodic interrupt. We store the status in the
140 * low byte and the number of interrupts received since
141 * the last read in the remainder of rtc_irq_data.
144 rtc_irq_data +=0x100;
145 rtc_irq_data &= ~0xff;
146 rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) &0xF0);
147 wake_up_interruptible(&rtc_wait);
149 if(rtc_status & RTC_TIMER_ON) {
150 del_timer(&rtc_irq_timer);
151 rtc_irq_timer.expires = jiffies + HZ/rtc_freq +2*HZ/100;
152 add_timer(&rtc_irq_timer);
155 #endif
158 * Now all the various file operations that we export.
159 * They are all useless on Alpha... *sigh*.
162 static long longrtc_llseek(struct file *file, loff_t offset,int origin)
164 return-ESPIPE;
167 static ssize_t rtc_read(struct file *file,char*buf,
168 size_t count, loff_t *ppos)
170 #ifdef __alpha__
171 return-EIO;
172 #else
173 struct wait_queue wait = { current, NULL };
174 unsigned long data;
175 ssize_t retval;
177 if(count <sizeof(unsigned long))
178 return-EINVAL;
180 add_wait_queue(&rtc_wait, &wait);
182 current->state = TASK_INTERRUPTIBLE;
184 while((data =xchg(&rtc_irq_data,0)) ==0) {
185 if(file->f_flags & O_NONBLOCK) {
186 retval = -EAGAIN;
187 goto out;
189 if(signal_pending(current)) {
190 retval = -ERESTARTSYS;
191 goto out;
193 schedule();
196 retval =put_user(data, (unsigned long*)buf);
197 if(!retval)
198 retval =sizeof(unsigned long);
199 out:
200 current->state = TASK_RUNNING;
201 remove_wait_queue(&rtc_wait, &wait);
203 return retval;
204 #endif
207 static intrtc_ioctl(struct inode *inode,struct file *file,unsigned int cmd,
208 unsigned long arg)
211 unsigned long flags;
212 struct rtc_time wtime;
214 switch(cmd) {
215 #ifndef __alpha__
216 case RTC_AIE_OFF:/* Mask alarm int. enab. bit */
218 mask_rtc_irq_bit(RTC_AIE);
219 return0;
221 case RTC_AIE_ON:/* Allow alarm interrupts. */
223 set_rtc_irq_bit(RTC_AIE);
224 return0;
226 case RTC_PIE_OFF:/* Mask periodic int. enab. bit */
228 mask_rtc_irq_bit(RTC_PIE);
229 if(rtc_status & RTC_TIMER_ON) {
230 del_timer(&rtc_irq_timer);
231 rtc_status &= ~RTC_TIMER_ON;
233 return0;
235 case RTC_PIE_ON:/* Allow periodic ints */
239 * We don't really want Joe User enabling more
240 * than 64Hz of interrupts on a multi-user machine.
242 if((rtc_freq >64) && (!suser()))
243 return-EACCES;
245 if(!(rtc_status & RTC_TIMER_ON)) {
246 rtc_status |= RTC_TIMER_ON;
247 rtc_irq_timer.expires = jiffies + HZ/rtc_freq +2*HZ/100;
248 add_timer(&rtc_irq_timer);
250 set_rtc_irq_bit(RTC_PIE);
251 return0;
253 case RTC_UIE_OFF:/* Mask ints from RTC updates. */
255 mask_rtc_irq_bit(RTC_UIE);
256 return0;
258 case RTC_UIE_ON:/* Allow ints for RTC updates. */
260 set_rtc_irq_bit(RTC_UIE);
261 return0;
263 #endif
264 case RTC_ALM_READ:/* Read the present alarm time */
267 * This returns a struct rtc_time. Reading >= 0xc0
268 * means "don't care" or "match all". Only the tm_hour,
269 * tm_min, and tm_sec values are filled in.
272 get_rtc_alm_time(&wtime);
273 break;
275 case RTC_ALM_SET:/* Store a time into the alarm */
278 * This expects a struct rtc_time. Writing 0xff means
279 * "don't care" or "match all". Only the tm_hour,
280 * tm_min and tm_sec are used.
282 unsigned char hrs, min, sec;
283 struct rtc_time alm_tm;
285 if(copy_from_user(&alm_tm, (struct rtc_time*)arg,
286 sizeof(struct rtc_time)))
287 return-EFAULT;
289 hrs = alm_tm.tm_hour;
290 min = alm_tm.tm_min;
291 sec = alm_tm.tm_sec;
293 if(hrs >=24)
294 hrs =0xff;
296 if(min >=60)
297 min =0xff;
299 if(sec >=60)
300 sec =0xff;
302 save_flags(flags);
303 cli();
304 if(!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) ||
305 RTC_ALWAYS_BCD)
307 BIN_TO_BCD(sec);
308 BIN_TO_BCD(min);
309 BIN_TO_BCD(hrs);
311 CMOS_WRITE(hrs, RTC_HOURS_ALARM);
312 CMOS_WRITE(min, RTC_MINUTES_ALARM);
313 CMOS_WRITE(sec, RTC_SECONDS_ALARM);
314 restore_flags(flags);
316 return0;
318 case RTC_RD_TIME:/* Read the time/date from RTC */
320 get_rtc_time(&wtime);
321 break;
323 case RTC_SET_TIME:/* Set the RTC */
325 struct rtc_time rtc_tm;
326 unsigned char mon, day, hrs, min, sec, leap_yr;
327 unsigned char save_control, save_freq_select;
328 unsigned int yrs;
329 unsigned long flags;
331 if(!suser())
332 return-EACCES;
334 if(copy_from_user(&rtc_tm, (struct rtc_time*)arg,
335 sizeof(struct rtc_time)))
336 return-EFAULT;
338 yrs = rtc_tm.tm_year +1900+ ARCFUDGE;
339 mon = rtc_tm.tm_mon +1;/* tm_mon starts at zero */
340 day = rtc_tm.tm_mday;
341 hrs = rtc_tm.tm_hour;
342 min = rtc_tm.tm_min;
343 sec = rtc_tm.tm_sec;
345 if(yrs <1970)
346 return-EINVAL;
348 leap_yr = ((!(yrs %4) && (yrs %100)) || !(yrs %400));
350 if((mon >12) || (day ==0))
351 return-EINVAL;
353 if(day > (days_in_mo[mon] + ((mon ==2) && leap_yr)))
354 return-EINVAL;
356 if((hrs >=24) || (min >=60) || (sec >=60))
357 return-EINVAL;
359 if((yrs -= epoch) >255)/* They are unsigned */
360 return-EINVAL;
362 save_flags(flags);
363 cli();
364 if(!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
365 || RTC_ALWAYS_BCD) {
366 if(yrs >169) {
367 restore_flags(flags);
368 return-EINVAL;
370 if(yrs >=100)
371 yrs -=100;
373 BIN_TO_BCD(sec);
374 BIN_TO_BCD(min);
375 BIN_TO_BCD(hrs);
376 BIN_TO_BCD(day);
377 BIN_TO_BCD(mon);
378 BIN_TO_BCD(yrs);
381 save_control =CMOS_READ(RTC_CONTROL);
382 CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
383 save_freq_select =CMOS_READ(RTC_FREQ_SELECT);
384 CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
386 CMOS_WRITE(yrs, RTC_YEAR);
387 CMOS_WRITE(mon, RTC_MONTH);
388 CMOS_WRITE(day, RTC_DAY_OF_MONTH);
389 CMOS_WRITE(hrs, RTC_HOURS);
390 CMOS_WRITE(min, RTC_MINUTES);
391 CMOS_WRITE(sec, RTC_SECONDS);
393 CMOS_WRITE(save_control, RTC_CONTROL);
394 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
396 restore_flags(flags);
397 return0;
399 case RTC_IRQP_READ:/* Read the periodic IRQ rate. */
401 returnput_user(rtc_freq, (unsigned long*)arg);
403 #ifndef __alpha__
404 case RTC_IRQP_SET:/* Set periodic IRQ rate. */
406 int tmp =0;
407 unsigned char val;
410 * The max we can do is 8192Hz.
412 if((arg <2) || (arg >8192))
413 return-EINVAL;
415 * We don't really want Joe User generating more
416 * than 64Hz of interrupts on a multi-user machine.
418 if((arg >64) && (!suser()))
419 return-EACCES;
421 while(arg > (1<<tmp))
422 tmp++;
425 * Check that the input was really a power of 2.
427 if(arg != (1<<tmp))
428 return-EINVAL;
430 rtc_freq = arg;
432 save_flags(flags);
433 cli();
434 val =CMOS_READ(RTC_FREQ_SELECT) &0xf0;
435 val |= (16- tmp);
436 CMOS_WRITE(val, RTC_FREQ_SELECT);
437 restore_flags(flags);
438 return0;
440 #else/* __alpha__ */
441 case RTC_EPOCH_READ:/* Read the epoch. */
443 returnput_user(epoch, (unsigned long*)arg);
445 case RTC_EPOCH_SET:/* Set the epoch. */
448 * There were no RTC clocks before 1900.
450 if(arg <1900)
451 return-EINVAL;
453 if(!suser())
454 return-EACCES;
456 epoch = arg;
457 return0;
459 #endif
460 default:
461 return-EINVAL;
463 returncopy_to_user((void*)arg, &wtime,sizeof wtime) ? -EFAULT :0;
467 * We enforce only one user at a time here with the open/close.
468 * Also clear the previous interrupt data on an open, and clean
469 * up things on a close.
470 * On Alpha we just open, for we don't mess with interrups anyway.
473 static intrtc_open(struct inode *inode,struct file *file)
475 #ifndef __alpha__
476 if(rtc_status & RTC_IS_OPEN)
477 return-EBUSY;
479 rtc_status |= RTC_IS_OPEN;
480 rtc_irq_data =0;
481 #endif
482 return0;
485 static intrtc_release(struct inode *inode,struct file *file)
488 * Turn off all interrupts once the device is no longer
489 * in use, and clear the data.
492 #ifndef __alpha__
493 unsigned char tmp;
494 unsigned long flags;
496 save_flags(flags);
497 cli();
498 tmp =CMOS_READ(RTC_CONTROL);
499 tmp &= ~RTC_PIE;
500 tmp &= ~RTC_AIE;
501 tmp &= ~RTC_UIE;
502 CMOS_WRITE(tmp, RTC_CONTROL);
503 CMOS_READ(RTC_INTR_FLAGS);
504 restore_flags(flags);
506 if(rtc_status & RTC_TIMER_ON) {
507 rtc_status &= ~RTC_TIMER_ON;
508 del_timer(&rtc_irq_timer);
511 rtc_irq_data =0;
512 rtc_status &= ~RTC_IS_OPEN;
513 #endif
514 return0;
517 #ifndef __alpha__
518 static unsigned intrtc_poll(struct file *file, poll_table *wait)
520 poll_wait(file, &rtc_wait, wait);
521 if(rtc_irq_data !=0)
522 return POLLIN | POLLRDNORM;
523 return0;
525 #endif
528 * The various file operations we support.
531 static struct file_operations rtc_fops = {
532 rtc_llseek,
533 rtc_read,
534 NULL,/* No write */
535 NULL,/* No readdir */
536 #ifdef __alpha__
537 NULL,/* No select on Alpha */
538 #else
539 rtc_poll,
540 #endif
541 rtc_ioctl,
542 NULL,/* No mmap */
543 rtc_open,
544 rtc_release
547 static struct miscdevice rtc_dev=
549 RTC_MINOR,
550 "rtc",
551 &rtc_fops
554 __initfunc(intrtc_init(void))
556 unsigned long flags;
557 #ifdef __alpha__
558 unsigned int year, ctrl;
559 unsigned long uip_watchdog;
560 char*guess = NULL;
561 #endif
562 printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION);
563 #ifndef __alpha__
564 if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT,"rtc", NULL))
566 /* Yeah right, seeing as irq 8 doesn't even hit the bus. */
567 printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
568 return-EIO;
570 #endif
571 misc_register(&rtc_dev);
572 /* Check region? Naaah! Just snarf it up. */
573 request_region(RTC_PORT(0), RTC_IO_EXTENT,"rtc");
574 #ifdef __alpha__
575 rtc_freq = HZ;
577 /* Each operating system on an Alpha uses its own epoch.
578 Let's try to guess which one we are using now. */
580 uip_watchdog = jiffies;
581 if(rtc_is_updating() !=0)
582 while(jiffies - uip_watchdog <2*HZ/100)
583 barrier();
585 save_flags(flags);
586 cli();
587 year =CMOS_READ(RTC_YEAR);
588 ctrl =CMOS_READ(RTC_CONTROL);
589 restore_flags(flags);
591 if(!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
592 BCD_TO_BIN(year);/* This should never happen... */
594 if(year >10&& year <44) {
595 epoch =1980;
596 guess ="ARC console";
597 }else if(year <96) {
598 epoch =1952;
599 guess ="Digital UNIX";
601 if(guess)
602 printk("rtc: %s epoch (%ld) detected\n", guess, epoch);
603 #else
604 init_timer(&rtc_irq_timer);
605 rtc_irq_timer.function = rtc_dropped_irq;
606 rtc_wait = NULL;
607 save_flags(flags);
608 cli();
609 /* Initialize periodic freq. to CMOS reset default, which is 1024Hz */
610 CMOS_WRITE(((CMOS_READ(RTC_FREQ_SELECT) &0xF0) |0x06), RTC_FREQ_SELECT);
611 restore_flags(flags);
612 rtc_freq =1024;
613 #endif
614 return0;
618 * At IRQ rates >= 4096Hz, an interrupt may get lost altogether.
619 * (usually during an IDE disk interrupt, with IRQ unmasking off)
620 * Since the interrupt handler doesn't get called, the IRQ status
621 * byte doesn't get read, and the RTC stops generating interrupts.
622 * A timer is set, and will call this function if/when that happens.
623 * To get it out of this stalled state, we just read the status.
624 * At least a jiffy of interrupts (rtc_freq/HZ) will have been lost.
625 * (You *really* shouldn't be trying to use a non-realtime system
626 * for something that requires a steady > 1KHz signal anyways.)
629 #ifndef __alpha__
630 voidrtc_dropped_irq(unsigned long data)
632 unsigned long flags;
634 printk(KERN_INFO "rtc: lost some interrupts at %ldHz.\n", rtc_freq);
635 del_timer(&rtc_irq_timer);
636 rtc_irq_timer.expires = jiffies + HZ/rtc_freq +2*HZ/100;
637 add_timer(&rtc_irq_timer);
639 save_flags(flags);
640 cli();
641 rtc_irq_data += ((rtc_freq/HZ)<<8);
642 rtc_irq_data &= ~0xff;
643 rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) &0xF0);/* restart */
644 restore_flags(flags);
646 #endif
649 * Info exported via "/proc/rtc".
652 intget_rtc_status(char*buf)
654 char*p;
655 struct rtc_time tm;
656 unsigned char batt, ctrl;
657 unsigned long flags;
659 save_flags(flags);
660 cli();
661 batt =CMOS_READ(RTC_VALID) & RTC_VRT;
662 ctrl =CMOS_READ(RTC_CONTROL);
663 restore_flags(flags);
665 p = buf;
667 get_rtc_time(&tm);
670 * There is no way to tell if the luser has the RTC set for local
671 * time or for Universal Standard Time (GMT). Probably local though.
673 p +=sprintf(p,
674 "rtc_time\t: %02d:%02d:%02d\n"
675 "rtc_date\t: %04d-%02d-%02d\n",
676 tm.tm_hour, tm.tm_min, tm.tm_sec,
677 tm.tm_year +1900, tm.tm_mon +1, tm.tm_mday);
679 get_rtc_alm_time(&tm);
682 * We implicitly assume 24hr mode here. Alarm values >= 0xc0 will
683 * match any value for that particular field. Values that are
684 * greater than a valid time, but less than 0xc0 shouldn't appear.
686 p +=sprintf(p,"alarm\t\t: ");
687 if(tm.tm_hour <=24)
688 p +=sprintf(p,"%02d:", tm.tm_hour);
689 else
690 p +=sprintf(p,"**:");
692 if(tm.tm_min <=59)
693 p +=sprintf(p,"%02d:", tm.tm_min);
694 else
695 p +=sprintf(p,"**:");
697 if(tm.tm_sec <=59)
698 p +=sprintf(p,"%02d\n", tm.tm_sec);
699 else
700 p +=sprintf(p,"**\n");
702 p +=sprintf(p,
703 "DST_enable\t: %s\n"
704 "BCD\t\t: %s\n"
705 "24hr\t\t: %s\n"
706 "square_wave\t: %s\n"
707 "alarm_IRQ\t: %s\n"
708 "update_IRQ\t: %s\n"
709 "periodic_IRQ\t: %s\n"
710 "periodic_freq\t: %ld\n"
711 "batt_status\t: %s\n",
712 (ctrl & RTC_DST_EN) ?"yes":"no",
713 (ctrl & RTC_DM_BINARY) ?"no":"yes",
714 (ctrl & RTC_24H) ?"yes":"no",
715 (ctrl & RTC_SQWE) ?"yes":"no",
716 (ctrl & RTC_AIE) ?"yes":"no",
717 (ctrl & RTC_UIE) ?"yes":"no",
718 (ctrl & RTC_PIE) ?"yes":"no",
719 rtc_freq,
720 batt ?"okay":"dead");
722 return p - buf;
726 * Returns true if a clock update is in progress
728 staticinlineunsigned charrtc_is_updating(void)
730 unsigned long flags;
731 unsigned char uip;
733 save_flags(flags);
734 cli();
735 uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
736 restore_flags(flags);
737 return uip;
740 voidget_rtc_time(struct rtc_time *rtc_tm)
743 unsigned long flags, uip_watchdog = jiffies;
744 unsigned char ctrl;
747 * read RTC once any update in progress is done. The update
748 * can take just over 2ms. We wait 10 to 20ms. There is no need to
749 * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
750 * If you need to know *exactly* when a second has started, enable
751 * periodic update complete interrupts, (via ioctl) and then
752 * immediately read /dev/rtc which will block until you get the IRQ.
753 * Once the read clears, read the RTC time (again via ioctl). Easy.
756 if(rtc_is_updating() !=0)
757 while(jiffies - uip_watchdog <2*HZ/100)
758 barrier();
761 * Only the values that we read from the RTC are set. We leave
762 * tm_wday, tm_yday and tm_isdst untouched. Even though the
763 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
764 * by the RTC when initially set to a non-zero value.
766 save_flags(flags);
767 cli();
768 rtc_tm->tm_sec =CMOS_READ(RTC_SECONDS);
769 rtc_tm->tm_min =CMOS_READ(RTC_MINUTES);
770 rtc_tm->tm_hour =CMOS_READ(RTC_HOURS);
771 rtc_tm->tm_mday =CMOS_READ(RTC_DAY_OF_MONTH);
772 rtc_tm->tm_mon =CMOS_READ(RTC_MONTH);
773 rtc_tm->tm_year =CMOS_READ(RTC_YEAR);
774 ctrl =CMOS_READ(RTC_CONTROL);
775 restore_flags(flags);
777 if(!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
779 BCD_TO_BIN(rtc_tm->tm_sec);
780 BCD_TO_BIN(rtc_tm->tm_min);
781 BCD_TO_BIN(rtc_tm->tm_hour);
782 BCD_TO_BIN(rtc_tm->tm_mday);
783 BCD_TO_BIN(rtc_tm->tm_mon);
784 BCD_TO_BIN(rtc_tm->tm_year);
788 * Account for differences between how the RTC uses the values
789 * and how they are defined in a struct rtc_time;
791 if((rtc_tm->tm_year += epoch -1900) <=69)
792 rtc_tm->tm_year +=100;
794 /* if ARCFUDGE == 0, the optimizer should do away with this */
795 rtc_tm->tm_year -= ARCFUDGE;
797 rtc_tm->tm_mon--;
800 voidget_rtc_alm_time(struct rtc_time *alm_tm)
802 unsigned long flags;
803 unsigned char ctrl;
806 * Only the values that we read from the RTC are set. That
807 * means only tm_hour, tm_min, and tm_sec.
809 save_flags(flags);
810 cli();
811 alm_tm->tm_sec =CMOS_READ(RTC_SECONDS_ALARM);
812 alm_tm->tm_min =CMOS_READ(RTC_MINUTES_ALARM);
813 alm_tm->tm_hour =CMOS_READ(RTC_HOURS_ALARM);
814 ctrl =CMOS_READ(RTC_CONTROL);
815 restore_flags(flags);
817 if(!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
819 BCD_TO_BIN(alm_tm->tm_sec);
820 BCD_TO_BIN(alm_tm->tm_min);
821 BCD_TO_BIN(alm_tm->tm_hour);
826 * Used to disable/enable interrupts for any one of UIE, AIE, PIE.
827 * Rumour has it that if you frob the interrupt enable/disable
828 * bits in RTC_CONTROL, you should read RTC_INTR_FLAGS, to
829 * ensure you actually start getting interrupts. Probably for
830 * compatibility with older/broken chipset RTC implementations.
831 * We also clear out any old irq data after an ioctl() that
832 * meddles with the interrupt enable/disable bits.
835 #ifndef __alpha__
836 voidmask_rtc_irq_bit(unsigned char bit)
838 unsigned char val;
839 unsigned long flags;
841 save_flags(flags);
842 cli();
843 val =CMOS_READ(RTC_CONTROL);
844 val &= ~bit;
845 CMOS_WRITE(val, RTC_CONTROL);
846 CMOS_READ(RTC_INTR_FLAGS);
847 restore_flags(flags);
848 rtc_irq_data =0;
851 voidset_rtc_irq_bit(unsigned char bit)
853 unsigned char val;
854 unsigned long flags;
856 save_flags(flags);
857 cli();
858 val =CMOS_READ(RTC_CONTROL);
859 val |= bit;
860 CMOS_WRITE(val, RTC_CONTROL);
861 CMOS_READ(RTC_INTR_FLAGS);
862 rtc_irq_data =0;
863 restore_flags(flags);
865 #endif
close