diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:31:09 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:31:09 -0500 |
commit | 5fd1fe9c582e00ca0a98f852cd693dc3caf607a0 (patch) | |
tree | f7965a80e784b659568dbd41e9773e812e550880 /drivers/char | |
parent | 6b4b05bd790389962e6fcfc862562e7fa239c9d2 (diff) |
x86: clean up drivers/char/rtc.c
tons of style cleanup in drivers/char/rtc.c - no code changed:
text data bss dec hex filename
6400 384 32 6816 1aa0 rtc.o.before
6400 384 32 6816 1aa0 rtc.o.after
since we seem to have a number of open breakages in this code we might
as well start with making the code more readable and maintainable.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/rtc.c | 238 |
1 files changed, 129 insertions, 109 deletions
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index 0c66b802736a..3ac7952fe086 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,12 @@ 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 | #ifdef RTC_IRQ | 113 | #ifdef RTC_IRQ |
114 | static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) | 114 | static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) |
115 | { | 115 | { |
@@ -147,7 +147,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, | |||
147 | static unsigned int rtc_poll(struct file *file, poll_table *wait); | 147 | static unsigned int rtc_poll(struct file *file, poll_table *wait); |
148 | #endif | 148 | #endif |
149 | 149 | ||
150 | static void get_rtc_alm_time (struct rtc_time *alm_tm); | 150 | static void get_rtc_alm_time(struct rtc_time *alm_tm); |
151 | #ifdef RTC_IRQ | 151 | #ifdef RTC_IRQ |
152 | static void set_rtc_irq_bit_locked(unsigned char bit); | 152 | static void set_rtc_irq_bit_locked(unsigned char bit); |
153 | static void mask_rtc_irq_bit_locked(unsigned char bit); | 153 | static void mask_rtc_irq_bit_locked(unsigned char bit); |
@@ -185,9 +185,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 | 185 | * 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) | 186 | * timer (but you would need to have an awful timing before you'd trip on it) |
187 | */ | 187 | */ |
188 | static unsigned long rtc_status = 0; /* bitmapped status byte. */ | 188 | static unsigned long rtc_status; /* bitmapped status byte. */ |
189 | static unsigned long rtc_freq = 0; /* Current periodic IRQ rate */ | 189 | static unsigned long rtc_freq; /* Current periodic IRQ rate */ |
190 | static unsigned long rtc_irq_data = 0; /* our output to the world */ | 190 | 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 */ | 191 | static unsigned long rtc_max_user_freq = 64; /* > this, need CAP_SYS_RESOURCE */ |
192 | 192 | ||
193 | #ifdef RTC_IRQ | 193 | #ifdef RTC_IRQ |
@@ -195,7 +195,7 @@ static unsigned long rtc_max_user_freq = 64; /* > this, need CAP_SYS_RESOURCE */ | |||
195 | * rtc_task_lock nests inside rtc_lock. | 195 | * rtc_task_lock nests inside rtc_lock. |
196 | */ | 196 | */ |
197 | static DEFINE_SPINLOCK(rtc_task_lock); | 197 | static DEFINE_SPINLOCK(rtc_task_lock); |
198 | static rtc_task_t *rtc_callback = NULL; | 198 | static rtc_task_t *rtc_callback; |
199 | #endif | 199 | #endif |
200 | 200 | ||
201 | /* | 201 | /* |
@@ -205,7 +205,7 @@ static rtc_task_t *rtc_callback = NULL; | |||
205 | 205 | ||
206 | static unsigned long epoch = 1900; /* year corresponding to 0x00 */ | 206 | static unsigned long epoch = 1900; /* year corresponding to 0x00 */ |
207 | 207 | ||
208 | static const unsigned char days_in_mo[] = | 208 | static const unsigned char days_in_mo[] = |
209 | {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; | 209 | {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; |
210 | 210 | ||
211 | /* | 211 | /* |
@@ -242,7 +242,7 @@ irqreturn_t rtc_interrupt(int irq, void *dev_id) | |||
242 | * the last read in the remainder of rtc_irq_data. | 242 | * the last read in the remainder of rtc_irq_data. |
243 | */ | 243 | */ |
244 | 244 | ||
245 | spin_lock (&rtc_lock); | 245 | spin_lock(&rtc_lock); |
246 | rtc_irq_data += 0x100; | 246 | rtc_irq_data += 0x100; |
247 | rtc_irq_data &= ~0xff; | 247 | rtc_irq_data &= ~0xff; |
248 | if (is_hpet_enabled()) { | 248 | if (is_hpet_enabled()) { |
@@ -259,16 +259,16 @@ irqreturn_t rtc_interrupt(int irq, void *dev_id) | |||
259 | if (rtc_status & RTC_TIMER_ON) | 259 | if (rtc_status & RTC_TIMER_ON) |
260 | mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100); | 260 | mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100); |
261 | 261 | ||
262 | spin_unlock (&rtc_lock); | 262 | spin_unlock(&rtc_lock); |
263 | 263 | ||
264 | /* Now do the rest of the actions */ | 264 | /* Now do the rest of the actions */ |
265 | spin_lock(&rtc_task_lock); | 265 | spin_lock(&rtc_task_lock); |
266 | if (rtc_callback) | 266 | if (rtc_callback) |
267 | rtc_callback->func(rtc_callback->private_data); | 267 | rtc_callback->func(rtc_callback->private_data); |
268 | spin_unlock(&rtc_task_lock); | 268 | spin_unlock(&rtc_task_lock); |
269 | wake_up_interruptible(&rtc_wait); | 269 | wake_up_interruptible(&rtc_wait); |
270 | 270 | ||
271 | kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); | 271 | kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); |
272 | 272 | ||
273 | return IRQ_HANDLED; | 273 | return IRQ_HANDLED; |
274 | } | 274 | } |
@@ -335,7 +335,7 @@ static ssize_t rtc_read(struct file *file, char __user *buf, | |||
335 | DECLARE_WAITQUEUE(wait, current); | 335 | DECLARE_WAITQUEUE(wait, current); |
336 | unsigned long data; | 336 | unsigned long data; |
337 | ssize_t retval; | 337 | ssize_t retval; |
338 | 338 | ||
339 | if (rtc_has_irq == 0) | 339 | if (rtc_has_irq == 0) |
340 | return -EIO; | 340 | return -EIO; |
341 | 341 | ||
@@ -358,11 +358,11 @@ static ssize_t rtc_read(struct file *file, char __user *buf, | |||
358 | * confusing. And no, xchg() is not the answer. */ | 358 | * confusing. And no, xchg() is not the answer. */ |
359 | 359 | ||
360 | __set_current_state(TASK_INTERRUPTIBLE); | 360 | __set_current_state(TASK_INTERRUPTIBLE); |
361 | 361 | ||
362 | spin_lock_irq (&rtc_lock); | 362 | spin_lock_irq(&rtc_lock); |
363 | data = rtc_irq_data; | 363 | data = rtc_irq_data; |
364 | rtc_irq_data = 0; | 364 | rtc_irq_data = 0; |
365 | spin_unlock_irq (&rtc_lock); | 365 | spin_unlock_irq(&rtc_lock); |
366 | 366 | ||
367 | if (data != 0) | 367 | if (data != 0) |
368 | break; | 368 | break; |
@@ -378,10 +378,13 @@ static ssize_t rtc_read(struct file *file, char __user *buf, | |||
378 | schedule(); | 378 | schedule(); |
379 | } while (1); | 379 | } while (1); |
380 | 380 | ||
381 | if (count == sizeof(unsigned int)) | 381 | if (count == sizeof(unsigned int)) { |
382 | retval = put_user(data, (unsigned int __user *)buf) ?: sizeof(int); | 382 | retval = put_user(data, |
383 | else | 383 | (unsigned int __user *)buf) ?: sizeof(int); |
384 | retval = put_user(data, (unsigned long __user *)buf) ?: sizeof(long); | 384 | } else { |
385 | retval = put_user(data, | ||
386 | (unsigned long __user *)buf) ?: sizeof(long); | ||
387 | } | ||
385 | if (!retval) | 388 | if (!retval) |
386 | retval = count; | 389 | retval = count; |
387 | out: | 390 | out: |
@@ -394,7 +397,7 @@ static ssize_t rtc_read(struct file *file, char __user *buf, | |||
394 | 397 | ||
395 | static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | 398 | static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) |
396 | { | 399 | { |
397 | struct rtc_time wtime; | 400 | struct rtc_time wtime; |
398 | 401 | ||
399 | #ifdef RTC_IRQ | 402 | #ifdef RTC_IRQ |
400 | if (rtc_has_irq == 0) { | 403 | if (rtc_has_irq == 0) { |
@@ -426,35 +429,41 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
426 | } | 429 | } |
427 | case RTC_PIE_OFF: /* Mask periodic int. enab. bit */ | 430 | case RTC_PIE_OFF: /* Mask periodic int. enab. bit */ |
428 | { | 431 | { |
429 | unsigned long flags; /* can be called from isr via rtc_control() */ | 432 | /* can be called from isr via rtc_control() */ |
430 | spin_lock_irqsave (&rtc_lock, flags); | 433 | unsigned long flags; |
434 | |||
435 | spin_lock_irqsave(&rtc_lock, flags); | ||
431 | mask_rtc_irq_bit_locked(RTC_PIE); | 436 | mask_rtc_irq_bit_locked(RTC_PIE); |
432 | if (rtc_status & RTC_TIMER_ON) { | 437 | if (rtc_status & RTC_TIMER_ON) { |
433 | rtc_status &= ~RTC_TIMER_ON; | 438 | rtc_status &= ~RTC_TIMER_ON; |
434 | del_timer(&rtc_irq_timer); | 439 | del_timer(&rtc_irq_timer); |
435 | } | 440 | } |
436 | spin_unlock_irqrestore (&rtc_lock, flags); | 441 | spin_unlock_irqrestore(&rtc_lock, flags); |
442 | |||
437 | return 0; | 443 | return 0; |
438 | } | 444 | } |
439 | case RTC_PIE_ON: /* Allow periodic ints */ | 445 | case RTC_PIE_ON: /* Allow periodic ints */ |
440 | { | 446 | { |
441 | unsigned long flags; /* can be called from isr via rtc_control() */ | 447 | /* can be called from isr via rtc_control() */ |
448 | unsigned long flags; | ||
449 | |||
442 | /* | 450 | /* |
443 | * We don't really want Joe User enabling more | 451 | * We don't really want Joe User enabling more |
444 | * than 64Hz of interrupts on a multi-user machine. | 452 | * than 64Hz of interrupts on a multi-user machine. |
445 | */ | 453 | */ |
446 | if (!kernel && (rtc_freq > rtc_max_user_freq) && | 454 | if (!kernel && (rtc_freq > rtc_max_user_freq) && |
447 | (!capable(CAP_SYS_RESOURCE))) | 455 | (!capable(CAP_SYS_RESOURCE))) |
448 | return -EACCES; | 456 | return -EACCES; |
449 | 457 | ||
450 | spin_lock_irqsave (&rtc_lock, flags); | 458 | spin_lock_irqsave(&rtc_lock, flags); |
451 | if (!(rtc_status & RTC_TIMER_ON)) { | 459 | if (!(rtc_status & RTC_TIMER_ON)) { |
452 | mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + | 460 | mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + |
453 | 2*HZ/100); | 461 | 2*HZ/100); |
454 | rtc_status |= RTC_TIMER_ON; | 462 | rtc_status |= RTC_TIMER_ON; |
455 | } | 463 | } |
456 | set_rtc_irq_bit_locked(RTC_PIE); | 464 | set_rtc_irq_bit_locked(RTC_PIE); |
457 | spin_unlock_irqrestore (&rtc_lock, flags); | 465 | spin_unlock_irqrestore(&rtc_lock, flags); |
466 | |||
458 | return 0; | 467 | return 0; |
459 | } | 468 | } |
460 | case RTC_UIE_OFF: /* Mask ints from RTC updates. */ | 469 | case RTC_UIE_OFF: /* Mask ints from RTC updates. */ |
@@ -477,7 +486,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
477 | */ | 486 | */ |
478 | memset(&wtime, 0, sizeof(struct rtc_time)); | 487 | memset(&wtime, 0, sizeof(struct rtc_time)); |
479 | get_rtc_alm_time(&wtime); | 488 | get_rtc_alm_time(&wtime); |
480 | break; | 489 | break; |
481 | } | 490 | } |
482 | case RTC_ALM_SET: /* Store a time into the alarm */ | 491 | case RTC_ALM_SET: /* Store a time into the alarm */ |
483 | { | 492 | { |
@@ -505,16 +514,21 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
505 | */ | 514 | */ |
506 | } | 515 | } |
507 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || | 516 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || |
508 | RTC_ALWAYS_BCD) | 517 | RTC_ALWAYS_BCD) { |
509 | { | 518 | if (sec < 60) |
510 | if (sec < 60) BIN_TO_BCD(sec); | 519 | BIN_TO_BCD(sec); |
511 | else sec = 0xff; | 520 | else |
512 | 521 | sec = 0xff; | |
513 | if (min < 60) BIN_TO_BCD(min); | 522 | |
514 | else min = 0xff; | 523 | if (min < 60) |
515 | 524 | BIN_TO_BCD(min); | |
516 | if (hrs < 24) BIN_TO_BCD(hrs); | 525 | else |
517 | else hrs = 0xff; | 526 | min = 0xff; |
527 | |||
528 | if (hrs < 24) | ||
529 | BIN_TO_BCD(hrs); | ||
530 | else | ||
531 | hrs = 0xff; | ||
518 | } | 532 | } |
519 | CMOS_WRITE(hrs, RTC_HOURS_ALARM); | 533 | CMOS_WRITE(hrs, RTC_HOURS_ALARM); |
520 | CMOS_WRITE(min, RTC_MINUTES_ALARM); | 534 | CMOS_WRITE(min, RTC_MINUTES_ALARM); |
@@ -563,11 +577,12 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
563 | 577 | ||
564 | if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) | 578 | if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) |
565 | return -EINVAL; | 579 | return -EINVAL; |
566 | 580 | ||
567 | if ((hrs >= 24) || (min >= 60) || (sec >= 60)) | 581 | if ((hrs >= 24) || (min >= 60) || (sec >= 60)) |
568 | return -EINVAL; | 582 | return -EINVAL; |
569 | 583 | ||
570 | if ((yrs -= epoch) > 255) /* They are unsigned */ | 584 | yrs -= epoch; |
585 | if (yrs > 255) /* They are unsigned */ | ||
571 | return -EINVAL; | 586 | return -EINVAL; |
572 | 587 | ||
573 | spin_lock_irq(&rtc_lock); | 588 | spin_lock_irq(&rtc_lock); |
@@ -635,9 +650,10 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
635 | { | 650 | { |
636 | int tmp = 0; | 651 | int tmp = 0; |
637 | unsigned char val; | 652 | unsigned char val; |
638 | unsigned long flags; /* can be called from isr via rtc_control() */ | 653 | /* can be called from isr via rtc_control() */ |
654 | unsigned long flags; | ||
639 | 655 | ||
640 | /* | 656 | /* |
641 | * The max we can do is 8192Hz. | 657 | * The max we can do is 8192Hz. |
642 | */ | 658 | */ |
643 | if ((arg < 2) || (arg > 8192)) | 659 | if ((arg < 2) || (arg > 8192)) |
@@ -646,7 +662,8 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
646 | * We don't really want Joe User generating more | 662 | * We don't really want Joe User generating more |
647 | * than 64Hz of interrupts on a multi-user machine. | 663 | * than 64Hz of interrupts on a multi-user machine. |
648 | */ | 664 | */ |
649 | if (!kernel && (arg > rtc_max_user_freq) && (!capable(CAP_SYS_RESOURCE))) | 665 | if (!kernel && (arg > rtc_max_user_freq) && |
666 | !capable(CAP_SYS_RESOURCE)) | ||
650 | return -EACCES; | 667 | return -EACCES; |
651 | 668 | ||
652 | while (arg > (1<<tmp)) | 669 | while (arg > (1<<tmp)) |
@@ -674,11 +691,11 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
674 | #endif | 691 | #endif |
675 | case RTC_EPOCH_READ: /* Read the epoch. */ | 692 | case RTC_EPOCH_READ: /* Read the epoch. */ |
676 | { | 693 | { |
677 | return put_user (epoch, (unsigned long __user *)arg); | 694 | return put_user(epoch, (unsigned long __user *)arg); |
678 | } | 695 | } |
679 | case RTC_EPOCH_SET: /* Set the epoch. */ | 696 | case RTC_EPOCH_SET: /* Set the epoch. */ |
680 | { | 697 | { |
681 | /* | 698 | /* |
682 | * There were no RTC clocks before 1900. | 699 | * There were no RTC clocks before 1900. |
683 | */ | 700 | */ |
684 | if (arg < 1900) | 701 | if (arg < 1900) |
@@ -693,7 +710,8 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
693 | default: | 710 | default: |
694 | return -ENOTTY; | 711 | return -ENOTTY; |
695 | } | 712 | } |
696 | return copy_to_user((void __user *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; | 713 | return copy_to_user((void __user *)arg, |
714 | &wtime, sizeof wtime) ? -EFAULT : 0; | ||
697 | } | 715 | } |
698 | 716 | ||
699 | static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 717 | static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, |
@@ -712,26 +730,25 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
712 | * needed here. Or anywhere else in this driver. */ | 730 | * needed here. Or anywhere else in this driver. */ |
713 | static int rtc_open(struct inode *inode, struct file *file) | 731 | static int rtc_open(struct inode *inode, struct file *file) |
714 | { | 732 | { |
715 | spin_lock_irq (&rtc_lock); | 733 | spin_lock_irq(&rtc_lock); |
716 | 734 | ||
717 | if(rtc_status & RTC_IS_OPEN) | 735 | if (rtc_status & RTC_IS_OPEN) |
718 | goto out_busy; | 736 | goto out_busy; |
719 | 737 | ||
720 | rtc_status |= RTC_IS_OPEN; | 738 | rtc_status |= RTC_IS_OPEN; |
721 | 739 | ||
722 | rtc_irq_data = 0; | 740 | rtc_irq_data = 0; |
723 | spin_unlock_irq (&rtc_lock); | 741 | spin_unlock_irq(&rtc_lock); |
724 | return 0; | 742 | return 0; |
725 | 743 | ||
726 | out_busy: | 744 | out_busy: |
727 | spin_unlock_irq (&rtc_lock); | 745 | spin_unlock_irq(&rtc_lock); |
728 | return -EBUSY; | 746 | return -EBUSY; |
729 | } | 747 | } |
730 | 748 | ||
731 | static int rtc_fasync (int fd, struct file *filp, int on) | 749 | static int rtc_fasync(int fd, struct file *filp, int on) |
732 | |||
733 | { | 750 | { |
734 | return fasync_helper (fd, filp, on, &rtc_async_queue); | 751 | return fasync_helper(fd, filp, on, &rtc_async_queue); |
735 | } | 752 | } |
736 | 753 | ||
737 | static int rtc_release(struct inode *inode, struct file *file) | 754 | static int rtc_release(struct inode *inode, struct file *file) |
@@ -762,16 +779,16 @@ static int rtc_release(struct inode *inode, struct file *file) | |||
762 | } | 779 | } |
763 | spin_unlock_irq(&rtc_lock); | 780 | spin_unlock_irq(&rtc_lock); |
764 | 781 | ||
765 | if (file->f_flags & FASYNC) { | 782 | if (file->f_flags & FASYNC) |
766 | rtc_fasync (-1, file, 0); | 783 | rtc_fasync(-1, file, 0); |
767 | } | ||
768 | no_irq: | 784 | no_irq: |
769 | #endif | 785 | #endif |
770 | 786 | ||
771 | spin_lock_irq (&rtc_lock); | 787 | spin_lock_irq(&rtc_lock); |
772 | rtc_irq_data = 0; | 788 | rtc_irq_data = 0; |
773 | rtc_status &= ~RTC_IS_OPEN; | 789 | rtc_status &= ~RTC_IS_OPEN; |
774 | spin_unlock_irq (&rtc_lock); | 790 | spin_unlock_irq(&rtc_lock); |
791 | |||
775 | return 0; | 792 | return 0; |
776 | } | 793 | } |
777 | 794 | ||
@@ -786,9 +803,9 @@ static unsigned int rtc_poll(struct file *file, poll_table *wait) | |||
786 | 803 | ||
787 | poll_wait(file, &rtc_wait, wait); | 804 | poll_wait(file, &rtc_wait, wait); |
788 | 805 | ||
789 | spin_lock_irq (&rtc_lock); | 806 | spin_lock_irq(&rtc_lock); |
790 | l = rtc_irq_data; | 807 | l = rtc_irq_data; |
791 | spin_unlock_irq (&rtc_lock); | 808 | spin_unlock_irq(&rtc_lock); |
792 | 809 | ||
793 | if (l != 0) | 810 | if (l != 0) |
794 | return POLLIN | POLLRDNORM; | 811 | return POLLIN | POLLRDNORM; |
@@ -796,14 +813,6 @@ static unsigned int rtc_poll(struct file *file, poll_table *wait) | |||
796 | } | 813 | } |
797 | #endif | 814 | #endif |
798 | 815 | ||
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) | 816 | int rtc_register(rtc_task_t *task) |
808 | { | 817 | { |
809 | #ifndef RTC_IRQ | 818 | #ifndef RTC_IRQ |
@@ -829,6 +838,7 @@ int rtc_register(rtc_task_t *task) | |||
829 | return 0; | 838 | return 0; |
830 | #endif | 839 | #endif |
831 | } | 840 | } |
841 | EXPORT_SYMBOL(rtc_register); | ||
832 | 842 | ||
833 | int rtc_unregister(rtc_task_t *task) | 843 | int rtc_unregister(rtc_task_t *task) |
834 | { | 844 | { |
@@ -845,7 +855,7 @@ int rtc_unregister(rtc_task_t *task) | |||
845 | return -ENXIO; | 855 | return -ENXIO; |
846 | } | 856 | } |
847 | rtc_callback = NULL; | 857 | rtc_callback = NULL; |
848 | 858 | ||
849 | /* disable controls */ | 859 | /* disable controls */ |
850 | if (!hpet_mask_rtc_irq_bit(RTC_PIE | RTC_AIE | RTC_UIE)) { | 860 | if (!hpet_mask_rtc_irq_bit(RTC_PIE | RTC_AIE | RTC_UIE)) { |
851 | tmp = CMOS_READ(RTC_CONTROL); | 861 | tmp = CMOS_READ(RTC_CONTROL); |
@@ -865,6 +875,7 @@ int rtc_unregister(rtc_task_t *task) | |||
865 | return 0; | 875 | return 0; |
866 | #endif | 876 | #endif |
867 | } | 877 | } |
878 | EXPORT_SYMBOL(rtc_unregister); | ||
868 | 879 | ||
869 | int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg) | 880 | int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg) |
870 | { | 881 | { |
@@ -883,7 +894,7 @@ int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg) | |||
883 | return rtc_do_ioctl(cmd, arg, 1); | 894 | return rtc_do_ioctl(cmd, arg, 1); |
884 | #endif | 895 | #endif |
885 | } | 896 | } |
886 | 897 | EXPORT_SYMBOL(rtc_control); | |
887 | 898 | ||
888 | /* | 899 | /* |
889 | * The various file operations we support. | 900 | * The various file operations we support. |
@@ -910,11 +921,11 @@ static struct miscdevice rtc_dev = { | |||
910 | 921 | ||
911 | #ifdef CONFIG_PROC_FS | 922 | #ifdef CONFIG_PROC_FS |
912 | static const struct file_operations rtc_proc_fops = { | 923 | static const struct file_operations rtc_proc_fops = { |
913 | .owner = THIS_MODULE, | 924 | .owner = THIS_MODULE, |
914 | .open = rtc_proc_open, | 925 | .open = rtc_proc_open, |
915 | .read = seq_read, | 926 | .read = seq_read, |
916 | .llseek = seq_lseek, | 927 | .llseek = seq_lseek, |
917 | .release = single_release, | 928 | .release = single_release, |
918 | }; | 929 | }; |
919 | #endif | 930 | #endif |
920 | 931 | ||
@@ -965,7 +976,7 @@ static int __init rtc_init(void) | |||
965 | #ifdef CONFIG_SPARC32 | 976 | #ifdef CONFIG_SPARC32 |
966 | for_each_ebus(ebus) { | 977 | for_each_ebus(ebus) { |
967 | for_each_ebusdev(edev, ebus) { | 978 | for_each_ebusdev(edev, ebus) { |
968 | if(strcmp(edev->prom_node->name, "rtc") == 0) { | 979 | if (strcmp(edev->prom_node->name, "rtc") == 0) { |
969 | rtc_port = edev->resource[0].start; | 980 | rtc_port = edev->resource[0].start; |
970 | rtc_irq = edev->irqs[0]; | 981 | rtc_irq = edev->irqs[0]; |
971 | goto found; | 982 | goto found; |
@@ -986,7 +997,8 @@ found: | |||
986 | * XXX Interrupt pin #7 in Espresso is shared between RTC and | 997 | * XXX Interrupt pin #7 in Espresso is shared between RTC and |
987 | * PCI Slot 2 INTA# (and some INTx# in Slot 1). | 998 | * PCI Slot 2 INTA# (and some INTx# in Slot 1). |
988 | */ | 999 | */ |
989 | if (request_irq(rtc_irq, rtc_interrupt, IRQF_SHARED, "rtc", (void *)&rtc_port)) { | 1000 | if (request_irq(rtc_irq, rtc_interrupt, IRQF_SHARED, "rtc", |
1001 | (void *)&rtc_port)) { | ||
990 | rtc_has_irq = 0; | 1002 | rtc_has_irq = 0; |
991 | printk(KERN_ERR "rtc: cannot register IRQ %d\n", rtc_irq); | 1003 | printk(KERN_ERR "rtc: cannot register IRQ %d\n", rtc_irq); |
992 | return -EIO; | 1004 | return -EIO; |
@@ -1020,11 +1032,13 @@ no_irq: | |||
1020 | rtc_int_handler_ptr = rtc_interrupt; | 1032 | rtc_int_handler_ptr = rtc_interrupt; |
1021 | } | 1033 | } |
1022 | 1034 | ||
1023 | if(request_irq(RTC_IRQ, rtc_int_handler_ptr, IRQF_DISABLED, "rtc", NULL)) { | 1035 | if (request_irq(RTC_IRQ, rtc_int_handler_ptr, IRQF_DISABLED, |
1036 | "rtc", NULL)) { | ||
1024 | /* Yeah right, seeing as irq 8 doesn't even hit the bus. */ | 1037 | /* Yeah right, seeing as irq 8 doesn't even hit the bus. */ |
1025 | rtc_has_irq = 0; | 1038 | rtc_has_irq = 0; |
1026 | printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ); | 1039 | printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ); |
1027 | rtc_release_region(); | 1040 | rtc_release_region(); |
1041 | |||
1028 | return -EIO; | 1042 | return -EIO; |
1029 | } | 1043 | } |
1030 | hpet_rtc_timer_init(); | 1044 | hpet_rtc_timer_init(); |
@@ -1052,21 +1066,21 @@ no_irq: | |||
1052 | 1066 | ||
1053 | #if defined(__alpha__) || defined(__mips__) | 1067 | #if defined(__alpha__) || defined(__mips__) |
1054 | rtc_freq = HZ; | 1068 | rtc_freq = HZ; |
1055 | 1069 | ||
1056 | /* Each operating system on an Alpha uses its own epoch. | 1070 | /* Each operating system on an Alpha uses its own epoch. |
1057 | Let's try to guess which one we are using now. */ | 1071 | Let's try to guess which one we are using now. */ |
1058 | 1072 | ||
1059 | if (rtc_is_updating() != 0) | 1073 | if (rtc_is_updating() != 0) |
1060 | msleep(20); | 1074 | msleep(20); |
1061 | 1075 | ||
1062 | spin_lock_irq(&rtc_lock); | 1076 | spin_lock_irq(&rtc_lock); |
1063 | year = CMOS_READ(RTC_YEAR); | 1077 | year = CMOS_READ(RTC_YEAR); |
1064 | ctrl = CMOS_READ(RTC_CONTROL); | 1078 | ctrl = CMOS_READ(RTC_CONTROL); |
1065 | spin_unlock_irq(&rtc_lock); | 1079 | spin_unlock_irq(&rtc_lock); |
1066 | 1080 | ||
1067 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | 1081 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) |
1068 | BCD_TO_BIN(year); /* This should never happen... */ | 1082 | BCD_TO_BIN(year); /* This should never happen... */ |
1069 | 1083 | ||
1070 | if (year < 20) { | 1084 | if (year < 20) { |
1071 | epoch = 2000; | 1085 | epoch = 2000; |
1072 | guess = "SRM (post-2000)"; | 1086 | guess = "SRM (post-2000)"; |
@@ -1087,7 +1101,8 @@ no_irq: | |||
1087 | #endif | 1101 | #endif |
1088 | } | 1102 | } |
1089 | if (guess) | 1103 | if (guess) |
1090 | printk(KERN_INFO "rtc: %s epoch (%lu) detected\n", guess, epoch); | 1104 | printk(KERN_INFO "rtc: %s epoch (%lu) detected\n", |
1105 | guess, epoch); | ||
1091 | #endif | 1106 | #endif |
1092 | #ifdef RTC_IRQ | 1107 | #ifdef RTC_IRQ |
1093 | if (rtc_has_irq == 0) | 1108 | if (rtc_has_irq == 0) |
@@ -1096,8 +1111,12 @@ no_irq: | |||
1096 | spin_lock_irq(&rtc_lock); | 1111 | spin_lock_irq(&rtc_lock); |
1097 | rtc_freq = 1024; | 1112 | rtc_freq = 1024; |
1098 | if (!hpet_set_periodic_freq(rtc_freq)) { | 1113 | if (!hpet_set_periodic_freq(rtc_freq)) { |
1099 | /* Initialize periodic freq. to CMOS reset default, which is 1024Hz */ | 1114 | /* |
1100 | CMOS_WRITE(((CMOS_READ(RTC_FREQ_SELECT) & 0xF0) | 0x06), RTC_FREQ_SELECT); | 1115 | * Initialize periodic frequency to CMOS reset default, |
1116 | * which is 1024Hz | ||
1117 | */ | ||
1118 | CMOS_WRITE(((CMOS_READ(RTC_FREQ_SELECT) & 0xF0) | 0x06), | ||
1119 | RTC_FREQ_SELECT); | ||
1101 | } | 1120 | } |
1102 | spin_unlock_irq(&rtc_lock); | 1121 | spin_unlock_irq(&rtc_lock); |
1103 | no_irq2: | 1122 | no_irq2: |
@@ -1110,20 +1129,20 @@ no_irq2: | |||
1110 | return 0; | 1129 | return 0; |
1111 | } | 1130 | } |
1112 | 1131 | ||
1113 | static void __exit rtc_exit (void) | 1132 | static void __exit rtc_exit(void) |
1114 | { | 1133 | { |
1115 | cleanup_sysctl(); | 1134 | cleanup_sysctl(); |
1116 | remove_proc_entry ("driver/rtc", NULL); | 1135 | remove_proc_entry("driver/rtc", NULL); |
1117 | misc_deregister(&rtc_dev); | 1136 | misc_deregister(&rtc_dev); |
1118 | 1137 | ||
1119 | #ifdef CONFIG_SPARC32 | 1138 | #ifdef CONFIG_SPARC32 |
1120 | if (rtc_has_irq) | 1139 | if (rtc_has_irq) |
1121 | free_irq (rtc_irq, &rtc_port); | 1140 | free_irq(rtc_irq, &rtc_port); |
1122 | #else | 1141 | #else |
1123 | rtc_release_region(); | 1142 | rtc_release_region(); |
1124 | #ifdef RTC_IRQ | 1143 | #ifdef RTC_IRQ |
1125 | if (rtc_has_irq) | 1144 | if (rtc_has_irq) |
1126 | free_irq (RTC_IRQ, NULL); | 1145 | free_irq(RTC_IRQ, NULL); |
1127 | #endif | 1146 | #endif |
1128 | #endif /* CONFIG_SPARC32 */ | 1147 | #endif /* CONFIG_SPARC32 */ |
1129 | } | 1148 | } |
@@ -1133,14 +1152,14 @@ module_exit(rtc_exit); | |||
1133 | 1152 | ||
1134 | #ifdef RTC_IRQ | 1153 | #ifdef RTC_IRQ |
1135 | /* | 1154 | /* |
1136 | * At IRQ rates >= 4096Hz, an interrupt may get lost altogether. | 1155 | * At IRQ rates >= 4096Hz, an interrupt may get lost altogether. |
1137 | * (usually during an IDE disk interrupt, with IRQ unmasking off) | 1156 | * (usually during an IDE disk interrupt, with IRQ unmasking off) |
1138 | * Since the interrupt handler doesn't get called, the IRQ status | 1157 | * Since the interrupt handler doesn't get called, the IRQ status |
1139 | * byte doesn't get read, and the RTC stops generating interrupts. | 1158 | * 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. | 1159 | * 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. | 1160 | * 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. | 1161 | * 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 | 1162 | * (You *really* shouldn't be trying to use a non-realtime system |
1144 | * for something that requires a steady > 1KHz signal anyways.) | 1163 | * for something that requires a steady > 1KHz signal anyways.) |
1145 | */ | 1164 | */ |
1146 | 1165 | ||
@@ -1148,7 +1167,7 @@ static void rtc_dropped_irq(unsigned long data) | |||
1148 | { | 1167 | { |
1149 | unsigned long freq; | 1168 | unsigned long freq; |
1150 | 1169 | ||
1151 | spin_lock_irq (&rtc_lock); | 1170 | spin_lock_irq(&rtc_lock); |
1152 | 1171 | ||
1153 | if (hpet_rtc_dropped_irq()) { | 1172 | if (hpet_rtc_dropped_irq()) { |
1154 | spin_unlock_irq(&rtc_lock); | 1173 | spin_unlock_irq(&rtc_lock); |
@@ -1167,13 +1186,15 @@ static void rtc_dropped_irq(unsigned long data) | |||
1167 | 1186 | ||
1168 | spin_unlock_irq(&rtc_lock); | 1187 | spin_unlock_irq(&rtc_lock); |
1169 | 1188 | ||
1170 | if (printk_ratelimit()) | 1189 | if (printk_ratelimit()) { |
1171 | printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n", freq); | 1190 | printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n", |
1191 | freq); | ||
1192 | } | ||
1172 | 1193 | ||
1173 | /* Now we have new data */ | 1194 | /* Now we have new data */ |
1174 | wake_up_interruptible(&rtc_wait); | 1195 | wake_up_interruptible(&rtc_wait); |
1175 | 1196 | ||
1176 | kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); | 1197 | kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); |
1177 | } | 1198 | } |
1178 | #endif | 1199 | #endif |
1179 | 1200 | ||
@@ -1277,7 +1298,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 | 1298 | * 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. | 1299 | * 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 | 1300 | * If you need to know *exactly* when a second has started, enable |
1280 | * periodic update complete interrupts, (via ioctl) and then | 1301 | * periodic update complete interrupts, (via ioctl) and then |
1281 | * immediately read /dev/rtc which will block until you get the IRQ. | 1302 | * 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. | 1303 | * Once the read clears, read the RTC time (again via ioctl). Easy. |
1283 | */ | 1304 | */ |
@@ -1307,8 +1328,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) | |||
1307 | ctrl = CMOS_READ(RTC_CONTROL); | 1328 | ctrl = CMOS_READ(RTC_CONTROL); |
1308 | spin_unlock_irqrestore(&rtc_lock, flags); | 1329 | spin_unlock_irqrestore(&rtc_lock, flags); |
1309 | 1330 | ||
1310 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | 1331 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
1311 | { | ||
1312 | BCD_TO_BIN(rtc_tm->tm_sec); | 1332 | BCD_TO_BIN(rtc_tm->tm_sec); |
1313 | BCD_TO_BIN(rtc_tm->tm_min); | 1333 | BCD_TO_BIN(rtc_tm->tm_min); |
1314 | BCD_TO_BIN(rtc_tm->tm_hour); | 1334 | BCD_TO_BIN(rtc_tm->tm_hour); |
@@ -1326,7 +1346,8 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) | |||
1326 | * Account for differences between how the RTC uses the values | 1346 | * Account for differences between how the RTC uses the values |
1327 | * and how they are defined in a struct rtc_time; | 1347 | * and how they are defined in a struct rtc_time; |
1328 | */ | 1348 | */ |
1329 | if ((rtc_tm->tm_year += (epoch - 1900)) <= 69) | 1349 | rtc_tm->tm_year += epoch - 1900; |
1350 | if (rtc_tm->tm_year <= 69) | ||
1330 | rtc_tm->tm_year += 100; | 1351 | rtc_tm->tm_year += 100; |
1331 | 1352 | ||
1332 | rtc_tm->tm_mon--; | 1353 | rtc_tm->tm_mon--; |
@@ -1347,8 +1368,7 @@ static void get_rtc_alm_time(struct rtc_time *alm_tm) | |||
1347 | ctrl = CMOS_READ(RTC_CONTROL); | 1368 | ctrl = CMOS_READ(RTC_CONTROL); |
1348 | spin_unlock_irq(&rtc_lock); | 1369 | spin_unlock_irq(&rtc_lock); |
1349 | 1370 | ||
1350 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | 1371 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
1351 | { | ||
1352 | BCD_TO_BIN(alm_tm->tm_sec); | 1372 | BCD_TO_BIN(alm_tm->tm_sec); |
1353 | BCD_TO_BIN(alm_tm->tm_min); | 1373 | BCD_TO_BIN(alm_tm->tm_min); |
1354 | BCD_TO_BIN(alm_tm->tm_hour); | 1374 | BCD_TO_BIN(alm_tm->tm_hour); |