aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-09-07 16:03:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-09-07 16:03:48 -0400
commit79016f648872549392d232cd648bd02298c2d2bb (patch)
tree8b3f435b7ff3633b0a82313a1bb12d052f36c6b7 /drivers/rtc
parente81b693c0104d6a767f998ee5a2e00b5acbbcd18 (diff)
parent486257130873a2172d8eac2c182f7e578465bdd0 (diff)
Merge branch 'timers-fixes-for-linus' of git://tesla.tglx.de/git/linux-2.6-tip
* 'timers-fixes-for-linus' of git://tesla.tglx.de/git/linux-2.6-tip: rtc: twl: Fix registration vs. init order rtc: Initialized rtc_time->tm_isdst rtc: Fix RTC PIE frequency limit rtc: rtc-twl: Remove lockdep related local_irq_enable() rtc: rtc-twl: Switch to using threaded irq rtc: ep93xx: Fix 'rtc' may be used uninitialized warning alarmtimers: Avoid possible denial of service with high freq periodic timers alarmtimers: Memset itimerspec passed into alarm_timer_get alarmtimers: Avoid possible null pointer traversal
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-ep93xx.c16
-rw-r--r--drivers/rtc/rtc-lib.c2
-rw-r--r--drivers/rtc/rtc-twl.c60
3 files changed, 34 insertions, 44 deletions
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c
index 335551d333b2..14a42a1edc66 100644
--- a/drivers/rtc/rtc-ep93xx.c
+++ b/drivers/rtc/rtc-ep93xx.c
@@ -36,6 +36,7 @@
36 */ 36 */
37struct ep93xx_rtc { 37struct ep93xx_rtc {
38 void __iomem *mmio_base; 38 void __iomem *mmio_base;
39 struct rtc_device *rtc;
39}; 40};
40 41
41static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload, 42static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload,
@@ -130,7 +131,6 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev)
130{ 131{
131 struct ep93xx_rtc *ep93xx_rtc; 132 struct ep93xx_rtc *ep93xx_rtc;
132 struct resource *res; 133 struct resource *res;
133 struct rtc_device *rtc;
134 int err; 134 int err;
135 135
136 ep93xx_rtc = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_rtc), GFP_KERNEL); 136 ep93xx_rtc = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_rtc), GFP_KERNEL);
@@ -151,12 +151,12 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev)
151 return -ENXIO; 151 return -ENXIO;
152 152
153 pdev->dev.platform_data = ep93xx_rtc; 153 pdev->dev.platform_data = ep93xx_rtc;
154 platform_set_drvdata(pdev, rtc); 154 platform_set_drvdata(pdev, ep93xx_rtc);
155 155
156 rtc = rtc_device_register(pdev->name, 156 ep93xx_rtc->rtc = rtc_device_register(pdev->name,
157 &pdev->dev, &ep93xx_rtc_ops, THIS_MODULE); 157 &pdev->dev, &ep93xx_rtc_ops, THIS_MODULE);
158 if (IS_ERR(rtc)) { 158 if (IS_ERR(ep93xx_rtc->rtc)) {
159 err = PTR_ERR(rtc); 159 err = PTR_ERR(ep93xx_rtc->rtc);
160 goto exit; 160 goto exit;
161 } 161 }
162 162
@@ -167,7 +167,7 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev)
167 return 0; 167 return 0;
168 168
169fail: 169fail:
170 rtc_device_unregister(rtc); 170 rtc_device_unregister(ep93xx_rtc->rtc);
171exit: 171exit:
172 platform_set_drvdata(pdev, NULL); 172 platform_set_drvdata(pdev, NULL);
173 pdev->dev.platform_data = NULL; 173 pdev->dev.platform_data = NULL;
@@ -176,11 +176,11 @@ exit:
176 176
177static int __exit ep93xx_rtc_remove(struct platform_device *pdev) 177static int __exit ep93xx_rtc_remove(struct platform_device *pdev)
178{ 178{
179 struct rtc_device *rtc = platform_get_drvdata(pdev); 179 struct ep93xx_rtc *ep93xx_rtc = platform_get_drvdata(pdev);
180 180
181 sysfs_remove_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files); 181 sysfs_remove_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files);
182 platform_set_drvdata(pdev, NULL); 182 platform_set_drvdata(pdev, NULL);
183 rtc_device_unregister(rtc); 183 rtc_device_unregister(ep93xx_rtc->rtc);
184 pdev->dev.platform_data = NULL; 184 pdev->dev.platform_data = NULL;
185 185
186 return 0; 186 return 0;
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
index 075f1708deae..c4cf05731118 100644
--- a/drivers/rtc/rtc-lib.c
+++ b/drivers/rtc/rtc-lib.c
@@ -85,6 +85,8 @@ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
85 time -= tm->tm_hour * 3600; 85 time -= tm->tm_hour * 3600;
86 tm->tm_min = time / 60; 86 tm->tm_min = time / 60;
87 tm->tm_sec = time - tm->tm_min * 60; 87 tm->tm_sec = time - tm->tm_min * 60;
88
89 tm->tm_isdst = 0;
88} 90}
89EXPORT_SYMBOL(rtc_time_to_tm); 91EXPORT_SYMBOL(rtc_time_to_tm);
90 92
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index 9a81f778d6b2..20687d55e7a7 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -362,14 +362,6 @@ static irqreturn_t twl_rtc_interrupt(int irq, void *rtc)
362 int res; 362 int res;
363 u8 rd_reg; 363 u8 rd_reg;
364 364
365#ifdef CONFIG_LOCKDEP
366 /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
367 * we don't want and can't tolerate. Although it might be
368 * friendlier not to borrow this thread context...
369 */
370 local_irq_enable();
371#endif
372
373 res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); 365 res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
374 if (res) 366 if (res)
375 goto out; 367 goto out;
@@ -428,24 +420,12 @@ static struct rtc_class_ops twl_rtc_ops = {
428static int __devinit twl_rtc_probe(struct platform_device *pdev) 420static int __devinit twl_rtc_probe(struct platform_device *pdev)
429{ 421{
430 struct rtc_device *rtc; 422 struct rtc_device *rtc;
431 int ret = 0; 423 int ret = -EINVAL;
432 int irq = platform_get_irq(pdev, 0); 424 int irq = platform_get_irq(pdev, 0);
433 u8 rd_reg; 425 u8 rd_reg;
434 426
435 if (irq <= 0) 427 if (irq <= 0)
436 return -EINVAL; 428 goto out1;
437
438 rtc = rtc_device_register(pdev->name,
439 &pdev->dev, &twl_rtc_ops, THIS_MODULE);
440 if (IS_ERR(rtc)) {
441 ret = PTR_ERR(rtc);
442 dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
443 PTR_ERR(rtc));
444 goto out0;
445
446 }
447
448 platform_set_drvdata(pdev, rtc);
449 429
450 ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); 430 ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
451 if (ret < 0) 431 if (ret < 0)
@@ -462,14 +442,6 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
462 if (ret < 0) 442 if (ret < 0)
463 goto out1; 443 goto out1;
464 444
465 ret = request_irq(irq, twl_rtc_interrupt,
466 IRQF_TRIGGER_RISING,
467 dev_name(&rtc->dev), rtc);
468 if (ret < 0) {
469 dev_err(&pdev->dev, "IRQ is not free.\n");
470 goto out1;
471 }
472
473 if (twl_class_is_6030()) { 445 if (twl_class_is_6030()) {
474 twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK, 446 twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
475 REG_INT_MSK_LINE_A); 447 REG_INT_MSK_LINE_A);
@@ -480,28 +452,44 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
480 /* Check RTC module status, Enable if it is off */ 452 /* Check RTC module status, Enable if it is off */
481 ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG); 453 ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
482 if (ret < 0) 454 if (ret < 0)
483 goto out2; 455 goto out1;
484 456
485 if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) { 457 if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
486 dev_info(&pdev->dev, "Enabling TWL-RTC.\n"); 458 dev_info(&pdev->dev, "Enabling TWL-RTC.\n");
487 rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M; 459 rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
488 ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG); 460 ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
489 if (ret < 0) 461 if (ret < 0)
490 goto out2; 462 goto out1;
491 } 463 }
492 464
493 /* init cached IRQ enable bits */ 465 /* init cached IRQ enable bits */
494 ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); 466 ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
495 if (ret < 0) 467 if (ret < 0)
468 goto out1;
469
470 rtc = rtc_device_register(pdev->name,
471 &pdev->dev, &twl_rtc_ops, THIS_MODULE);
472 if (IS_ERR(rtc)) {
473 ret = PTR_ERR(rtc);
474 dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
475 PTR_ERR(rtc));
476 goto out1;
477 }
478
479 ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt,
480 IRQF_TRIGGER_RISING,
481 dev_name(&rtc->dev), rtc);
482 if (ret < 0) {
483 dev_err(&pdev->dev, "IRQ is not free.\n");
496 goto out2; 484 goto out2;
485 }
497 486
498 return ret; 487 platform_set_drvdata(pdev, rtc);
488 return 0;
499 489
500out2: 490out2:
501 free_irq(irq, rtc);
502out1:
503 rtc_device_unregister(rtc); 491 rtc_device_unregister(rtc);
504out0: 492out1:
505 return ret; 493 return ret;
506} 494}
507 495