diff options
Diffstat (limited to 'drivers/char/rtc.c')
-rw-r--r-- | drivers/char/rtc.c | 253 |
1 files changed, 143 insertions, 110 deletions
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index 0c66b802736a..78b151c4d20f 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Real Time Clock interface for Linux | 2 | * Real Time Clock interface for Linux |
3 | * | 3 | * |
4 | * Copyright (C) 1996 Paul Gortmaker | 4 | * Copyright (C) 1996 Paul Gortmaker |
5 | * | 5 | * |
@@ -17,7 +17,7 @@ | |||
17 | * has been received. If a RTC interrupt has already happened, | 17 | * has been received. If a RTC interrupt has already happened, |
18 | * it will output an unsigned long and then block. The output value | 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 | 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 | 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. | 21 | * /dev/rtc interface can also be used with the select(2) call. |
22 | * | 22 | * |
23 | * This program is free software; you can redistribute it and/or | 23 | * This program is free software; you can redistribute it and/or |
@@ -104,12 +104,14 @@ static int rtc_has_irq = 1; | |||
104 | 104 | ||
105 | #ifndef CONFIG_HPET_EMULATE_RTC | 105 | #ifndef CONFIG_HPET_EMULATE_RTC |
106 | #define is_hpet_enabled() 0 | 106 | #define is_hpet_enabled() 0 |
107 | #define hpet_set_alarm_time(hrs, min, sec) 0 | 107 | #define hpet_set_alarm_time(hrs, min, sec) 0 |
108 | #define hpet_set_periodic_freq(arg) 0 | 108 | #define hpet_set_periodic_freq(arg) 0 |
109 | #define hpet_mask_rtc_irq_bit(arg) 0 | 109 | #define hpet_mask_rtc_irq_bit(arg) 0 |
110 | #define hpet_set_rtc_irq_bit(arg) 0 | 110 | #define hpet_set_rtc_irq_bit(arg) 0 |
111 | #define hpet_rtc_timer_init() do { } while (0) | 111 | #define hpet_rtc_timer_init() do { } while (0) |
112 | #define hpet_rtc_dropped_irq() 0 | 112 | #define hpet_rtc_dropped_irq() 0 |
113 | #define hpet_register_irq_handler(h) 0 | ||
114 | #define hpet_unregister_irq_handler(h) 0 | ||
113 | #ifdef RTC_IRQ | 115 | #ifdef RTC_IRQ |
114 | static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) | 116 | static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) |
115 | { | 117 | { |
@@ -147,7 +149,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, | |||
147 | static unsigned int rtc_poll(struct file *file, poll_table *wait); | 149 | static unsigned int rtc_poll(struct file *file, poll_table *wait); |
148 | #endif | 150 | #endif |
149 | 151 | ||
150 | static void get_rtc_alm_time (struct rtc_time *alm_tm); | 152 | static void get_rtc_alm_time(struct rtc_time *alm_tm); |
151 | #ifdef RTC_IRQ | 153 | #ifdef RTC_IRQ |
152 | static void set_rtc_irq_bit_locked(unsigned char bit); | 154 | static void set_rtc_irq_bit_locked(unsigned char bit); |
153 | static void mask_rtc_irq_bit_locked(unsigned char bit); | 155 | static void mask_rtc_irq_bit_locked(unsigned char bit); |
@@ -185,9 +187,9 @@ static int rtc_proc_open(struct inode *inode, struct file *file); | |||
185 | * rtc_status but before mod_timer is called, which would then reenable the | 187 | * rtc_status but before mod_timer is called, which would then reenable the |
186 | * timer (but you would need to have an awful timing before you'd trip on it) | 188 | * timer (but you would need to have an awful timing before you'd trip on it) |
187 | */ | 189 | */ |
188 | static unsigned long rtc_status = 0; /* bitmapped status byte. */ | 190 | static unsigned long rtc_status; /* bitmapped status byte. */ |
189 | static unsigned long rtc_freq = 0; /* Current periodic IRQ rate */ | 191 | static unsigned long rtc_freq; /* Current periodic IRQ rate */ |
190 | static unsigned long rtc_irq_data = 0; /* our output to the world */ | 192 | static unsigned long rtc_irq_data; /* our output to the world */ |
191 | static unsigned long rtc_max_user_freq = 64; /* > this, need CAP_SYS_RESOURCE */ | 193 | static unsigned long rtc_max_user_freq = 64; /* > this, need CAP_SYS_RESOURCE */ |
192 | 194 | ||
193 | #ifdef RTC_IRQ | 195 | #ifdef RTC_IRQ |
@@ -195,7 +197,7 @@ static unsigned long rtc_max_user_freq = 64; /* > this, need CAP_SYS_RESOURCE */ | |||
195 | * rtc_task_lock nests inside rtc_lock. | 197 | * rtc_task_lock nests inside rtc_lock. |
196 | */ | 198 | */ |
197 | static DEFINE_SPINLOCK(rtc_task_lock); | 199 | static DEFINE_SPINLOCK(rtc_task_lock); |
198 | static rtc_task_t *rtc_callback = NULL; | 200 | static rtc_task_t *rtc_callback; |
199 | #endif | 201 | #endif |
200 | 202 | ||
201 | /* | 203 | /* |
@@ -205,7 +207,7 @@ static rtc_task_t *rtc_callback = NULL; | |||
205 | 207 | ||
206 | static unsigned long epoch = 1900; /* year corresponding to 0x00 */ | 208 | static unsigned long epoch = 1900; /* year corresponding to 0x00 */ |
207 | 209 | ||
208 | static const unsigned char days_in_mo[] = | 210 | static const unsigned char days_in_mo[] = |
209 | {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; | 211 | {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; |
210 | 212 | ||
211 | /* | 213 | /* |
@@ -242,7 +244,7 @@ irqreturn_t rtc_interrupt(int irq, void *dev_id) | |||
242 | * the last read in the remainder of rtc_irq_data. | 244 | * the last read in the remainder of rtc_irq_data. |
243 | */ | 245 | */ |
244 | 246 | ||
245 | spin_lock (&rtc_lock); | 247 | spin_lock(&rtc_lock); |
246 | rtc_irq_data += 0x100; | 248 | rtc_irq_data += 0x100; |
247 | rtc_irq_data &= ~0xff; | 249 | rtc_irq_data &= ~0xff; |
248 | if (is_hpet_enabled()) { | 250 | if (is_hpet_enabled()) { |
@@ -259,16 +261,16 @@ irqreturn_t rtc_interrupt(int irq, void *dev_id) | |||
259 | if (rtc_status & RTC_TIMER_ON) | 261 | if (rtc_status & RTC_TIMER_ON) |
260 | mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100); | 262 | mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100); |
261 | 263 | ||
262 | spin_unlock (&rtc_lock); | 264 | spin_unlock(&rtc_lock); |
263 | 265 | ||
264 | /* Now do the rest of the actions */ | 266 | /* Now do the rest of the actions */ |
265 | spin_lock(&rtc_task_lock); | 267 | spin_lock(&rtc_task_lock); |
266 | if (rtc_callback) | 268 | if (rtc_callback) |
267 | rtc_callback->func(rtc_callback->private_data); | 269 | rtc_callback->func(rtc_callback->private_data); |
268 | spin_unlock(&rtc_task_lock); | 270 | spin_unlock(&rtc_task_lock); |
269 | wake_up_interruptible(&rtc_wait); | 271 | wake_up_interruptible(&rtc_wait); |
270 | 272 | ||
271 | kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); | 273 | kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); |
272 | 274 | ||
273 | return IRQ_HANDLED; | 275 | return IRQ_HANDLED; |
274 | } | 276 | } |
@@ -335,7 +337,7 @@ static ssize_t rtc_read(struct file *file, char __user *buf, | |||
335 | DECLARE_WAITQUEUE(wait, current); | 337 | DECLARE_WAITQUEUE(wait, current); |
336 | unsigned long data; | 338 | unsigned long data; |
337 | ssize_t retval; | 339 | ssize_t retval; |
338 | 340 | ||
339 | if (rtc_has_irq == 0) | 341 | if (rtc_has_irq == 0) |
340 | return -EIO; | 342 | return -EIO; |
341 | 343 | ||
@@ -358,11 +360,11 @@ static ssize_t rtc_read(struct file *file, char __user *buf, | |||
358 | * confusing. And no, xchg() is not the answer. */ | 360 | * confusing. And no, xchg() is not the answer. */ |
359 | 361 | ||
360 | __set_current_state(TASK_INTERRUPTIBLE); | 362 | __set_current_state(TASK_INTERRUPTIBLE); |
361 | 363 | ||
362 | spin_lock_irq (&rtc_lock); | 364 | spin_lock_irq(&rtc_lock); |
363 | data = rtc_irq_data; | 365 | data = rtc_irq_data; |
364 | rtc_irq_data = 0; | 366 | rtc_irq_data = 0; |
365 | spin_unlock_irq (&rtc_lock); | 367 | spin_unlock_irq(&rtc_lock); |
366 | 368 | ||
367 | if (data != 0) | 369 | if (data != 0) |
368 | break; | 370 | break; |
@@ -378,10 +380,13 @@ static ssize_t rtc_read(struct file *file, char __user *buf, | |||
378 | schedule(); | 380 | schedule(); |
379 | } while (1); | 381 | } while (1); |
380 | 382 | ||
381 | if (count == sizeof(unsigned int)) | 383 | if (count == sizeof(unsigned int)) { |
382 | retval = put_user(data, (unsigned int __user *)buf) ?: sizeof(int); | 384 | retval = put_user(data, |
383 | else | 385 | (unsigned int __user *)buf) ?: sizeof(int); |
384 | retval = put_user(data, (unsigned long __user *)buf) ?: sizeof(long); | 386 | } else { |
387 | retval = put_user(data, | ||
388 | (unsigned long __user *)buf) ?: sizeof(long); | ||
389 | } | ||
385 | if (!retval) | 390 | if (!retval) |
386 | retval = count; | 391 | retval = count; |
387 | out: | 392 | out: |
@@ -394,7 +399,7 @@ static ssize_t rtc_read(struct file *file, char __user *buf, | |||
394 | 399 | ||
395 | static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | 400 | static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) |
396 | { | 401 | { |
397 | struct rtc_time wtime; | 402 | struct rtc_time wtime; |
398 | 403 | ||
399 | #ifdef RTC_IRQ | 404 | #ifdef RTC_IRQ |
400 | if (rtc_has_irq == 0) { | 405 | if (rtc_has_irq == 0) { |
@@ -426,35 +431,41 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
426 | } | 431 | } |
427 | case RTC_PIE_OFF: /* Mask periodic int. enab. bit */ | 432 | case RTC_PIE_OFF: /* Mask periodic int. enab. bit */ |
428 | { | 433 | { |
429 | unsigned long flags; /* can be called from isr via rtc_control() */ | 434 | /* can be called from isr via rtc_control() */ |
430 | spin_lock_irqsave (&rtc_lock, flags); | 435 | unsigned long flags; |
436 | |||
437 | spin_lock_irqsave(&rtc_lock, flags); | ||
431 | mask_rtc_irq_bit_locked(RTC_PIE); | 438 | mask_rtc_irq_bit_locked(RTC_PIE); |
432 | if (rtc_status & RTC_TIMER_ON) { | 439 | if (rtc_status & RTC_TIMER_ON) { |
433 | rtc_status &= ~RTC_TIMER_ON; | 440 | rtc_status &= ~RTC_TIMER_ON; |
434 | del_timer(&rtc_irq_timer); | 441 | del_timer(&rtc_irq_timer); |
435 | } | 442 | } |
436 | spin_unlock_irqrestore (&rtc_lock, flags); | 443 | spin_unlock_irqrestore(&rtc_lock, flags); |
444 | |||
437 | return 0; | 445 | return 0; |
438 | } | 446 | } |
439 | case RTC_PIE_ON: /* Allow periodic ints */ | 447 | case RTC_PIE_ON: /* Allow periodic ints */ |
440 | { | 448 | { |
441 | unsigned long flags; /* can be called from isr via rtc_control() */ | 449 | /* can be called from isr via rtc_control() */ |
450 | unsigned long flags; | ||
451 | |||
442 | /* | 452 | /* |
443 | * We don't really want Joe User enabling more | 453 | * We don't really want Joe User enabling more |
444 | * than 64Hz of interrupts on a multi-user machine. | 454 | * than 64Hz of interrupts on a multi-user machine. |
445 | */ | 455 | */ |
446 | if (!kernel && (rtc_freq > rtc_max_user_freq) && | 456 | if (!kernel && (rtc_freq > rtc_max_user_freq) && |
447 | (!capable(CAP_SYS_RESOURCE))) | 457 | (!capable(CAP_SYS_RESOURCE))) |
448 | return -EACCES; | 458 | return -EACCES; |
449 | 459 | ||
450 | spin_lock_irqsave (&rtc_lock, flags); | 460 | spin_lock_irqsave(&rtc_lock, flags); |
451 | if (!(rtc_status & RTC_TIMER_ON)) { | 461 | if (!(rtc_status & RTC_TIMER_ON)) { |
452 | mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + | 462 | mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + |
453 | 2*HZ/100); | 463 | 2*HZ/100); |
454 | rtc_status |= RTC_TIMER_ON; | 464 | rtc_status |= RTC_TIMER_ON; |
455 | } | 465 | } |
456 | set_rtc_irq_bit_locked(RTC_PIE); | 466 | set_rtc_irq_bit_locked(RTC_PIE); |
457 | spin_unlock_irqrestore (&rtc_lock, flags); | 467 | spin_unlock_irqrestore(&rtc_lock, flags); |
468 | |||
458 | return 0; | 469 | return 0; |
459 | } | 470 | } |
460 | case RTC_UIE_OFF: /* Mask ints from RTC updates. */ | 471 | case RTC_UIE_OFF: /* Mask ints from RTC updates. */ |
@@ -477,7 +488,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
477 | */ | 488 | */ |
478 | memset(&wtime, 0, sizeof(struct rtc_time)); | 489 | memset(&wtime, 0, sizeof(struct rtc_time)); |
479 | get_rtc_alm_time(&wtime); | 490 | get_rtc_alm_time(&wtime); |
480 | break; | 491 | break; |
481 | } | 492 | } |
482 | case RTC_ALM_SET: /* Store a time into the alarm */ | 493 | case RTC_ALM_SET: /* Store a time into the alarm */ |
483 | { | 494 | { |
@@ -505,16 +516,21 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
505 | */ | 516 | */ |
506 | } | 517 | } |
507 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || | 518 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || |
508 | RTC_ALWAYS_BCD) | 519 | RTC_ALWAYS_BCD) { |
509 | { | 520 | if (sec < 60) |
510 | if (sec < 60) BIN_TO_BCD(sec); | 521 | BIN_TO_BCD(sec); |
511 | else sec = 0xff; | 522 | else |
512 | 523 | sec = 0xff; | |
513 | if (min < 60) BIN_TO_BCD(min); | 524 | |
514 | else min = 0xff; | 525 | if (min < 60) |
515 | 526 | BIN_TO_BCD(min); | |
516 | if (hrs < 24) BIN_TO_BCD(hrs); | 527 | else |
517 | else hrs = 0xff; | 528 | min = 0xff; |
529 | |||
530 | if (hrs < 24) | ||
531 | BIN_TO_BCD(hrs); | ||
532 | else | ||
533 | hrs = 0xff; | ||
518 | } | 534 | } |
519 | CMOS_WRITE(hrs, RTC_HOURS_ALARM); | 535 | CMOS_WRITE(hrs, RTC_HOURS_ALARM); |
520 | CMOS_WRITE(min, RTC_MINUTES_ALARM); | 536 | CMOS_WRITE(min, RTC_MINUTES_ALARM); |
@@ -563,11 +579,12 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
563 | 579 | ||
564 | if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) | 580 | if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) |
565 | return -EINVAL; | 581 | return -EINVAL; |
566 | 582 | ||
567 | if ((hrs >= 24) || (min >= 60) || (sec >= 60)) | 583 | if ((hrs >= 24) || (min >= 60) || (sec >= 60)) |
568 | return -EINVAL; | 584 | return -EINVAL; |
569 | 585 | ||
570 | if ((yrs -= epoch) > 255) /* They are unsigned */ | 586 | yrs -= epoch; |
587 | if (yrs > 255) /* They are unsigned */ | ||
571 | return -EINVAL; | 588 | return -EINVAL; |
572 | 589 | ||
573 | spin_lock_irq(&rtc_lock); | 590 | spin_lock_irq(&rtc_lock); |
@@ -635,9 +652,10 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
635 | { | 652 | { |
636 | int tmp = 0; | 653 | int tmp = 0; |
637 | unsigned char val; | 654 | unsigned char val; |
638 | unsigned long flags; /* can be called from isr via rtc_control() */ | 655 | /* can be called from isr via rtc_control() */ |
656 | unsigned long flags; | ||
639 | 657 | ||
640 | /* | 658 | /* |
641 | * The max we can do is 8192Hz. | 659 | * The max we can do is 8192Hz. |
642 | */ | 660 | */ |
643 | if ((arg < 2) || (arg > 8192)) | 661 | if ((arg < 2) || (arg > 8192)) |
@@ -646,7 +664,8 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
646 | * We don't really want Joe User generating more | 664 | * We don't really want Joe User generating more |
647 | * than 64Hz of interrupts on a multi-user machine. | 665 | * than 64Hz of interrupts on a multi-user machine. |
648 | */ | 666 | */ |
649 | if (!kernel && (arg > rtc_max_user_freq) && (!capable(CAP_SYS_RESOURCE))) | 667 | if (!kernel && (arg > rtc_max_user_freq) && |
668 | !capable(CAP_SYS_RESOURCE)) | ||
650 | return -EACCES; | 669 | return -EACCES; |
651 | 670 | ||
652 | while (arg > (1<<tmp)) | 671 | while (arg > (1<<tmp)) |
@@ -674,11 +693,11 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
674 | #endif | 693 | #endif |
675 | case RTC_EPOCH_READ: /* Read the epoch. */ | 694 | case RTC_EPOCH_READ: /* Read the epoch. */ |
676 | { | 695 | { |
677 | return put_user (epoch, (unsigned long __user *)arg); | 696 | return put_user(epoch, (unsigned long __user *)arg); |
678 | } | 697 | } |
679 | case RTC_EPOCH_SET: /* Set the epoch. */ | 698 | case RTC_EPOCH_SET: /* Set the epoch. */ |
680 | { | 699 | { |
681 | /* | 700 | /* |
682 | * There were no RTC clocks before 1900. | 701 | * There were no RTC clocks before 1900. |
683 | */ | 702 | */ |
684 | if (arg < 1900) | 703 | if (arg < 1900) |
@@ -693,7 +712,8 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
693 | default: | 712 | default: |
694 | return -ENOTTY; | 713 | return -ENOTTY; |
695 | } | 714 | } |
696 | return copy_to_user((void __user *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; | 715 | return copy_to_user((void __user *)arg, |
716 | &wtime, sizeof wtime) ? -EFAULT : 0; | ||
697 | } | 717 | } |
698 | 718 | ||
699 | static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 719 | static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, |
@@ -712,26 +732,25 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
712 | * needed here. Or anywhere else in this driver. */ | 732 | * needed here. Or anywhere else in this driver. */ |
713 | static int rtc_open(struct inode *inode, struct file *file) | 733 | static int rtc_open(struct inode *inode, struct file *file) |
714 | { | 734 | { |
715 | spin_lock_irq (&rtc_lock); | 735 | spin_lock_irq(&rtc_lock); |
716 | 736 | ||
717 | if(rtc_status & RTC_IS_OPEN) | 737 | if (rtc_status & RTC_IS_OPEN) |
718 | goto out_busy; | 738 | goto out_busy; |
719 | 739 | ||
720 | rtc_status |= RTC_IS_OPEN; | 740 | rtc_status |= RTC_IS_OPEN; |
721 | 741 | ||
722 | rtc_irq_data = 0; | 742 | rtc_irq_data = 0; |
723 | spin_unlock_irq (&rtc_lock); | 743 | spin_unlock_irq(&rtc_lock); |
724 | return 0; | 744 | return 0; |
725 | 745 | ||
726 | out_busy: | 746 | out_busy: |
727 | spin_unlock_irq (&rtc_lock); | 747 | spin_unlock_irq(&rtc_lock); |
728 | return -EBUSY; | 748 | return -EBUSY; |
729 | } | 749 | } |
730 | 750 | ||
731 | static int rtc_fasync (int fd, struct file *filp, int on) | 751 | static int rtc_fasync(int fd, struct file *filp, int on) |
732 | |||
733 | { | 752 | { |
734 | return fasync_helper (fd, filp, on, &rtc_async_queue); | 753 | return fasync_helper(fd, filp, on, &rtc_async_queue); |
735 | } | 754 | } |
736 | 755 | ||
737 | static int rtc_release(struct inode *inode, struct file *file) | 756 | static int rtc_release(struct inode *inode, struct file *file) |
@@ -762,16 +781,16 @@ static int rtc_release(struct inode *inode, struct file *file) | |||
762 | } | 781 | } |
763 | spin_unlock_irq(&rtc_lock); | 782 | spin_unlock_irq(&rtc_lock); |
764 | 783 | ||
765 | if (file->f_flags & FASYNC) { | 784 | if (file->f_flags & FASYNC) |
766 | rtc_fasync (-1, file, 0); | 785 | rtc_fasync(-1, file, 0); |
767 | } | ||
768 | no_irq: | 786 | no_irq: |
769 | #endif | 787 | #endif |
770 | 788 | ||
771 | spin_lock_irq (&rtc_lock); | 789 | spin_lock_irq(&rtc_lock); |
772 | rtc_irq_data = 0; | 790 | rtc_irq_data = 0; |
773 | rtc_status &= ~RTC_IS_OPEN; | 791 | rtc_status &= ~RTC_IS_OPEN; |
774 | spin_unlock_irq (&rtc_lock); | 792 | spin_unlock_irq(&rtc_lock); |
793 | |||
775 | return 0; | 794 | return 0; |
776 | } | 795 | } |
777 | 796 | ||
@@ -786,9 +805,9 @@ static unsigned int rtc_poll(struct file *file, poll_table *wait) | |||
786 | 805 | ||
787 | poll_wait(file, &rtc_wait, wait); | 806 | poll_wait(file, &rtc_wait, wait); |
788 | 807 | ||
789 | spin_lock_irq (&rtc_lock); | 808 | spin_lock_irq(&rtc_lock); |
790 | l = rtc_irq_data; | 809 | l = rtc_irq_data; |
791 | spin_unlock_irq (&rtc_lock); | 810 | spin_unlock_irq(&rtc_lock); |
792 | 811 | ||
793 | if (l != 0) | 812 | if (l != 0) |
794 | return POLLIN | POLLRDNORM; | 813 | return POLLIN | POLLRDNORM; |
@@ -796,14 +815,6 @@ static unsigned int rtc_poll(struct file *file, poll_table *wait) | |||
796 | } | 815 | } |
797 | #endif | 816 | #endif |
798 | 817 | ||
799 | /* | ||
800 | * exported stuffs | ||
801 | */ | ||
802 | |||
803 | EXPORT_SYMBOL(rtc_register); | ||
804 | EXPORT_SYMBOL(rtc_unregister); | ||
805 | EXPORT_SYMBOL(rtc_control); | ||
806 | |||
807 | int rtc_register(rtc_task_t *task) | 818 | int rtc_register(rtc_task_t *task) |
808 | { | 819 | { |
809 | #ifndef RTC_IRQ | 820 | #ifndef RTC_IRQ |
@@ -829,6 +840,7 @@ int rtc_register(rtc_task_t *task) | |||
829 | return 0; | 840 | return 0; |
830 | #endif | 841 | #endif |
831 | } | 842 | } |
843 | EXPORT_SYMBOL(rtc_register); | ||
832 | 844 | ||
833 | int rtc_unregister(rtc_task_t *task) | 845 | int rtc_unregister(rtc_task_t *task) |
834 | { | 846 | { |
@@ -845,7 +857,7 @@ int rtc_unregister(rtc_task_t *task) | |||
845 | return -ENXIO; | 857 | return -ENXIO; |
846 | } | 858 | } |
847 | rtc_callback = NULL; | 859 | rtc_callback = NULL; |
848 | 860 | ||
849 | /* disable controls */ | 861 | /* disable controls */ |
850 | if (!hpet_mask_rtc_irq_bit(RTC_PIE | RTC_AIE | RTC_UIE)) { | 862 | if (!hpet_mask_rtc_irq_bit(RTC_PIE | RTC_AIE | RTC_UIE)) { |
851 | tmp = CMOS_READ(RTC_CONTROL); | 863 | tmp = CMOS_READ(RTC_CONTROL); |
@@ -865,6 +877,7 @@ int rtc_unregister(rtc_task_t *task) | |||
865 | return 0; | 877 | return 0; |
866 | #endif | 878 | #endif |
867 | } | 879 | } |
880 | EXPORT_SYMBOL(rtc_unregister); | ||
868 | 881 | ||
869 | int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg) | 882 | int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg) |
870 | { | 883 | { |
@@ -883,7 +896,7 @@ int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg) | |||
883 | return rtc_do_ioctl(cmd, arg, 1); | 896 | return rtc_do_ioctl(cmd, arg, 1); |
884 | #endif | 897 | #endif |
885 | } | 898 | } |
886 | 899 | EXPORT_SYMBOL(rtc_control); | |
887 | 900 | ||
888 | /* | 901 | /* |
889 | * The various file operations we support. | 902 | * The various file operations we support. |
@@ -910,11 +923,11 @@ static struct miscdevice rtc_dev = { | |||
910 | 923 | ||
911 | #ifdef CONFIG_PROC_FS | 924 | #ifdef CONFIG_PROC_FS |
912 | static const struct file_operations rtc_proc_fops = { | 925 | static const struct file_operations rtc_proc_fops = { |
913 | .owner = THIS_MODULE, | 926 | .owner = THIS_MODULE, |
914 | .open = rtc_proc_open, | 927 | .open = rtc_proc_open, |
915 | .read = seq_read, | 928 | .read = seq_read, |
916 | .llseek = seq_lseek, | 929 | .llseek = seq_lseek, |
917 | .release = single_release, | 930 | .release = single_release, |
918 | }; | 931 | }; |
919 | #endif | 932 | #endif |
920 | 933 | ||
@@ -965,7 +978,7 @@ static int __init rtc_init(void) | |||
965 | #ifdef CONFIG_SPARC32 | 978 | #ifdef CONFIG_SPARC32 |
966 | for_each_ebus(ebus) { | 979 | for_each_ebus(ebus) { |
967 | for_each_ebusdev(edev, ebus) { | 980 | for_each_ebusdev(edev, ebus) { |
968 | if(strcmp(edev->prom_node->name, "rtc") == 0) { | 981 | if (strcmp(edev->prom_node->name, "rtc") == 0) { |
969 | rtc_port = edev->resource[0].start; | 982 | rtc_port = edev->resource[0].start; |
970 | rtc_irq = edev->irqs[0]; | 983 | rtc_irq = edev->irqs[0]; |
971 | goto found; | 984 | goto found; |
@@ -986,7 +999,8 @@ found: | |||
986 | * XXX Interrupt pin #7 in Espresso is shared between RTC and | 999 | * XXX Interrupt pin #7 in Espresso is shared between RTC and |
987 | * PCI Slot 2 INTA# (and some INTx# in Slot 1). | 1000 | * PCI Slot 2 INTA# (and some INTx# in Slot 1). |
988 | */ | 1001 | */ |
989 | if (request_irq(rtc_irq, rtc_interrupt, IRQF_SHARED, "rtc", (void *)&rtc_port)) { | 1002 | if (request_irq(rtc_irq, rtc_interrupt, IRQF_SHARED, "rtc", |
1003 | (void *)&rtc_port)) { | ||
990 | rtc_has_irq = 0; | 1004 | rtc_has_irq = 0; |
991 | printk(KERN_ERR "rtc: cannot register IRQ %d\n", rtc_irq); | 1005 | printk(KERN_ERR "rtc: cannot register IRQ %d\n", rtc_irq); |
992 | return -EIO; | 1006 | return -EIO; |
@@ -1015,16 +1029,26 @@ no_irq: | |||
1015 | 1029 | ||
1016 | #ifdef RTC_IRQ | 1030 | #ifdef RTC_IRQ |
1017 | if (is_hpet_enabled()) { | 1031 | if (is_hpet_enabled()) { |
1032 | int err; | ||
1033 | |||
1018 | rtc_int_handler_ptr = hpet_rtc_interrupt; | 1034 | rtc_int_handler_ptr = hpet_rtc_interrupt; |
1035 | err = hpet_register_irq_handler(rtc_interrupt); | ||
1036 | if (err != 0) { | ||
1037 | printk(KERN_WARNING "hpet_register_irq_handler failed " | ||
1038 | "in rtc_init()."); | ||
1039 | return err; | ||
1040 | } | ||
1019 | } else { | 1041 | } else { |
1020 | rtc_int_handler_ptr = rtc_interrupt; | 1042 | rtc_int_handler_ptr = rtc_interrupt; |
1021 | } | 1043 | } |
1022 | 1044 | ||
1023 | if(request_irq(RTC_IRQ, rtc_int_handler_ptr, IRQF_DISABLED, "rtc", NULL)) { | 1045 | if (request_irq(RTC_IRQ, rtc_int_handler_ptr, IRQF_DISABLED, |
1046 | "rtc", NULL)) { | ||
1024 | /* Yeah right, seeing as irq 8 doesn't even hit the bus. */ | 1047 | /* Yeah right, seeing as irq 8 doesn't even hit the bus. */ |
1025 | rtc_has_irq = 0; | 1048 | rtc_has_irq = 0; |
1026 | printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ); | 1049 | printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ); |
1027 | rtc_release_region(); | 1050 | rtc_release_region(); |
1051 | |||
1028 | return -EIO; | 1052 | return -EIO; |
1029 | } | 1053 | } |
1030 | hpet_rtc_timer_init(); | 1054 | hpet_rtc_timer_init(); |
@@ -1036,6 +1060,7 @@ no_irq: | |||
1036 | if (misc_register(&rtc_dev)) { | 1060 | if (misc_register(&rtc_dev)) { |
1037 | #ifdef RTC_IRQ | 1061 | #ifdef RTC_IRQ |
1038 | free_irq(RTC_IRQ, NULL); | 1062 | free_irq(RTC_IRQ, NULL); |
1063 | hpet_unregister_irq_handler(rtc_interrupt); | ||
1039 | rtc_has_irq = 0; | 1064 | rtc_has_irq = 0; |
1040 | #endif | 1065 | #endif |
1041 | rtc_release_region(); | 1066 | rtc_release_region(); |
@@ -1052,21 +1077,21 @@ no_irq: | |||
1052 | 1077 | ||
1053 | #if defined(__alpha__) || defined(__mips__) | 1078 | #if defined(__alpha__) || defined(__mips__) |
1054 | rtc_freq = HZ; | 1079 | rtc_freq = HZ; |
1055 | 1080 | ||
1056 | /* Each operating system on an Alpha uses its own epoch. | 1081 | /* Each operating system on an Alpha uses its own epoch. |
1057 | Let's try to guess which one we are using now. */ | 1082 | Let's try to guess which one we are using now. */ |
1058 | 1083 | ||
1059 | if (rtc_is_updating() != 0) | 1084 | if (rtc_is_updating() != 0) |
1060 | msleep(20); | 1085 | msleep(20); |
1061 | 1086 | ||
1062 | spin_lock_irq(&rtc_lock); | 1087 | spin_lock_irq(&rtc_lock); |
1063 | year = CMOS_READ(RTC_YEAR); | 1088 | year = CMOS_READ(RTC_YEAR); |
1064 | ctrl = CMOS_READ(RTC_CONTROL); | 1089 | ctrl = CMOS_READ(RTC_CONTROL); |
1065 | spin_unlock_irq(&rtc_lock); | 1090 | spin_unlock_irq(&rtc_lock); |
1066 | 1091 | ||
1067 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | 1092 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) |
1068 | BCD_TO_BIN(year); /* This should never happen... */ | 1093 | BCD_TO_BIN(year); /* This should never happen... */ |
1069 | 1094 | ||
1070 | if (year < 20) { | 1095 | if (year < 20) { |
1071 | epoch = 2000; | 1096 | epoch = 2000; |
1072 | guess = "SRM (post-2000)"; | 1097 | guess = "SRM (post-2000)"; |
@@ -1087,7 +1112,8 @@ no_irq: | |||
1087 | #endif | 1112 | #endif |
1088 | } | 1113 | } |
1089 | if (guess) | 1114 | if (guess) |
1090 | printk(KERN_INFO "rtc: %s epoch (%lu) detected\n", guess, epoch); | 1115 | printk(KERN_INFO "rtc: %s epoch (%lu) detected\n", |
1116 | guess, epoch); | ||
1091 | #endif | 1117 | #endif |
1092 | #ifdef RTC_IRQ | 1118 | #ifdef RTC_IRQ |
1093 | if (rtc_has_irq == 0) | 1119 | if (rtc_has_irq == 0) |
@@ -1096,8 +1122,12 @@ no_irq: | |||
1096 | spin_lock_irq(&rtc_lock); | 1122 | spin_lock_irq(&rtc_lock); |
1097 | rtc_freq = 1024; | 1123 | rtc_freq = 1024; |
1098 | if (!hpet_set_periodic_freq(rtc_freq)) { | 1124 | if (!hpet_set_periodic_freq(rtc_freq)) { |
1099 | /* Initialize periodic freq. to CMOS reset default, which is 1024Hz */ | 1125 | /* |
1100 | CMOS_WRITE(((CMOS_READ(RTC_FREQ_SELECT) & 0xF0) | 0x06), RTC_FREQ_SELECT); | 1126 | * Initialize periodic frequency to CMOS reset default, |
1127 | * which is 1024Hz | ||
1128 | */ | ||
1129 | CMOS_WRITE(((CMOS_READ(RTC_FREQ_SELECT) & 0xF0) | 0x06), | ||
1130 | RTC_FREQ_SELECT); | ||
1101 | } | 1131 | } |
1102 | spin_unlock_irq(&rtc_lock); | 1132 | spin_unlock_irq(&rtc_lock); |
1103 | no_irq2: | 1133 | no_irq2: |
@@ -1110,20 +1140,22 @@ no_irq2: | |||
1110 | return 0; | 1140 | return 0; |
1111 | } | 1141 | } |
1112 | 1142 | ||
1113 | static void __exit rtc_exit (void) | 1143 | static void __exit rtc_exit(void) |
1114 | { | 1144 | { |
1115 | cleanup_sysctl(); | 1145 | cleanup_sysctl(); |
1116 | remove_proc_entry ("driver/rtc", NULL); | 1146 | remove_proc_entry("driver/rtc", NULL); |
1117 | misc_deregister(&rtc_dev); | 1147 | misc_deregister(&rtc_dev); |
1118 | 1148 | ||
1119 | #ifdef CONFIG_SPARC32 | 1149 | #ifdef CONFIG_SPARC32 |
1120 | if (rtc_has_irq) | 1150 | if (rtc_has_irq) |
1121 | free_irq (rtc_irq, &rtc_port); | 1151 | free_irq(rtc_irq, &rtc_port); |
1122 | #else | 1152 | #else |
1123 | rtc_release_region(); | 1153 | rtc_release_region(); |
1124 | #ifdef RTC_IRQ | 1154 | #ifdef RTC_IRQ |
1125 | if (rtc_has_irq) | 1155 | if (rtc_has_irq) { |
1126 | free_irq (RTC_IRQ, NULL); | 1156 | free_irq(RTC_IRQ, NULL); |
1157 | hpet_unregister_irq_handler(hpet_rtc_interrupt); | ||
1158 | } | ||
1127 | #endif | 1159 | #endif |
1128 | #endif /* CONFIG_SPARC32 */ | 1160 | #endif /* CONFIG_SPARC32 */ |
1129 | } | 1161 | } |
@@ -1133,14 +1165,14 @@ module_exit(rtc_exit); | |||
1133 | 1165 | ||
1134 | #ifdef RTC_IRQ | 1166 | #ifdef RTC_IRQ |
1135 | /* | 1167 | /* |
1136 | * At IRQ rates >= 4096Hz, an interrupt may get lost altogether. | 1168 | * At IRQ rates >= 4096Hz, an interrupt may get lost altogether. |
1137 | * (usually during an IDE disk interrupt, with IRQ unmasking off) | 1169 | * (usually during an IDE disk interrupt, with IRQ unmasking off) |
1138 | * Since the interrupt handler doesn't get called, the IRQ status | 1170 | * Since the interrupt handler doesn't get called, the IRQ status |
1139 | * byte doesn't get read, and the RTC stops generating interrupts. | 1171 | * byte doesn't get read, and the RTC stops generating interrupts. |
1140 | * A timer is set, and will call this function if/when that happens. | 1172 | * A timer is set, and will call this function if/when that happens. |
1141 | * To get it out of this stalled state, we just read the status. | 1173 | * To get it out of this stalled state, we just read the status. |
1142 | * At least a jiffy of interrupts (rtc_freq/HZ) will have been lost. | 1174 | * At least a jiffy of interrupts (rtc_freq/HZ) will have been lost. |
1143 | * (You *really* shouldn't be trying to use a non-realtime system | 1175 | * (You *really* shouldn't be trying to use a non-realtime system |
1144 | * for something that requires a steady > 1KHz signal anyways.) | 1176 | * for something that requires a steady > 1KHz signal anyways.) |
1145 | */ | 1177 | */ |
1146 | 1178 | ||
@@ -1148,7 +1180,7 @@ static void rtc_dropped_irq(unsigned long data) | |||
1148 | { | 1180 | { |
1149 | unsigned long freq; | 1181 | unsigned long freq; |
1150 | 1182 | ||
1151 | spin_lock_irq (&rtc_lock); | 1183 | spin_lock_irq(&rtc_lock); |
1152 | 1184 | ||
1153 | if (hpet_rtc_dropped_irq()) { | 1185 | if (hpet_rtc_dropped_irq()) { |
1154 | spin_unlock_irq(&rtc_lock); | 1186 | spin_unlock_irq(&rtc_lock); |
@@ -1167,13 +1199,15 @@ static void rtc_dropped_irq(unsigned long data) | |||
1167 | 1199 | ||
1168 | spin_unlock_irq(&rtc_lock); | 1200 | spin_unlock_irq(&rtc_lock); |
1169 | 1201 | ||
1170 | if (printk_ratelimit()) | 1202 | if (printk_ratelimit()) { |
1171 | printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n", freq); | 1203 | printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n", |
1204 | freq); | ||
1205 | } | ||
1172 | 1206 | ||
1173 | /* Now we have new data */ | 1207 | /* Now we have new data */ |
1174 | wake_up_interruptible(&rtc_wait); | 1208 | wake_up_interruptible(&rtc_wait); |
1175 | 1209 | ||
1176 | kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); | 1210 | kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); |
1177 | } | 1211 | } |
1178 | #endif | 1212 | #endif |
1179 | 1213 | ||
@@ -1277,7 +1311,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) | |||
1277 | * can take just over 2ms. We wait 20ms. There is no need to | 1311 | * can take just over 2ms. We wait 20ms. There is no need to |
1278 | * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. | 1312 | * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. |
1279 | * If you need to know *exactly* when a second has started, enable | 1313 | * If you need to know *exactly* when a second has started, enable |
1280 | * periodic update complete interrupts, (via ioctl) and then | 1314 | * periodic update complete interrupts, (via ioctl) and then |
1281 | * immediately read /dev/rtc which will block until you get the IRQ. | 1315 | * immediately read /dev/rtc which will block until you get the IRQ. |
1282 | * Once the read clears, read the RTC time (again via ioctl). Easy. | 1316 | * Once the read clears, read the RTC time (again via ioctl). Easy. |
1283 | */ | 1317 | */ |
@@ -1307,8 +1341,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) | |||
1307 | ctrl = CMOS_READ(RTC_CONTROL); | 1341 | ctrl = CMOS_READ(RTC_CONTROL); |
1308 | spin_unlock_irqrestore(&rtc_lock, flags); | 1342 | spin_unlock_irqrestore(&rtc_lock, flags); |
1309 | 1343 | ||
1310 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | 1344 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
1311 | { | ||
1312 | BCD_TO_BIN(rtc_tm->tm_sec); | 1345 | BCD_TO_BIN(rtc_tm->tm_sec); |
1313 | BCD_TO_BIN(rtc_tm->tm_min); | 1346 | BCD_TO_BIN(rtc_tm->tm_min); |
1314 | BCD_TO_BIN(rtc_tm->tm_hour); | 1347 | BCD_TO_BIN(rtc_tm->tm_hour); |
@@ -1326,7 +1359,8 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) | |||
1326 | * Account for differences between how the RTC uses the values | 1359 | * Account for differences between how the RTC uses the values |
1327 | * and how they are defined in a struct rtc_time; | 1360 | * and how they are defined in a struct rtc_time; |
1328 | */ | 1361 | */ |
1329 | if ((rtc_tm->tm_year += (epoch - 1900)) <= 69) | 1362 | rtc_tm->tm_year += epoch - 1900; |
1363 | if (rtc_tm->tm_year <= 69) | ||
1330 | rtc_tm->tm_year += 100; | 1364 | rtc_tm->tm_year += 100; |
1331 | 1365 | ||
1332 | rtc_tm->tm_mon--; | 1366 | rtc_tm->tm_mon--; |
@@ -1347,8 +1381,7 @@ static void get_rtc_alm_time(struct rtc_time *alm_tm) | |||
1347 | ctrl = CMOS_READ(RTC_CONTROL); | 1381 | ctrl = CMOS_READ(RTC_CONTROL); |
1348 | spin_unlock_irq(&rtc_lock); | 1382 | spin_unlock_irq(&rtc_lock); |
1349 | 1383 | ||
1350 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | 1384 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
1351 | { | ||
1352 | BCD_TO_BIN(alm_tm->tm_sec); | 1385 | BCD_TO_BIN(alm_tm->tm_sec); |
1353 | BCD_TO_BIN(alm_tm->tm_min); | 1386 | BCD_TO_BIN(alm_tm->tm_min); |
1354 | BCD_TO_BIN(alm_tm->tm_hour); | 1387 | BCD_TO_BIN(alm_tm->tm_hour); |