aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorTodd Poynor <toddpoynor@google.com>2011-08-10 23:20:36 -0400
committerJohn Stultz <john.stultz@linaro.org>2011-08-26 20:26:54 -0400
commit7e72c686347562b4a275c97b4bdd7a79c1f23c65 (patch)
tree02d26d0499a1510efa3e15ff57046ad35955f84c /drivers/rtc
parenta7402deb324f62106566f5a95199a54c41e200ef (diff)
rtc: twl: Fix registration vs. init order
Only register as an RTC device after the hardware has been successfully initialized. The RTC class driver will call back to this driver to read a pending alarm, and other drivers watching for new devices on the RTC class may read the RTC time upon registration. Such access might occur while the RTC is stopped, prior to clearing pending alarms, etc. The new ordering also avoids leaving the platform device drvdata set to an unregistered struct rtc_device * on probe errors. Signed-off-by: Todd Poynor <toddpoynor@google.com> Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-twl.c52
1 files changed, 24 insertions, 28 deletions
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index 9677bbc433f..20687d55e7a 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -420,24 +420,12 @@ static struct rtc_class_ops twl_rtc_ops = {
420static int __devinit twl_rtc_probe(struct platform_device *pdev) 420static int __devinit twl_rtc_probe(struct platform_device *pdev)
421{ 421{
422 struct rtc_device *rtc; 422 struct rtc_device *rtc;
423 int ret = 0; 423 int ret = -EINVAL;
424 int irq = platform_get_irq(pdev, 0); 424 int irq = platform_get_irq(pdev, 0);
425 u8 rd_reg; 425 u8 rd_reg;
426 426
427 if (irq <= 0) 427 if (irq <= 0)
428 return -EINVAL; 428 goto out1;
429
430 rtc = rtc_device_register(pdev->name,
431 &pdev->dev, &twl_rtc_ops, THIS_MODULE);
432 if (IS_ERR(rtc)) {
433 ret = PTR_ERR(rtc);
434 dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
435 PTR_ERR(rtc));
436 goto out0;
437
438 }
439
440 platform_set_drvdata(pdev, rtc);
441 429
442 ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); 430 ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
443 if (ret < 0) 431 if (ret < 0)
@@ -454,14 +442,6 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
454 if (ret < 0) 442 if (ret < 0)
455 goto out1; 443 goto out1;
456 444
457 ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt,
458 IRQF_TRIGGER_RISING,
459 dev_name(&rtc->dev), rtc);
460 if (ret < 0) {
461 dev_err(&pdev->dev, "IRQ is not free.\n");
462 goto out1;
463 }
464
465 if (twl_class_is_6030()) { 445 if (twl_class_is_6030()) {
466 twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK, 446 twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
467 REG_INT_MSK_LINE_A); 447 REG_INT_MSK_LINE_A);
@@ -472,28 +452,44 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
472 /* Check RTC module status, Enable if it is off */ 452 /* Check RTC module status, Enable if it is off */
473 ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG); 453 ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
474 if (ret < 0) 454 if (ret < 0)
475 goto out2; 455 goto out1;
476 456
477 if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) { 457 if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
478 dev_info(&pdev->dev, "Enabling TWL-RTC.\n"); 458 dev_info(&pdev->dev, "Enabling TWL-RTC.\n");
479 rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M; 459 rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
480 ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG); 460 ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
481 if (ret < 0) 461 if (ret < 0)
482 goto out2; 462 goto out1;
483 } 463 }
484 464
485 /* init cached IRQ enable bits */ 465 /* init cached IRQ enable bits */
486 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);
487 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");
488 goto out2; 484 goto out2;
485 }
489 486
490 return ret; 487 platform_set_drvdata(pdev, rtc);
488 return 0;
491 489
492out2: 490out2:
493 free_irq(irq, rtc);
494out1:
495 rtc_device_unregister(rtc); 491 rtc_device_unregister(rtc);
496out0: 492out1:
497 return ret; 493 return ret;
498} 494}
499 495