aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-omap.c
diff options
context:
space:
mode:
authorLokesh Vutla <lokeshvutla@ti.com>2014-06-06 17:36:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-06 19:08:09 -0400
commitab7f580b8e6ca9b90a00a28e7edfe2d9e5b8fed9 (patch)
tree07e5f5a10cd550dee85df832883ca25d6147f841 /drivers/rtc/rtc-omap.c
parent9dcc87fec8947308e0111c65dcd881e6aa5b1673 (diff)
drivers/rtc/rtc-omap.c: enable RTC_IRQWAKEEN bits when Alarm is set
When RTC CLKTRCTRL bit is configured in HW_AUTO, module goes to sleep in IDLE state. The Alarm SWakeup event can be used to wakeup the RTC when it is in IDLE state. In order to do so, the alarm needs to be set and enabled before RTC enters the IDLE state. Also the wakeup generation for alarm/timer event needs to be set (bits [1:0] in RTC_IRQWAKEEN register). Currently RTC_IRQWAKEEN bits are set only in suspend/resume paths. With this ALARM interrupts are not generated when it enters IDLE state. So programming the RTC_IRQWAKEEN bits when ever ALARM is set. Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com> Acked-by: Sekhar Nori <nsekhar@ti.com> Cc: Grant Likely <grant.likely@linaro.org> Cc: Rob Herring <robh+dt@kernel.org> Cc: Alessandro Zummo <a.zummo@towertech.it> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc/rtc-omap.c')
-rw-r--r--drivers/rtc/rtc-omap.c67
1 files changed, 33 insertions, 34 deletions
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 03bce134414c..21142e6574a9 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -171,17 +171,28 @@ static irqreturn_t rtc_irq(int irq, void *rtc)
171 171
172static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) 172static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
173{ 173{
174 u8 reg; 174 u8 reg, irqwake_reg = 0;
175 struct platform_device *pdev = to_platform_device(dev);
176 const struct platform_device_id *id_entry =
177 platform_get_device_id(pdev);
175 178
176 local_irq_disable(); 179 local_irq_disable();
177 rtc_wait_not_busy(); 180 rtc_wait_not_busy();
178 reg = rtc_read(OMAP_RTC_INTERRUPTS_REG); 181 reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
179 if (enabled) 182 if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN)
183 irqwake_reg = rtc_read(OMAP_RTC_IRQWAKEEN);
184
185 if (enabled) {
180 reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; 186 reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
181 else 187 irqwake_reg |= OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
188 } else {
182 reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; 189 reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
190 irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
191 }
183 rtc_wait_not_busy(); 192 rtc_wait_not_busy();
184 rtc_write(reg, OMAP_RTC_INTERRUPTS_REG); 193 rtc_write(reg, OMAP_RTC_INTERRUPTS_REG);
194 if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN)
195 rtc_write(irqwake_reg, OMAP_RTC_IRQWAKEEN);
185 local_irq_enable(); 196 local_irq_enable();
186 197
187 return 0; 198 return 0;
@@ -281,7 +292,10 @@ static int omap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
281 292
282static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) 293static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
283{ 294{
284 u8 reg; 295 u8 reg, irqwake_reg = 0;
296 struct platform_device *pdev = to_platform_device(dev);
297 const struct platform_device_id *id_entry =
298 platform_get_device_id(pdev);
285 299
286 if (tm2bcd(&alm->time) < 0) 300 if (tm2bcd(&alm->time) < 0)
287 return -EINVAL; 301 return -EINVAL;
@@ -297,11 +311,19 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
297 rtc_write(alm->time.tm_sec, OMAP_RTC_ALARM_SECONDS_REG); 311 rtc_write(alm->time.tm_sec, OMAP_RTC_ALARM_SECONDS_REG);
298 312
299 reg = rtc_read(OMAP_RTC_INTERRUPTS_REG); 313 reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
300 if (alm->enabled) 314 if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN)
315 irqwake_reg = rtc_read(OMAP_RTC_IRQWAKEEN);
316
317 if (alm->enabled) {
301 reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; 318 reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
302 else 319 irqwake_reg |= OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
320 } else {
303 reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; 321 reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
322 irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
323 }
304 rtc_write(reg, OMAP_RTC_INTERRUPTS_REG); 324 rtc_write(reg, OMAP_RTC_INTERRUPTS_REG);
325 if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN)
326 rtc_write(irqwake_reg, OMAP_RTC_IRQWAKEEN);
305 327
306 local_irq_enable(); 328 local_irq_enable();
307 329
@@ -503,28 +525,16 @@ static u8 irqstat;
503 525
504static int omap_rtc_suspend(struct device *dev) 526static int omap_rtc_suspend(struct device *dev)
505{ 527{
506 u8 irqwake_stat;
507 struct platform_device *pdev = to_platform_device(dev);
508 const struct platform_device_id *id_entry =
509 platform_get_device_id(pdev);
510
511 irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG); 528 irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG);
512 529
513 /* FIXME the RTC alarm is not currently acting as a wakeup event 530 /* FIXME the RTC alarm is not currently acting as a wakeup event
514 * source on some platforms, and in fact this enable() call is just 531 * source on some platforms, and in fact this enable() call is just
515 * saving a flag that's never used... 532 * saving a flag that's never used...
516 */ 533 */
517 if (device_may_wakeup(dev)) { 534 if (device_may_wakeup(dev))
518 enable_irq_wake(omap_rtc_alarm); 535 enable_irq_wake(omap_rtc_alarm);
519 536 else
520 if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN) {
521 irqwake_stat = rtc_read(OMAP_RTC_IRQWAKEEN);
522 irqwake_stat |= OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
523 rtc_write(irqwake_stat, OMAP_RTC_IRQWAKEEN);
524 }
525 } else {
526 rtc_write(0, OMAP_RTC_INTERRUPTS_REG); 537 rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
527 }
528 538
529 /* Disable the clock/module */ 539 /* Disable the clock/module */
530 pm_runtime_put_sync(dev); 540 pm_runtime_put_sync(dev);
@@ -534,25 +544,14 @@ static int omap_rtc_suspend(struct device *dev)
534 544
535static int omap_rtc_resume(struct device *dev) 545static int omap_rtc_resume(struct device *dev)
536{ 546{
537 u8 irqwake_stat;
538 struct platform_device *pdev = to_platform_device(dev);
539 const struct platform_device_id *id_entry =
540 platform_get_device_id(pdev);
541
542 /* Enable the clock/module so that we can access the registers */ 547 /* Enable the clock/module so that we can access the registers */
543 pm_runtime_get_sync(dev); 548 pm_runtime_get_sync(dev);
544 549
545 if (device_may_wakeup(dev)) { 550 if (device_may_wakeup(dev))
546 disable_irq_wake(omap_rtc_alarm); 551 disable_irq_wake(omap_rtc_alarm);
547 552 else
548 if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN) {
549 irqwake_stat = rtc_read(OMAP_RTC_IRQWAKEEN);
550 irqwake_stat &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
551 rtc_write(irqwake_stat, OMAP_RTC_IRQWAKEEN);
552 }
553 } else {
554 rtc_write(irqstat, OMAP_RTC_INTERRUPTS_REG); 553 rtc_write(irqstat, OMAP_RTC_INTERRUPTS_REG);
555 } 554
556 return 0; 555 return 0;
557} 556}
558#endif 557#endif