diff options
author | Keerthy <j-keerthy@ti.com> | 2015-08-18 05:41:16 -0400 |
---|---|---|
committer | Alexandre Belloni <alexandre.belloni@free-electrons.com> | 2015-09-05 13:37:21 -0400 |
commit | 399cf0f63f6f24d7a837fbfbc801010cb6e77579 (patch) | |
tree | a2a48fe8f0a07fac664f91149925c378e4f126a1 | |
parent | 532409aa1ba8b69d5a3dea159d4b1bd9adbd7a46 (diff) |
rtc: omap: Add external clock enabling support
Configure the clock source to external clock if available.
External clock is preferred as it can be ticking during suspend.
Signed-off-by: Keerthy <j-keerthy@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
-rw-r--r-- | drivers/rtc/rtc-omap.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index f31c0127dae0..ec2e9c5fb993 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -108,6 +108,7 @@ | |||
108 | 108 | ||
109 | /* OMAP_RTC_OSC_REG bit fields: */ | 109 | /* OMAP_RTC_OSC_REG bit fields: */ |
110 | #define OMAP_RTC_OSC_32KCLK_EN BIT(6) | 110 | #define OMAP_RTC_OSC_32KCLK_EN BIT(6) |
111 | #define OMAP_RTC_OSC_SEL_32KCLK_SRC BIT(3) | ||
111 | 112 | ||
112 | /* OMAP_RTC_IRQWAKEEN bit fields: */ | 113 | /* OMAP_RTC_IRQWAKEEN bit fields: */ |
113 | #define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN BIT(1) | 114 | #define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN BIT(1) |
@@ -138,6 +139,7 @@ struct omap_rtc { | |||
138 | int irq_timer; | 139 | int irq_timer; |
139 | u8 interrupts_reg; | 140 | u8 interrupts_reg; |
140 | bool is_pmic_controller; | 141 | bool is_pmic_controller; |
142 | bool has_ext_clk; | ||
141 | const struct omap_rtc_device_type *type; | 143 | const struct omap_rtc_device_type *type; |
142 | }; | 144 | }; |
143 | 145 | ||
@@ -555,7 +557,11 @@ static int omap_rtc_probe(struct platform_device *pdev) | |||
555 | if (rtc->irq_alarm <= 0) | 557 | if (rtc->irq_alarm <= 0) |
556 | return -ENOENT; | 558 | return -ENOENT; |
557 | 559 | ||
558 | rtc->clk = devm_clk_get(&pdev->dev, "int-clk"); | 560 | rtc->clk = devm_clk_get(&pdev->dev, "ext-clk"); |
561 | if (!IS_ERR(rtc->clk)) | ||
562 | rtc->has_ext_clk = true; | ||
563 | else | ||
564 | rtc->clk = devm_clk_get(&pdev->dev, "int-clk"); | ||
559 | 565 | ||
560 | if (!IS_ERR(rtc->clk)) | 566 | if (!IS_ERR(rtc->clk)) |
561 | clk_prepare_enable(rtc->clk); | 567 | clk_prepare_enable(rtc->clk); |
@@ -634,6 +640,16 @@ static int omap_rtc_probe(struct platform_device *pdev) | |||
634 | if (reg != new_ctrl) | 640 | if (reg != new_ctrl) |
635 | rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl); | 641 | rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl); |
636 | 642 | ||
643 | /* | ||
644 | * If we have the external clock then switch to it so we can keep | ||
645 | * ticking across suspend. | ||
646 | */ | ||
647 | if (rtc->has_ext_clk) { | ||
648 | reg = rtc_read(rtc, OMAP_RTC_OSC_REG); | ||
649 | rtc_write(rtc, OMAP_RTC_OSC_REG, | ||
650 | reg | OMAP_RTC_OSC_SEL_32KCLK_SRC); | ||
651 | } | ||
652 | |||
637 | rtc->type->lock(rtc); | 653 | rtc->type->lock(rtc); |
638 | 654 | ||
639 | device_init_wakeup(&pdev->dev, true); | 655 | device_init_wakeup(&pdev->dev, true); |
@@ -679,6 +695,7 @@ err: | |||
679 | static int __exit omap_rtc_remove(struct platform_device *pdev) | 695 | static int __exit omap_rtc_remove(struct platform_device *pdev) |
680 | { | 696 | { |
681 | struct omap_rtc *rtc = platform_get_drvdata(pdev); | 697 | struct omap_rtc *rtc = platform_get_drvdata(pdev); |
698 | u8 reg; | ||
682 | 699 | ||
683 | if (pm_power_off == omap_rtc_power_off && | 700 | if (pm_power_off == omap_rtc_power_off && |
684 | omap_rtc_power_off_rtc == rtc) { | 701 | omap_rtc_power_off_rtc == rtc) { |
@@ -695,6 +712,12 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) | |||
695 | /* leave rtc running, but disable irqs */ | 712 | /* leave rtc running, but disable irqs */ |
696 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); | 713 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); |
697 | 714 | ||
715 | if (rtc->has_ext_clk) { | ||
716 | reg = rtc_read(rtc, OMAP_RTC_OSC_REG); | ||
717 | reg &= ~OMAP_RTC_OSC_SEL_32KCLK_SRC; | ||
718 | rtc_write(rtc, OMAP_RTC_OSC_REG, reg); | ||
719 | } | ||
720 | |||
698 | rtc->type->lock(rtc); | 721 | rtc->type->lock(rtc); |
699 | 722 | ||
700 | /* Disable the clock/module */ | 723 | /* Disable the clock/module */ |