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.c80
1 files changed, 77 insertions, 3 deletions
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 0b614e32653d..600971407aac 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -20,6 +20,9 @@
20#include <linux/rtc.h> 20#include <linux/rtc.h>
21#include <linux/bcd.h> 21#include <linux/bcd.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/of.h>
24#include <linux/of_device.h>
25#include <linux/pm_runtime.h>
23 26
24#include <asm/io.h> 27#include <asm/io.h>
25 28
@@ -38,6 +41,8 @@
38 * the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment. 41 * the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment.
39 */ 42 */
40 43
44#define DRIVER_NAME "omap_rtc"
45
41#define OMAP_RTC_BASE 0xfffb4800 46#define OMAP_RTC_BASE 0xfffb4800
42 47
43/* RTC registers */ 48/* RTC registers */
@@ -64,6 +69,9 @@
64#define OMAP_RTC_COMP_MSB_REG 0x50 69#define OMAP_RTC_COMP_MSB_REG 0x50
65#define OMAP_RTC_OSC_REG 0x54 70#define OMAP_RTC_OSC_REG 0x54
66 71
72#define OMAP_RTC_KICK0_REG 0x6c
73#define OMAP_RTC_KICK1_REG 0x70
74
67/* OMAP_RTC_CTRL_REG bit fields: */ 75/* OMAP_RTC_CTRL_REG bit fields: */
68#define OMAP_RTC_CTRL_SPLIT (1<<7) 76#define OMAP_RTC_CTRL_SPLIT (1<<7)
69#define OMAP_RTC_CTRL_DISABLE (1<<6) 77#define OMAP_RTC_CTRL_DISABLE (1<<6)
@@ -88,10 +96,18 @@
88#define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3) 96#define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3)
89#define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2) 97#define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2)
90 98
99/* OMAP_RTC_KICKER values */
100#define KICK0_VALUE 0x83e70b13
101#define KICK1_VALUE 0x95a4f1e0
102
103#define OMAP_RTC_HAS_KICKER 0x1
104
91static void __iomem *rtc_base; 105static void __iomem *rtc_base;
92 106
93#define rtc_read(addr) __raw_readb(rtc_base + (addr)) 107#define rtc_read(addr) readb(rtc_base + (addr))
94#define rtc_write(val, addr) __raw_writeb(val, rtc_base + (addr)) 108#define rtc_write(val, addr) writeb(val, rtc_base + (addr))
109
110#define rtc_writel(val, addr) writel(val, rtc_base + (addr))
95 111
96 112
97/* we rely on the rtc framework to handle locking (rtc->ops_lock), 113/* we rely on the rtc framework to handle locking (rtc->ops_lock),
@@ -285,11 +301,38 @@ static struct rtc_class_ops omap_rtc_ops = {
285static int omap_rtc_alarm; 301static int omap_rtc_alarm;
286static int omap_rtc_timer; 302static int omap_rtc_timer;
287 303
304#define OMAP_RTC_DATA_DA830_IDX 1
305
306static struct platform_device_id omap_rtc_devtype[] = {
307 {
308 .name = DRIVER_NAME,
309 }, {
310 .name = "da830-rtc",
311 .driver_data = OMAP_RTC_HAS_KICKER,
312 },
313 {},
314};
315MODULE_DEVICE_TABLE(platform, omap_rtc_devtype);
316
317static const struct of_device_id omap_rtc_of_match[] = {
318 { .compatible = "ti,da830-rtc",
319 .data = &omap_rtc_devtype[OMAP_RTC_DATA_DA830_IDX],
320 },
321 {},
322};
323MODULE_DEVICE_TABLE(of, omap_rtc_of_match);
324
288static int __init omap_rtc_probe(struct platform_device *pdev) 325static int __init omap_rtc_probe(struct platform_device *pdev)
289{ 326{
290 struct resource *res, *mem; 327 struct resource *res, *mem;
291 struct rtc_device *rtc; 328 struct rtc_device *rtc;
292 u8 reg, new_ctrl; 329 u8 reg, new_ctrl;
330 const struct platform_device_id *id_entry;
331 const struct of_device_id *of_id;
332
333 of_id = of_match_device(omap_rtc_of_match, &pdev->dev);
334 if (of_id)
335 pdev->id_entry = of_id->data;
293 336
294 omap_rtc_timer = platform_get_irq(pdev, 0); 337 omap_rtc_timer = platform_get_irq(pdev, 0);
295 if (omap_rtc_timer <= 0) { 338 if (omap_rtc_timer <= 0) {
@@ -322,6 +365,16 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
322 goto fail; 365 goto fail;
323 } 366 }
324 367
368 /* Enable the clock/module so that we can access the registers */
369 pm_runtime_enable(&pdev->dev);
370 pm_runtime_get_sync(&pdev->dev);
371
372 id_entry = platform_get_device_id(pdev);
373 if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) {
374 rtc_writel(KICK0_VALUE, OMAP_RTC_KICK0_REG);
375 rtc_writel(KICK1_VALUE, OMAP_RTC_KICK1_REG);
376 }
377
325 rtc = rtc_device_register(pdev->name, &pdev->dev, 378 rtc = rtc_device_register(pdev->name, &pdev->dev,
326 &omap_rtc_ops, THIS_MODULE); 379 &omap_rtc_ops, THIS_MODULE);
327 if (IS_ERR(rtc)) { 380 if (IS_ERR(rtc)) {
@@ -398,6 +451,10 @@ fail2:
398fail1: 451fail1:
399 rtc_device_unregister(rtc); 452 rtc_device_unregister(rtc);
400fail0: 453fail0:
454 if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER))
455 rtc_writel(0, OMAP_RTC_KICK0_REG);
456 pm_runtime_put_sync(&pdev->dev);
457 pm_runtime_disable(&pdev->dev);
401 iounmap(rtc_base); 458 iounmap(rtc_base);
402fail: 459fail:
403 release_mem_region(mem->start, resource_size(mem)); 460 release_mem_region(mem->start, resource_size(mem));
@@ -408,6 +465,8 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
408{ 465{
409 struct rtc_device *rtc = platform_get_drvdata(pdev); 466 struct rtc_device *rtc = platform_get_drvdata(pdev);
410 struct resource *mem = dev_get_drvdata(&rtc->dev); 467 struct resource *mem = dev_get_drvdata(&rtc->dev);
468 const struct platform_device_id *id_entry =
469 platform_get_device_id(pdev);
411 470
412 device_init_wakeup(&pdev->dev, 0); 471 device_init_wakeup(&pdev->dev, 0);
413 472
@@ -420,6 +479,13 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
420 free_irq(omap_rtc_alarm, rtc); 479 free_irq(omap_rtc_alarm, rtc);
421 480
422 rtc_device_unregister(rtc); 481 rtc_device_unregister(rtc);
482 if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER))
483 rtc_writel(0, OMAP_RTC_KICK0_REG);
484
485 /* Disable the clock/module */
486 pm_runtime_put_sync(&pdev->dev);
487 pm_runtime_disable(&pdev->dev);
488
423 iounmap(rtc_base); 489 iounmap(rtc_base);
424 release_mem_region(mem->start, resource_size(mem)); 490 release_mem_region(mem->start, resource_size(mem));
425 return 0; 491 return 0;
@@ -442,11 +508,17 @@ static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state)
442 else 508 else
443 rtc_write(0, OMAP_RTC_INTERRUPTS_REG); 509 rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
444 510
511 /* Disable the clock/module */
512 pm_runtime_put_sync(&pdev->dev);
513
445 return 0; 514 return 0;
446} 515}
447 516
448static int omap_rtc_resume(struct platform_device *pdev) 517static int omap_rtc_resume(struct platform_device *pdev)
449{ 518{
519 /* Enable the clock/module so that we can access the registers */
520 pm_runtime_get_sync(&pdev->dev);
521
450 if (device_may_wakeup(&pdev->dev)) 522 if (device_may_wakeup(&pdev->dev))
451 disable_irq_wake(omap_rtc_alarm); 523 disable_irq_wake(omap_rtc_alarm);
452 else 524 else
@@ -471,9 +543,11 @@ static struct platform_driver omap_rtc_driver = {
471 .resume = omap_rtc_resume, 543 .resume = omap_rtc_resume,
472 .shutdown = omap_rtc_shutdown, 544 .shutdown = omap_rtc_shutdown,
473 .driver = { 545 .driver = {
474 .name = "omap_rtc", 546 .name = DRIVER_NAME,
475 .owner = THIS_MODULE, 547 .owner = THIS_MODULE,
548 .of_match_table = of_match_ptr(omap_rtc_of_match),
476 }, 549 },
550 .id_table = omap_rtc_devtype,
477}; 551};
478 552
479static int __init rtc_init(void) 553static int __init rtc_init(void)