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.c47
1 files changed, 26 insertions, 21 deletions
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 0587d53987fe..64d9727b7229 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -87,9 +87,10 @@
87#define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3) 87#define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3)
88#define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2) 88#define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2)
89 89
90static void __iomem *rtc_base;
90 91
91#define rtc_read(addr) omap_readb(OMAP_RTC_BASE + (addr)) 92#define rtc_read(addr) __raw_readb(rtc_base + (addr))
92#define rtc_write(val, addr) omap_writeb(val, OMAP_RTC_BASE + (addr)) 93#define rtc_write(val, addr) __raw_writeb(val, rtc_base + (addr))
93 94
94 95
95/* we rely on the rtc framework to handle locking (rtc->ops_lock), 96/* we rely on the rtc framework to handle locking (rtc->ops_lock),
@@ -330,32 +331,31 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
330 return -ENOENT; 331 return -ENOENT;
331 } 332 }
332 333
333 /* NOTE: using static mapping for RTC registers */
334 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 334 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
335 if (res && res->start != OMAP_RTC_BASE) { 335 if (!res) {
336 pr_debug("%s: RTC registers at %08x, expected %08x\n", 336 pr_debug("%s: RTC resource data missing\n", pdev->name);
337 pdev->name, (unsigned) res->start, OMAP_RTC_BASE);
338 return -ENOENT; 337 return -ENOENT;
339 } 338 }
340 339
341 if (res) 340 mem = request_mem_region(res->start, resource_size(res), pdev->name);
342 mem = request_mem_region(res->start,
343 res->end - res->start + 1,
344 pdev->name);
345 else
346 mem = NULL;
347 if (!mem) { 341 if (!mem) {
348 pr_debug("%s: RTC registers at %08x are not free\n", 342 pr_debug("%s: RTC registers at %08x are not free\n",
349 pdev->name, OMAP_RTC_BASE); 343 pdev->name, res->start);
350 return -EBUSY; 344 return -EBUSY;
351 } 345 }
352 346
347 rtc_base = ioremap(res->start, resource_size(res));
348 if (!rtc_base) {
349 pr_debug("%s: RTC registers can't be mapped\n", pdev->name);
350 goto fail;
351 }
352
353 rtc = rtc_device_register(pdev->name, &pdev->dev, 353 rtc = rtc_device_register(pdev->name, &pdev->dev,
354 &omap_rtc_ops, THIS_MODULE); 354 &omap_rtc_ops, THIS_MODULE);
355 if (IS_ERR(rtc)) { 355 if (IS_ERR(rtc)) {
356 pr_debug("%s: can't register RTC device, err %ld\n", 356 pr_debug("%s: can't register RTC device, err %ld\n",
357 pdev->name, PTR_ERR(rtc)); 357 pdev->name, PTR_ERR(rtc));
358 goto fail; 358 goto fail0;
359 } 359 }
360 platform_set_drvdata(pdev, rtc); 360 platform_set_drvdata(pdev, rtc);
361 dev_set_drvdata(&rtc->dev, mem); 361 dev_set_drvdata(&rtc->dev, mem);
@@ -380,13 +380,14 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
380 dev_name(&rtc->dev), rtc)) { 380 dev_name(&rtc->dev), rtc)) {
381 pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", 381 pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
382 pdev->name, omap_rtc_timer); 382 pdev->name, omap_rtc_timer);
383 goto fail0; 383 goto fail1;
384 } 384 }
385 if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, 385 if ((omap_rtc_timer != omap_rtc_alarm) &&
386 dev_name(&rtc->dev), rtc)) { 386 (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED,
387 dev_name(&rtc->dev), rtc))) {
387 pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", 388 pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
388 pdev->name, omap_rtc_alarm); 389 pdev->name, omap_rtc_alarm);
389 goto fail1; 390 goto fail2;
390 } 391 }
391 392
392 /* On boards with split power, RTC_ON_NOFF won't reset the RTC */ 393 /* On boards with split power, RTC_ON_NOFF won't reset the RTC */
@@ -419,10 +420,12 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
419 420
420 return 0; 421 return 0;
421 422
422fail1: 423fail2:
423 free_irq(omap_rtc_timer, NULL); 424 free_irq(omap_rtc_timer, NULL);
424fail0: 425fail1:
425 rtc_device_unregister(rtc); 426 rtc_device_unregister(rtc);
427fail0:
428 iounmap(rtc_base);
426fail: 429fail:
427 release_resource(mem); 430 release_resource(mem);
428 return -EIO; 431 return -EIO;
@@ -438,7 +441,9 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
438 rtc_write(0, OMAP_RTC_INTERRUPTS_REG); 441 rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
439 442
440 free_irq(omap_rtc_timer, rtc); 443 free_irq(omap_rtc_timer, rtc);
441 free_irq(omap_rtc_alarm, rtc); 444
445 if (omap_rtc_timer != omap_rtc_alarm)
446 free_irq(omap_rtc_alarm, rtc);
442 447
443 release_resource(dev_get_drvdata(&rtc->dev)); 448 release_resource(dev_get_drvdata(&rtc->dev));
444 rtc_device_unregister(rtc); 449 rtc_device_unregister(rtc);