diff options
Diffstat (limited to 'drivers/rtc/rtc-omap.c')
-rw-r--r-- | drivers/rtc/rtc-omap.c | 67 |
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 | ||
172 | static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | 172 | static 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 | ||
282 | static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | 293 | static 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 | ||
504 | static int omap_rtc_suspend(struct device *dev) | 526 | static 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 | ||
535 | static int omap_rtc_resume(struct device *dev) | 545 | static 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 |