aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/interface.c16
-rw-r--r--drivers/rtc/rtc-at91.c3
-rw-r--r--drivers/rtc/rtc-dev.c25
-rw-r--r--drivers/rtc/rtc-ds1553.c3
-rw-r--r--drivers/rtc/rtc-max6902.c2
-rw-r--r--drivers/rtc/rtc-rs5c372.c6
-rw-r--r--drivers/rtc/rtc-test.c2
-rw-r--r--drivers/rtc/rtc-v3020.c4
8 files changed, 43 insertions, 18 deletions
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 579cd667b16f..6f11f6dfdd9d 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -145,6 +145,13 @@ int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm)
145} 145}
146EXPORT_SYMBOL_GPL(rtc_set_alarm); 146EXPORT_SYMBOL_GPL(rtc_set_alarm);
147 147
148/**
149 * rtc_update_irq - report RTC periodic, alarm, and/or update irqs
150 * @class_dev: the rtc's class device
151 * @num: how many irqs are being reported (usually one)
152 * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF
153 * Context: in_interrupt(), irqs blocked
154 */
148void rtc_update_irq(struct class_device *class_dev, 155void rtc_update_irq(struct class_device *class_dev,
149 unsigned long num, unsigned long events) 156 unsigned long num, unsigned long events)
150{ 157{
@@ -201,12 +208,12 @@ int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task)
201 if (task == NULL || task->func == NULL) 208 if (task == NULL || task->func == NULL)
202 return -EINVAL; 209 return -EINVAL;
203 210
204 spin_lock(&rtc->irq_task_lock); 211 spin_lock_irq(&rtc->irq_task_lock);
205 if (rtc->irq_task == NULL) { 212 if (rtc->irq_task == NULL) {
206 rtc->irq_task = task; 213 rtc->irq_task = task;
207 retval = 0; 214 retval = 0;
208 } 215 }
209 spin_unlock(&rtc->irq_task_lock); 216 spin_unlock_irq(&rtc->irq_task_lock);
210 217
211 return retval; 218 return retval;
212} 219}
@@ -216,10 +223,10 @@ void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task)
216{ 223{
217 struct rtc_device *rtc = to_rtc_device(class_dev); 224 struct rtc_device *rtc = to_rtc_device(class_dev);
218 225
219 spin_lock(&rtc->irq_task_lock); 226 spin_lock_irq(&rtc->irq_task_lock);
220 if (rtc->irq_task == task) 227 if (rtc->irq_task == task)
221 rtc->irq_task = NULL; 228 rtc->irq_task = NULL;
222 spin_unlock(&rtc->irq_task_lock); 229 spin_unlock_irq(&rtc->irq_task_lock);
223} 230}
224EXPORT_SYMBOL_GPL(rtc_irq_unregister); 231EXPORT_SYMBOL_GPL(rtc_irq_unregister);
225 232
@@ -265,3 +272,4 @@ int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int
265 } 272 }
266 return err; 273 return err;
267} 274}
275EXPORT_SYMBOL_GPL(rtc_irq_set_freq);
diff --git a/drivers/rtc/rtc-at91.c b/drivers/rtc/rtc-at91.c
index bd61e99540a3..5c8addcaf1fb 100644
--- a/drivers/rtc/rtc-at91.c
+++ b/drivers/rtc/rtc-at91.c
@@ -292,7 +292,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
292 AT91_RTC_CALEV); 292 AT91_RTC_CALEV);
293 293
294 ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, 294 ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt,
295 IRQF_SHARED, "at91_rtc", pdev); 295 IRQF_DISABLED | IRQF_SHARED,
296 "at91_rtc", pdev);
296 if (ret) { 297 if (ret) {
297 printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n", 298 printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n",
298 AT91_ID_SYS); 299 AT91_ID_SYS);
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 583789c66cdb..814b9e1873f5 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -61,7 +61,9 @@ static void rtc_uie_task(void *data)
61 int err; 61 int err;
62 62
63 err = rtc_read_time(&rtc->class_dev, &tm); 63 err = rtc_read_time(&rtc->class_dev, &tm);
64 spin_lock_irq(&rtc->irq_lock); 64
65 local_irq_disable();
66 spin_lock(&rtc->irq_lock);
65 if (rtc->stop_uie_polling || err) { 67 if (rtc->stop_uie_polling || err) {
66 rtc->uie_task_active = 0; 68 rtc->uie_task_active = 0;
67 } else if (rtc->oldsecs != tm.tm_sec) { 69 } else if (rtc->oldsecs != tm.tm_sec) {
@@ -74,11 +76,11 @@ static void rtc_uie_task(void *data)
74 } else if (schedule_work(&rtc->uie_task) == 0) { 76 } else if (schedule_work(&rtc->uie_task) == 0) {
75 rtc->uie_task_active = 0; 77 rtc->uie_task_active = 0;
76 } 78 }
77 spin_unlock_irq(&rtc->irq_lock); 79 spin_unlock(&rtc->irq_lock);
78 if (num) 80 if (num)
79 rtc_update_irq(&rtc->class_dev, num, RTC_UF | RTC_IRQF); 81 rtc_update_irq(&rtc->class_dev, num, RTC_UF | RTC_IRQF);
82 local_irq_enable();
80} 83}
81
82static void rtc_uie_timer(unsigned long data) 84static void rtc_uie_timer(unsigned long data)
83{ 85{
84 struct rtc_device *rtc = (struct rtc_device *)data; 86 struct rtc_device *rtc = (struct rtc_device *)data;
@@ -214,7 +216,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
214 struct rtc_wkalrm alarm; 216 struct rtc_wkalrm alarm;
215 void __user *uarg = (void __user *) arg; 217 void __user *uarg = (void __user *) arg;
216 218
217 /* check that the calles has appropriate permissions 219 /* check that the calling task has appropriate permissions
218 * for certain ioctls. doing this check here is useful 220 * for certain ioctls. doing this check here is useful
219 * to avoid duplicate code in each driver. 221 * to avoid duplicate code in each driver.
220 */ 222 */
@@ -238,10 +240,10 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
238 240
239 /* avoid conflicting IRQ users */ 241 /* avoid conflicting IRQ users */
240 if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) { 242 if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) {
241 spin_lock(&rtc->irq_task_lock); 243 spin_lock_irq(&rtc->irq_task_lock);
242 if (rtc->irq_task) 244 if (rtc->irq_task)
243 err = -EBUSY; 245 err = -EBUSY;
244 spin_unlock(&rtc->irq_task_lock); 246 spin_unlock_irq(&rtc->irq_task_lock);
245 247
246 if (err < 0) 248 if (err < 0)
247 return err; 249 return err;
@@ -299,6 +301,17 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
299 301
300 err = rtc_set_time(class_dev, &tm); 302 err = rtc_set_time(class_dev, &tm);
301 break; 303 break;
304
305 case RTC_IRQP_READ:
306 if (ops->irq_set_freq)
307 err = put_user(rtc->irq_freq, (unsigned long *) arg);
308 break;
309
310 case RTC_IRQP_SET:
311 if (ops->irq_set_freq)
312 err = rtc_irq_set_freq(class_dev, rtc->irq_task, arg);
313 break;
314
302#if 0 315#if 0
303 case RTC_EPOCH_SET: 316 case RTC_EPOCH_SET:
304#ifndef rtc_epoch 317#ifndef rtc_epoch
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index 78552e6e76aa..001eb1123a65 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -340,7 +340,8 @@ static int __init ds1553_rtc_probe(struct platform_device *pdev)
340 340
341 if (pdata->irq >= 0) { 341 if (pdata->irq >= 0) {
342 writeb(0, ioaddr + RTC_INTERRUPTS); 342 writeb(0, ioaddr + RTC_INTERRUPTS);
343 if (request_irq(pdata->irq, ds1553_rtc_interrupt, IRQF_SHARED, 343 if (request_irq(pdata->irq, ds1553_rtc_interrupt,
344 IRQF_DISABLED | IRQF_SHARED,
344 pdev->name, pdev) < 0) { 345 pdev->name, pdev) < 0) {
345 dev_warn(&pdev->dev, "interrupt not available.\n"); 346 dev_warn(&pdev->dev, "interrupt not available.\n");
346 pdata->irq = -1; 347 pdata->irq = -1;
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c
index 0b20dfacbf59..d94170728075 100644
--- a/drivers/rtc/rtc-max6902.c
+++ b/drivers/rtc/rtc-max6902.c
@@ -136,7 +136,7 @@ static int max6902_get_datetime(struct device *dev, struct rtc_time *dt)
136 dt->tm_min = BCD2BIN(chip->buf[2]); 136 dt->tm_min = BCD2BIN(chip->buf[2]);
137 dt->tm_hour = BCD2BIN(chip->buf[3]); 137 dt->tm_hour = BCD2BIN(chip->buf[3]);
138 dt->tm_mday = BCD2BIN(chip->buf[4]); 138 dt->tm_mday = BCD2BIN(chip->buf[4]);
139 dt->tm_mon = BCD2BIN(chip->buf[5] - 1); 139 dt->tm_mon = BCD2BIN(chip->buf[5]) - 1;
140 dt->tm_wday = BCD2BIN(chip->buf[6]); 140 dt->tm_wday = BCD2BIN(chip->buf[6]);
141 dt->tm_year = BCD2BIN(chip->buf[7]); 141 dt->tm_year = BCD2BIN(chip->buf[7]);
142 142
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 2a86632580f1..a44fe4efa216 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -126,13 +126,13 @@ static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim)
126 return -EIO; 126 return -EIO;
127 } 127 }
128 128
129 dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, *trim);
130
131 if (osc) 129 if (osc)
132 *osc = (buf & RS5C372_TRIM_XSL) ? 32000 : 32768; 130 *osc = (buf & RS5C372_TRIM_XSL) ? 32000 : 32768;
133 131
134 if (trim) 132 if (trim) {
135 *trim = buf & RS5C372_TRIM_MASK; 133 *trim = buf & RS5C372_TRIM_MASK;
134 dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, *trim);
135 }
136 136
137 return 0; 137 return 0;
138} 138}
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c
index bc4bd24508a2..6ef9c62d5032 100644
--- a/drivers/rtc/rtc-test.c
+++ b/drivers/rtc/rtc-test.c
@@ -99,6 +99,7 @@ static ssize_t test_irq_store(struct device *dev,
99 struct rtc_device *rtc = platform_get_drvdata(plat_dev); 99 struct rtc_device *rtc = platform_get_drvdata(plat_dev);
100 100
101 retval = count; 101 retval = count;
102 local_irq_disable();
102 if (strncmp(buf, "tick", 4) == 0) 103 if (strncmp(buf, "tick", 4) == 0)
103 rtc_update_irq(&rtc->class_dev, 1, RTC_PF | RTC_IRQF); 104 rtc_update_irq(&rtc->class_dev, 1, RTC_PF | RTC_IRQF);
104 else if (strncmp(buf, "alarm", 5) == 0) 105 else if (strncmp(buf, "alarm", 5) == 0)
@@ -107,6 +108,7 @@ static ssize_t test_irq_store(struct device *dev,
107 rtc_update_irq(&rtc->class_dev, 1, RTC_UF | RTC_IRQF); 108 rtc_update_irq(&rtc->class_dev, 1, RTC_UF | RTC_IRQF);
108 else 109 else
109 retval = -EINVAL; 110 retval = -EINVAL;
111 local_irq_enable();
110 112
111 return retval; 113 return retval;
112} 114}
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
index 09b714f1cdc3..3b58d3d5d38a 100644
--- a/drivers/rtc/rtc-v3020.c
+++ b/drivers/rtc/rtc-v3020.c
@@ -195,9 +195,9 @@ static int rtc_probe(struct platform_device *pdev)
195 * are all disabled */ 195 * are all disabled */
196 v3020_set_reg(chip, V3020_STATUS_0, 0x0); 196 v3020_set_reg(chip, V3020_STATUS_0, 0x0);
197 197
198 dev_info(&pdev->dev, "Chip available at physical address 0x%p," 198 dev_info(&pdev->dev, "Chip available at physical address 0x%llx,"
199 "data connected to D%d\n", 199 "data connected to D%d\n",
200 (void*)pdev->resource[0].start, 200 (unsigned long long)pdev->resource[0].start,
201 chip->leftshift); 201 chip->leftshift);
202 202
203 platform_set_drvdata(pdev, chip); 203 platform_set_drvdata(pdev, chip);