aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorAfzal Mohammed <afzal@ti.com>2012-12-17 19:02:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-17 20:15:20 -0500
commitcab1458c8c4fdfc993e86454eef785bc39517dd8 (patch)
tree1bc3b4d5e9f3ea0eb91c35180439557a7301d6e1 /drivers/rtc
parent6899e92d65c490c5292752718ff277b123f8c00a (diff)
rtc: omap: kicker mechanism support
OMAP RTC IP can have kicker feature. This prevents spurious writes to register. To write to registers kicker lock has to be released. Procedure to do it as follows, 1. write to kick0 register, 0x83e70b13 2. write to kick1 register, 0x95a4f1e0 Writing value other than 0x83e70b13 to kick0 enables write locking, more details about kicker mechanism can be found in section 20.3.3.5.3 of AM335X TRM @www.ti.com/am335x Here id table information is added and is used to distinguish those that require kicker handling and the ones that doesn't need it. There are more features in the newer IP's compared to legacy ones other than kicker, which driver currently doesn't handle, supporting additional features would be easier with the addition of id table. Older IP (of OMAP1) doesn't have revision register as per TRM, so revision register can't be relied always to find features, hence id table is being used. While at it, replace __raw_writeb/__raw_readb with writeb/readb; this driver is used on ARMv7 (AM335X SoC) Signed-off-by: Afzal Mohammed <afzal@ti.com> Acked-by: Sekhar Nori <nsekhar@ti.com> Cc: Grant Likely <grant.likely@secretlab.ca> Cc: Sekhar Nori <nsekhar@ti.com> Cc: Kevin Hilman <khilman@ti.com> Cc: Russell King <linux@arm.linux.org.uk> Cc: Alessandro Zummo <a.zummo@towertech.it> Cc: Daniel Mack <zonque@gmail.com> Cc: Vaibhav Hiremath <hvaibhav@ti.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-omap.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 0b614e32653d..d948426283db 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -38,6 +38,8 @@
38 * the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment. 38 * the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment.
39 */ 39 */
40 40
41#define DRIVER_NAME "omap_rtc"
42
41#define OMAP_RTC_BASE 0xfffb4800 43#define OMAP_RTC_BASE 0xfffb4800
42 44
43/* RTC registers */ 45/* RTC registers */
@@ -64,6 +66,9 @@
64#define OMAP_RTC_COMP_MSB_REG 0x50 66#define OMAP_RTC_COMP_MSB_REG 0x50
65#define OMAP_RTC_OSC_REG 0x54 67#define OMAP_RTC_OSC_REG 0x54
66 68
69#define OMAP_RTC_KICK0_REG 0x6c
70#define OMAP_RTC_KICK1_REG 0x70
71
67/* OMAP_RTC_CTRL_REG bit fields: */ 72/* OMAP_RTC_CTRL_REG bit fields: */
68#define OMAP_RTC_CTRL_SPLIT (1<<7) 73#define OMAP_RTC_CTRL_SPLIT (1<<7)
69#define OMAP_RTC_CTRL_DISABLE (1<<6) 74#define OMAP_RTC_CTRL_DISABLE (1<<6)
@@ -88,10 +93,18 @@
88#define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3) 93#define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3)
89#define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2) 94#define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2)
90 95
96/* OMAP_RTC_KICKER values */
97#define KICK0_VALUE 0x83e70b13
98#define KICK1_VALUE 0x95a4f1e0
99
100#define OMAP_RTC_HAS_KICKER 0x1
101
91static void __iomem *rtc_base; 102static void __iomem *rtc_base;
92 103
93#define rtc_read(addr) __raw_readb(rtc_base + (addr)) 104#define rtc_read(addr) readb(rtc_base + (addr))
94#define rtc_write(val, addr) __raw_writeb(val, rtc_base + (addr)) 105#define rtc_write(val, addr) writeb(val, rtc_base + (addr))
106
107#define rtc_writel(val, addr) writel(val, rtc_base + (addr))
95 108
96 109
97/* we rely on the rtc framework to handle locking (rtc->ops_lock), 110/* we rely on the rtc framework to handle locking (rtc->ops_lock),
@@ -285,11 +298,23 @@ static struct rtc_class_ops omap_rtc_ops = {
285static int omap_rtc_alarm; 298static int omap_rtc_alarm;
286static int omap_rtc_timer; 299static int omap_rtc_timer;
287 300
301static struct platform_device_id omap_rtc_devtype[] = {
302 {
303 .name = DRIVER_NAME,
304 }, {
305 .name = "da830-rtc",
306 .driver_data = OMAP_RTC_HAS_KICKER,
307 },
308 {},
309};
310MODULE_DEVICE_TABLE(platform, omap_rtc_devtype);
311
288static int __init omap_rtc_probe(struct platform_device *pdev) 312static int __init omap_rtc_probe(struct platform_device *pdev)
289{ 313{
290 struct resource *res, *mem; 314 struct resource *res, *mem;
291 struct rtc_device *rtc; 315 struct rtc_device *rtc;
292 u8 reg, new_ctrl; 316 u8 reg, new_ctrl;
317 const struct platform_device_id *id_entry;
293 318
294 omap_rtc_timer = platform_get_irq(pdev, 0); 319 omap_rtc_timer = platform_get_irq(pdev, 0);
295 if (omap_rtc_timer <= 0) { 320 if (omap_rtc_timer <= 0) {
@@ -322,6 +347,12 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
322 goto fail; 347 goto fail;
323 } 348 }
324 349
350 id_entry = platform_get_device_id(pdev);
351 if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) {
352 rtc_writel(KICK0_VALUE, OMAP_RTC_KICK0_REG);
353 rtc_writel(KICK1_VALUE, OMAP_RTC_KICK1_REG);
354 }
355
325 rtc = rtc_device_register(pdev->name, &pdev->dev, 356 rtc = rtc_device_register(pdev->name, &pdev->dev,
326 &omap_rtc_ops, THIS_MODULE); 357 &omap_rtc_ops, THIS_MODULE);
327 if (IS_ERR(rtc)) { 358 if (IS_ERR(rtc)) {
@@ -398,6 +429,8 @@ fail2:
398fail1: 429fail1:
399 rtc_device_unregister(rtc); 430 rtc_device_unregister(rtc);
400fail0: 431fail0:
432 if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER))
433 rtc_writel(0, OMAP_RTC_KICK0_REG);
401 iounmap(rtc_base); 434 iounmap(rtc_base);
402fail: 435fail:
403 release_mem_region(mem->start, resource_size(mem)); 436 release_mem_region(mem->start, resource_size(mem));
@@ -408,6 +441,8 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
408{ 441{
409 struct rtc_device *rtc = platform_get_drvdata(pdev); 442 struct rtc_device *rtc = platform_get_drvdata(pdev);
410 struct resource *mem = dev_get_drvdata(&rtc->dev); 443 struct resource *mem = dev_get_drvdata(&rtc->dev);
444 const struct platform_device_id *id_entry =
445 platform_get_device_id(pdev);
411 446
412 device_init_wakeup(&pdev->dev, 0); 447 device_init_wakeup(&pdev->dev, 0);
413 448
@@ -420,6 +455,8 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
420 free_irq(omap_rtc_alarm, rtc); 455 free_irq(omap_rtc_alarm, rtc);
421 456
422 rtc_device_unregister(rtc); 457 rtc_device_unregister(rtc);
458 if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER))
459 rtc_writel(0, OMAP_RTC_KICK0_REG);
423 iounmap(rtc_base); 460 iounmap(rtc_base);
424 release_mem_region(mem->start, resource_size(mem)); 461 release_mem_region(mem->start, resource_size(mem));
425 return 0; 462 return 0;
@@ -471,9 +508,10 @@ static struct platform_driver omap_rtc_driver = {
471 .resume = omap_rtc_resume, 508 .resume = omap_rtc_resume,
472 .shutdown = omap_rtc_shutdown, 509 .shutdown = omap_rtc_shutdown,
473 .driver = { 510 .driver = {
474 .name = "omap_rtc", 511 .name = DRIVER_NAME,
475 .owner = THIS_MODULE, 512 .owner = THIS_MODULE,
476 }, 513 },
514 .id_table = omap_rtc_devtype,
477}; 515};
478 516
479static int __init rtc_init(void) 517static int __init rtc_init(void)