aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-omap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-omap.c')
-rw-r--r--drivers/rtc/rtc-omap.c138
1 files changed, 78 insertions, 60 deletions
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 26de5f8c2ae4..21142e6574a9 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -73,43 +73,52 @@
73#define OMAP_RTC_IRQWAKEEN 0x7c 73#define OMAP_RTC_IRQWAKEEN 0x7c
74 74
75/* OMAP_RTC_CTRL_REG bit fields: */ 75/* OMAP_RTC_CTRL_REG bit fields: */
76#define OMAP_RTC_CTRL_SPLIT (1<<7) 76#define OMAP_RTC_CTRL_SPLIT BIT(7)
77#define OMAP_RTC_CTRL_DISABLE (1<<6) 77#define OMAP_RTC_CTRL_DISABLE BIT(6)
78#define OMAP_RTC_CTRL_SET_32_COUNTER (1<<5) 78#define OMAP_RTC_CTRL_SET_32_COUNTER BIT(5)
79#define OMAP_RTC_CTRL_TEST (1<<4) 79#define OMAP_RTC_CTRL_TEST BIT(4)
80#define OMAP_RTC_CTRL_MODE_12_24 (1<<3) 80#define OMAP_RTC_CTRL_MODE_12_24 BIT(3)
81#define OMAP_RTC_CTRL_AUTO_COMP (1<<2) 81#define OMAP_RTC_CTRL_AUTO_COMP BIT(2)
82#define OMAP_RTC_CTRL_ROUND_30S (1<<1) 82#define OMAP_RTC_CTRL_ROUND_30S BIT(1)
83#define OMAP_RTC_CTRL_STOP (1<<0) 83#define OMAP_RTC_CTRL_STOP BIT(0)
84 84
85/* OMAP_RTC_STATUS_REG bit fields: */ 85/* OMAP_RTC_STATUS_REG bit fields: */
86#define OMAP_RTC_STATUS_POWER_UP (1<<7) 86#define OMAP_RTC_STATUS_POWER_UP BIT(7)
87#define OMAP_RTC_STATUS_ALARM (1<<6) 87#define OMAP_RTC_STATUS_ALARM BIT(6)
88#define OMAP_RTC_STATUS_1D_EVENT (1<<5) 88#define OMAP_RTC_STATUS_1D_EVENT BIT(5)
89#define OMAP_RTC_STATUS_1H_EVENT (1<<4) 89#define OMAP_RTC_STATUS_1H_EVENT BIT(4)
90#define OMAP_RTC_STATUS_1M_EVENT (1<<3) 90#define OMAP_RTC_STATUS_1M_EVENT BIT(3)
91#define OMAP_RTC_STATUS_1S_EVENT (1<<2) 91#define OMAP_RTC_STATUS_1S_EVENT BIT(2)
92#define OMAP_RTC_STATUS_RUN (1<<1) 92#define OMAP_RTC_STATUS_RUN BIT(1)
93#define OMAP_RTC_STATUS_BUSY (1<<0) 93#define OMAP_RTC_STATUS_BUSY BIT(0)
94 94
95/* OMAP_RTC_INTERRUPTS_REG bit fields: */ 95/* OMAP_RTC_INTERRUPTS_REG bit fields: */
96#define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3) 96#define OMAP_RTC_INTERRUPTS_IT_ALARM BIT(3)
97#define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2) 97#define OMAP_RTC_INTERRUPTS_IT_TIMER BIT(2)
98
99/* OMAP_RTC_OSC_REG bit fields: */
100#define OMAP_RTC_OSC_32KCLK_EN BIT(6)
98 101
99/* OMAP_RTC_IRQWAKEEN bit fields: */ 102/* OMAP_RTC_IRQWAKEEN bit fields: */
100#define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN (1<<1) 103#define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN BIT(1)
101 104
102/* OMAP_RTC_KICKER values */ 105/* OMAP_RTC_KICKER values */
103#define KICK0_VALUE 0x83e70b13 106#define KICK0_VALUE 0x83e70b13
104#define KICK1_VALUE 0x95a4f1e0 107#define KICK1_VALUE 0x95a4f1e0
105 108
106#define OMAP_RTC_HAS_KICKER 0x1 109#define OMAP_RTC_HAS_KICKER BIT(0)
107 110
108/* 111/*
109 * Few RTC IP revisions has special WAKE-EN Register to enable Wakeup 112 * Few RTC IP revisions has special WAKE-EN Register to enable Wakeup
110 * generation for event Alarm. 113 * generation for event Alarm.
111 */ 114 */
112#define OMAP_RTC_HAS_IRQWAKEEN 0x2 115#define OMAP_RTC_HAS_IRQWAKEEN BIT(1)
116
117/*
118 * Some RTC IP revisions (like those in AM335x and DRA7x) need
119 * the 32KHz clock to be explicitly enabled.
120 */
121#define OMAP_RTC_HAS_32KCLK_EN BIT(2)
113 122
114static void __iomem *rtc_base; 123static void __iomem *rtc_base;
115 124
@@ -162,17 +171,28 @@ static irqreturn_t rtc_irq(int irq, void *rtc)
162 171
163static 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)
164{ 173{
165 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);
166 178
167 local_irq_disable(); 179 local_irq_disable();
168 rtc_wait_not_busy(); 180 rtc_wait_not_busy();
169 reg = rtc_read(OMAP_RTC_INTERRUPTS_REG); 181 reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
170 if (enabled) 182 if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN)
183 irqwake_reg = rtc_read(OMAP_RTC_IRQWAKEEN);
184
185 if (enabled) {
171 reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; 186 reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
172 else 187 irqwake_reg |= OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
188 } else {
173 reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; 189 reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
190 irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
191 }
174 rtc_wait_not_busy(); 192 rtc_wait_not_busy();
175 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);
176 local_irq_enable(); 196 local_irq_enable();
177 197
178 return 0; 198 return 0;
@@ -272,7 +292,10 @@ static int omap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
272 292
273static 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)
274{ 294{
275 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);
276 299
277 if (tm2bcd(&alm->time) < 0) 300 if (tm2bcd(&alm->time) < 0)
278 return -EINVAL; 301 return -EINVAL;
@@ -288,11 +311,19 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
288 rtc_write(alm->time.tm_sec, OMAP_RTC_ALARM_SECONDS_REG); 311 rtc_write(alm->time.tm_sec, OMAP_RTC_ALARM_SECONDS_REG);
289 312
290 reg = rtc_read(OMAP_RTC_INTERRUPTS_REG); 313 reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
291 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) {
292 reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; 318 reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
293 else 319 irqwake_reg |= OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
320 } else {
294 reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; 321 reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
322 irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
323 }
295 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);
296 327
297 local_irq_enable(); 328 local_irq_enable();
298 329
@@ -319,7 +350,8 @@ static struct platform_device_id omap_rtc_devtype[] = {
319 }, 350 },
320 [OMAP_RTC_DATA_AM3352_IDX] = { 351 [OMAP_RTC_DATA_AM3352_IDX] = {
321 .name = "am3352-rtc", 352 .name = "am3352-rtc",
322 .driver_data = OMAP_RTC_HAS_KICKER | OMAP_RTC_HAS_IRQWAKEEN, 353 .driver_data = OMAP_RTC_HAS_KICKER | OMAP_RTC_HAS_IRQWAKEEN |
354 OMAP_RTC_HAS_32KCLK_EN,
323 }, 355 },
324 [OMAP_RTC_DATA_DA830_IDX] = { 356 [OMAP_RTC_DATA_DA830_IDX] = {
325 .name = "da830-rtc", 357 .name = "da830-rtc",
@@ -352,6 +384,12 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
352 if (of_id) 384 if (of_id)
353 pdev->id_entry = of_id->data; 385 pdev->id_entry = of_id->data;
354 386
387 id_entry = platform_get_device_id(pdev);
388 if (!id_entry) {
389 dev_err(&pdev->dev, "no matching device entry\n");
390 return -ENODEV;
391 }
392
355 omap_rtc_timer = platform_get_irq(pdev, 0); 393 omap_rtc_timer = platform_get_irq(pdev, 0);
356 if (omap_rtc_timer <= 0) { 394 if (omap_rtc_timer <= 0) {
357 pr_debug("%s: no update irq?\n", pdev->name); 395 pr_debug("%s: no update irq?\n", pdev->name);
@@ -373,8 +411,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
373 pm_runtime_enable(&pdev->dev); 411 pm_runtime_enable(&pdev->dev);
374 pm_runtime_get_sync(&pdev->dev); 412 pm_runtime_get_sync(&pdev->dev);
375 413
376 id_entry = platform_get_device_id(pdev); 414 if (id_entry->driver_data & OMAP_RTC_HAS_KICKER) {
377 if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) {
378 rtc_writel(KICK0_VALUE, OMAP_RTC_KICK0_REG); 415 rtc_writel(KICK0_VALUE, OMAP_RTC_KICK0_REG);
379 rtc_writel(KICK1_VALUE, OMAP_RTC_KICK1_REG); 416 rtc_writel(KICK1_VALUE, OMAP_RTC_KICK1_REG);
380 } 417 }
@@ -393,6 +430,10 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
393 */ 430 */
394 rtc_write(0, OMAP_RTC_INTERRUPTS_REG); 431 rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
395 432
433 /* enable RTC functional clock */
434 if (id_entry->driver_data & OMAP_RTC_HAS_32KCLK_EN)
435 rtc_writel(OMAP_RTC_OSC_32KCLK_EN, OMAP_RTC_OSC_REG);
436
396 /* clear old status */ 437 /* clear old status */
397 reg = rtc_read(OMAP_RTC_STATUS_REG); 438 reg = rtc_read(OMAP_RTC_STATUS_REG);
398 if (reg & (u8) OMAP_RTC_STATUS_POWER_UP) { 439 if (reg & (u8) OMAP_RTC_STATUS_POWER_UP) {
@@ -452,7 +493,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
452 return 0; 493 return 0;
453 494
454fail0: 495fail0:
455 if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) 496 if (id_entry->driver_data & OMAP_RTC_HAS_KICKER)
456 rtc_writel(0, OMAP_RTC_KICK0_REG); 497 rtc_writel(0, OMAP_RTC_KICK0_REG);
457 pm_runtime_put_sync(&pdev->dev); 498 pm_runtime_put_sync(&pdev->dev);
458 pm_runtime_disable(&pdev->dev); 499 pm_runtime_disable(&pdev->dev);
@@ -469,7 +510,7 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
469 /* leave rtc running, but disable irqs */ 510 /* leave rtc running, but disable irqs */
470 rtc_write(0, OMAP_RTC_INTERRUPTS_REG); 511 rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
471 512
472 if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) 513 if (id_entry->driver_data & OMAP_RTC_HAS_KICKER)
473 rtc_writel(0, OMAP_RTC_KICK0_REG); 514 rtc_writel(0, OMAP_RTC_KICK0_REG);
474 515
475 /* Disable the clock/module */ 516 /* Disable the clock/module */
@@ -484,28 +525,16 @@ static u8 irqstat;
484 525
485static int omap_rtc_suspend(struct device *dev) 526static int omap_rtc_suspend(struct device *dev)
486{ 527{
487 u8 irqwake_stat;
488 struct platform_device *pdev = to_platform_device(dev);
489 const struct platform_device_id *id_entry =
490 platform_get_device_id(pdev);
491
492 irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG); 528 irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG);
493 529
494 /* 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
495 * 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
496 * saving a flag that's never used... 532 * saving a flag that's never used...
497 */ 533 */
498 if (device_may_wakeup(dev)) { 534 if (device_may_wakeup(dev))
499 enable_irq_wake(omap_rtc_alarm); 535 enable_irq_wake(omap_rtc_alarm);
500 536 else
501 if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN) {
502 irqwake_stat = rtc_read(OMAP_RTC_IRQWAKEEN);
503 irqwake_stat |= OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
504 rtc_write(irqwake_stat, OMAP_RTC_IRQWAKEEN);
505 }
506 } else {
507 rtc_write(0, OMAP_RTC_INTERRUPTS_REG); 537 rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
508 }
509 538
510 /* Disable the clock/module */ 539 /* Disable the clock/module */
511 pm_runtime_put_sync(dev); 540 pm_runtime_put_sync(dev);
@@ -515,25 +544,14 @@ static int omap_rtc_suspend(struct device *dev)
515 544
516static int omap_rtc_resume(struct device *dev) 545static int omap_rtc_resume(struct device *dev)
517{ 546{
518 u8 irqwake_stat;
519 struct platform_device *pdev = to_platform_device(dev);
520 const struct platform_device_id *id_entry =
521 platform_get_device_id(pdev);
522
523 /* Enable the clock/module so that we can access the registers */ 547 /* Enable the clock/module so that we can access the registers */
524 pm_runtime_get_sync(dev); 548 pm_runtime_get_sync(dev);
525 549
526 if (device_may_wakeup(dev)) { 550 if (device_may_wakeup(dev))
527 disable_irq_wake(omap_rtc_alarm); 551 disable_irq_wake(omap_rtc_alarm);
528 552 else
529 if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN) {
530 irqwake_stat = rtc_read(OMAP_RTC_IRQWAKEEN);
531 irqwake_stat &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
532 rtc_write(irqwake_stat, OMAP_RTC_IRQWAKEEN);
533 }
534 } else {
535 rtc_write(irqstat, OMAP_RTC_INTERRUPTS_REG); 553 rtc_write(irqstat, OMAP_RTC_INTERRUPTS_REG);
536 } 554
537 return 0; 555 return 0;
538} 556}
539#endif 557#endif