diff options
Diffstat (limited to 'drivers/char/rtc.c')
-rw-r--r-- | drivers/char/rtc.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index 5f80a9dff573..d9799e2bcfbf 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
@@ -73,13 +73,15 @@ | |||
73 | #include <linux/proc_fs.h> | 73 | #include <linux/proc_fs.h> |
74 | #include <linux/seq_file.h> | 74 | #include <linux/seq_file.h> |
75 | #include <linux/spinlock.h> | 75 | #include <linux/spinlock.h> |
76 | #include <linux/smp_lock.h> | ||
76 | #include <linux/sysctl.h> | 77 | #include <linux/sysctl.h> |
77 | #include <linux/wait.h> | 78 | #include <linux/wait.h> |
78 | #include <linux/bcd.h> | 79 | #include <linux/bcd.h> |
79 | #include <linux/delay.h> | 80 | #include <linux/delay.h> |
81 | #include <linux/smp_lock.h> | ||
82 | #include <linux/uaccess.h> | ||
80 | 83 | ||
81 | #include <asm/current.h> | 84 | #include <asm/current.h> |
82 | #include <asm/uaccess.h> | ||
83 | #include <asm/system.h> | 85 | #include <asm/system.h> |
84 | 86 | ||
85 | #ifdef CONFIG_X86 | 87 | #ifdef CONFIG_X86 |
@@ -119,8 +121,6 @@ static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) | |||
119 | return 0; | 121 | return 0; |
120 | } | 122 | } |
121 | #endif | 123 | #endif |
122 | #else | ||
123 | extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id); | ||
124 | #endif | 124 | #endif |
125 | 125 | ||
126 | /* | 126 | /* |
@@ -143,8 +143,8 @@ static DEFINE_TIMER(rtc_irq_timer, rtc_dropped_irq, 0, 0); | |||
143 | static ssize_t rtc_read(struct file *file, char __user *buf, | 143 | static ssize_t rtc_read(struct file *file, char __user *buf, |
144 | size_t count, loff_t *ppos); | 144 | size_t count, loff_t *ppos); |
145 | 145 | ||
146 | static int rtc_ioctl(struct inode *inode, struct file *file, | 146 | static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
147 | unsigned int cmd, unsigned long arg); | 147 | static void rtc_get_rtc_time(struct rtc_time *rtc_tm); |
148 | 148 | ||
149 | #ifdef RTC_IRQ | 149 | #ifdef RTC_IRQ |
150 | static unsigned int rtc_poll(struct file *file, poll_table *wait); | 150 | static unsigned int rtc_poll(struct file *file, poll_table *wait); |
@@ -236,7 +236,7 @@ static inline unsigned char rtc_is_updating(void) | |||
236 | * (See ./arch/XXXX/kernel/time.c for the set_rtc_mmss() function.) | 236 | * (See ./arch/XXXX/kernel/time.c for the set_rtc_mmss() function.) |
237 | */ | 237 | */ |
238 | 238 | ||
239 | irqreturn_t rtc_interrupt(int irq, void *dev_id) | 239 | static irqreturn_t rtc_interrupt(int irq, void *dev_id) |
240 | { | 240 | { |
241 | /* | 241 | /* |
242 | * Can be an alarm interrupt, update complete interrupt, | 242 | * Can be an alarm interrupt, update complete interrupt, |
@@ -678,12 +678,13 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
678 | if (arg != (1<<tmp)) | 678 | if (arg != (1<<tmp)) |
679 | return -EINVAL; | 679 | return -EINVAL; |
680 | 680 | ||
681 | rtc_freq = arg; | ||
682 | |||
681 | spin_lock_irqsave(&rtc_lock, flags); | 683 | spin_lock_irqsave(&rtc_lock, flags); |
682 | if (hpet_set_periodic_freq(arg)) { | 684 | if (hpet_set_periodic_freq(arg)) { |
683 | spin_unlock_irqrestore(&rtc_lock, flags); | 685 | spin_unlock_irqrestore(&rtc_lock, flags); |
684 | return 0; | 686 | return 0; |
685 | } | 687 | } |
686 | rtc_freq = arg; | ||
687 | 688 | ||
688 | val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0; | 689 | val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0; |
689 | val |= (16 - tmp); | 690 | val |= (16 - tmp); |
@@ -717,10 +718,13 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
717 | &wtime, sizeof wtime) ? -EFAULT : 0; | 718 | &wtime, sizeof wtime) ? -EFAULT : 0; |
718 | } | 719 | } |
719 | 720 | ||
720 | static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 721 | static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
721 | unsigned long arg) | ||
722 | { | 722 | { |
723 | return rtc_do_ioctl(cmd, arg, 0); | 723 | long ret; |
724 | lock_kernel(); | ||
725 | ret = rtc_do_ioctl(cmd, arg, 0); | ||
726 | unlock_kernel(); | ||
727 | return ret; | ||
724 | } | 728 | } |
725 | 729 | ||
726 | /* | 730 | /* |
@@ -733,6 +737,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
733 | * needed here. Or anywhere else in this driver. */ | 737 | * needed here. Or anywhere else in this driver. */ |
734 | static int rtc_open(struct inode *inode, struct file *file) | 738 | static int rtc_open(struct inode *inode, struct file *file) |
735 | { | 739 | { |
740 | lock_kernel(); | ||
736 | spin_lock_irq(&rtc_lock); | 741 | spin_lock_irq(&rtc_lock); |
737 | 742 | ||
738 | if (rtc_status & RTC_IS_OPEN) | 743 | if (rtc_status & RTC_IS_OPEN) |
@@ -742,10 +747,12 @@ static int rtc_open(struct inode *inode, struct file *file) | |||
742 | 747 | ||
743 | rtc_irq_data = 0; | 748 | rtc_irq_data = 0; |
744 | spin_unlock_irq(&rtc_lock); | 749 | spin_unlock_irq(&rtc_lock); |
750 | unlock_kernel(); | ||
745 | return 0; | 751 | return 0; |
746 | 752 | ||
747 | out_busy: | 753 | out_busy: |
748 | spin_unlock_irq(&rtc_lock); | 754 | spin_unlock_irq(&rtc_lock); |
755 | unlock_kernel(); | ||
749 | return -EBUSY; | 756 | return -EBUSY; |
750 | } | 757 | } |
751 | 758 | ||
@@ -910,7 +917,7 @@ static const struct file_operations rtc_fops = { | |||
910 | #ifdef RTC_IRQ | 917 | #ifdef RTC_IRQ |
911 | .poll = rtc_poll, | 918 | .poll = rtc_poll, |
912 | #endif | 919 | #endif |
913 | .ioctl = rtc_ioctl, | 920 | .unlocked_ioctl = rtc_ioctl, |
914 | .open = rtc_open, | 921 | .open = rtc_open, |
915 | .release = rtc_release, | 922 | .release = rtc_release, |
916 | .fasync = rtc_fasync, | 923 | .fasync = rtc_fasync, |
@@ -1297,7 +1304,7 @@ static int rtc_proc_open(struct inode *inode, struct file *file) | |||
1297 | } | 1304 | } |
1298 | #endif | 1305 | #endif |
1299 | 1306 | ||
1300 | void rtc_get_rtc_time(struct rtc_time *rtc_tm) | 1307 | static void rtc_get_rtc_time(struct rtc_time *rtc_tm) |
1301 | { | 1308 | { |
1302 | unsigned long uip_watchdog = jiffies, flags; | 1309 | unsigned long uip_watchdog = jiffies, flags; |
1303 | unsigned char ctrl; | 1310 | unsigned char ctrl; |