diff options
Diffstat (limited to 'drivers/rtc/rtc-omap.c')
-rw-r--r-- | drivers/rtc/rtc-omap.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 0587d53987f..64d9727b722 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -87,9 +87,10 @@ #define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3) #define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2) +static void __iomem *rtc_base; -#define rtc_read(addr) omap_readb(OMAP_RTC_BASE + (addr)) -#define rtc_write(val, addr) omap_writeb(val, OMAP_RTC_BASE + (addr)) +#define rtc_read(addr) __raw_readb(rtc_base + (addr)) +#define rtc_write(val, addr) __raw_writeb(val, rtc_base + (addr)) /* 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) return -ENOENT; } - /* NOTE: using static mapping for RTC registers */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res && res->start != OMAP_RTC_BASE) { - pr_debug("%s: RTC registers at %08x, expected %08x\n", - pdev->name, (unsigned) res->start, OMAP_RTC_BASE); + if (!res) { + pr_debug("%s: RTC resource data missing\n", pdev->name); return -ENOENT; } - if (res) - mem = request_mem_region(res->start, - res->end - res->start + 1, - pdev->name); - else - mem = NULL; + mem = request_mem_region(res->start, resource_size(res), pdev->name); if (!mem) { pr_debug("%s: RTC registers at %08x are not free\n", - pdev->name, OMAP_RTC_BASE); + pdev->name, res->start); return -EBUSY; } + rtc_base = ioremap(res->start, resource_size(res)); + if (!rtc_base) { + pr_debug("%s: RTC registers can't be mapped\n", pdev->name); + goto fail; + } + rtc = rtc_device_register(pdev->name, &pdev->dev, &omap_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { pr_debug("%s: can't register RTC device, err %ld\n", pdev->name, PTR_ERR(rtc)); - goto fail; + goto fail0; } platform_set_drvdata(pdev, rtc); dev_set_drvdata(&rtc->dev, mem); @@ -380,13 +380,14 @@ static int __init omap_rtc_probe(struct platform_device *pdev) dev_name(&rtc->dev), rtc)) { pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", pdev->name, omap_rtc_timer); - goto fail0; + goto fail1; } - if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, - dev_name(&rtc->dev), rtc)) { + if ((omap_rtc_timer != omap_rtc_alarm) && + (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, + dev_name(&rtc->dev), rtc))) { pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", pdev->name, omap_rtc_alarm); - goto fail1; + goto fail2; } /* 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) return 0; -fail1: +fail2: free_irq(omap_rtc_timer, NULL); -fail0: +fail1: rtc_device_unregister(rtc); +fail0: + iounmap(rtc_base); fail: release_resource(mem); return -EIO; @@ -438,7 +441,9 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) rtc_write(0, OMAP_RTC_INTERRUPTS_REG); free_irq(omap_rtc_timer, rtc); - free_irq(omap_rtc_alarm, rtc); + + if (omap_rtc_timer != omap_rtc_alarm) + free_irq(omap_rtc_alarm, rtc); release_resource(dev_get_drvdata(&rtc->dev)); rtc_device_unregister(rtc); |