aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-dev.c')
-rw-r--r--drivers/rtc/rtc-dev.c105
1 files changed, 1 insertions, 104 deletions
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 8a11de9552cd..212b16edafc0 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/rtc.h> 15#include <linux/rtc.h>
16#include <linux/sched.h>
16#include "rtc-core.h" 17#include "rtc-core.h"
17 18
18static dev_t rtc_devt; 19static dev_t rtc_devt;
@@ -45,105 +46,6 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
45 return err; 46 return err;
46} 47}
47 48
48#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
49/*
50 * Routine to poll RTC seconds field for change as often as possible,
51 * after first RTC_UIE use timer to reduce polling
52 */
53static void rtc_uie_task(struct work_struct *work)
54{
55 struct rtc_device *rtc =
56 container_of(work, struct rtc_device, uie_task);
57 struct rtc_time tm;
58 int num = 0;
59 int err;
60
61 err = rtc_read_time(rtc, &tm);
62
63 spin_lock_irq(&rtc->irq_lock);
64 if (rtc->stop_uie_polling || err) {
65 rtc->uie_task_active = 0;
66 } else if (rtc->oldsecs != tm.tm_sec) {
67 num = (tm.tm_sec + 60 - rtc->oldsecs) % 60;
68 rtc->oldsecs = tm.tm_sec;
69 rtc->uie_timer.expires = jiffies + HZ - (HZ/10);
70 rtc->uie_timer_active = 1;
71 rtc->uie_task_active = 0;
72 add_timer(&rtc->uie_timer);
73 } else if (schedule_work(&rtc->uie_task) == 0) {
74 rtc->uie_task_active = 0;
75 }
76 spin_unlock_irq(&rtc->irq_lock);
77 if (num)
78 rtc_update_irq(rtc, num, RTC_UF | RTC_IRQF);
79}
80static void rtc_uie_timer(unsigned long data)
81{
82 struct rtc_device *rtc = (struct rtc_device *)data;
83 unsigned long flags;
84
85 spin_lock_irqsave(&rtc->irq_lock, flags);
86 rtc->uie_timer_active = 0;
87 rtc->uie_task_active = 1;
88 if ((schedule_work(&rtc->uie_task) == 0))
89 rtc->uie_task_active = 0;
90 spin_unlock_irqrestore(&rtc->irq_lock, flags);
91}
92
93static int clear_uie(struct rtc_device *rtc)
94{
95 spin_lock_irq(&rtc->irq_lock);
96 if (rtc->uie_irq_active) {
97 rtc->stop_uie_polling = 1;
98 if (rtc->uie_timer_active) {
99 spin_unlock_irq(&rtc->irq_lock);
100 del_timer_sync(&rtc->uie_timer);
101 spin_lock_irq(&rtc->irq_lock);
102 rtc->uie_timer_active = 0;
103 }
104 if (rtc->uie_task_active) {
105 spin_unlock_irq(&rtc->irq_lock);
106 flush_scheduled_work();
107 spin_lock_irq(&rtc->irq_lock);
108 }
109 rtc->uie_irq_active = 0;
110 }
111 spin_unlock_irq(&rtc->irq_lock);
112 return 0;
113}
114
115static int set_uie(struct rtc_device *rtc)
116{
117 struct rtc_time tm;
118 int err;
119
120 err = rtc_read_time(rtc, &tm);
121 if (err)
122 return err;
123 spin_lock_irq(&rtc->irq_lock);
124 if (!rtc->uie_irq_active) {
125 rtc->uie_irq_active = 1;
126 rtc->stop_uie_polling = 0;
127 rtc->oldsecs = tm.tm_sec;
128 rtc->uie_task_active = 1;
129 if (schedule_work(&rtc->uie_task) == 0)
130 rtc->uie_task_active = 0;
131 }
132 rtc->irq_data = 0;
133 spin_unlock_irq(&rtc->irq_lock);
134 return 0;
135}
136
137int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, unsigned int enabled)
138{
139 if (enabled)
140 return set_uie(rtc);
141 else
142 return clear_uie(rtc);
143}
144EXPORT_SYMBOL(rtc_dev_update_irq_enable_emul);
145
146#endif /* CONFIG_RTC_INTF_DEV_UIE_EMUL */
147 49
148static ssize_t 50static ssize_t
149rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 51rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
@@ -492,11 +394,6 @@ void rtc_dev_prepare(struct rtc_device *rtc)
492 394
493 rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id); 395 rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id);
494 396
495#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
496 INIT_WORK(&rtc->uie_task, rtc_uie_task);
497 setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc);
498#endif
499
500 cdev_init(&rtc->char_dev, &rtc_dev_fops); 397 cdev_init(&rtc->char_dev, &rtc_dev_fops);
501 rtc->char_dev.owner = rtc->owner; 398 rtc->char_dev.owner = rtc->owner;
502} 399}