From 585dd0ec76b3dbe9406e68e38f3a273b52db4721 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 26 Jul 2005 04:38:37 -0700 Subject: [PATCH] [PATCH] ARM: OMAP: RTC Teach the RTC driver how to work with the driver model; reserve physical memory addresses, not virtual I/O ones Signed-off-by: David Brownell Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/devices.c | 39 +++++++++++++++++++++++ drivers/char/omap-rtc.c | 58 ++++++++++++++++++++++++++--------- 2 files changed, 82 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index bc2406a83c9..4cdb51cd562 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -56,6 +56,44 @@ static void omap_init_irda(void) static inline void omap_init_irda(void) {} #endif +#if defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC) + +#define OMAP_RTC_BASE 0xfffb4800 + +static struct resource rtc_resources[] = { + { + .start = OMAP_RTC_BASE, + .end = OMAP_RTC_BASE + 0x5f, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_RTC_TIMER, + .flags = IORESOURCE_IRQ, + }, + { + .start = INT_RTC_ALARM, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device omap_rtc_device = { + .name = "omap_rtc", + .id = -1, + .dev = { + .release = omap_nop_release, + }, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, +}; + +static void omap_init_rtc(void) +{ + (void) platform_device_register(&omap_rtc_device); +} +#else +static inline void omap_init_rtc(void) {} +#endif + /*-------------------------------------------------------------------------*/ #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) @@ -252,6 +290,7 @@ static int __init omap_init_devices(void) omap_init_i2c(); omap_init_irda(); omap_init_mmc(); + omap_init_rtc(); omap_init_wdt(); return 0; diff --git a/drivers/char/omap-rtc.c b/drivers/char/omap-rtc.c index 5c28e783b01..e2c06c7ebbe 100644 --- a/drivers/char/omap-rtc.c +++ b/drivers/char/omap-rtc.c @@ -434,50 +434,60 @@ static struct miscdevice rtc_dev = { .fops = &rtc_fops, }; -static int __init rtc_init(void) +static int __init omap_rtc_probe(struct device *dev) { - if (!request_region(OMAP_RTC_VIRT_BASE, OMAP_RTC_SIZE, - rtc_dev.name)) { + struct platform_device *pdev = to_platform_device(dev); + struct resource *res, *mem; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res) + mem = request_mem_region(res->start, + res->end - res->start + 1, + pdev->name); + else + mem = NULL; + if (!mem) { pr_debug("%s: RTC registers at %x are not free.\n", - rtc_dev.name, OMAP_RTC_VIRT_BASE); + pdev->name, OMAP_RTC_BASE); return -EBUSY; } + dev_set_drvdata(dev, mem); if (CMOS_READ(OMAP_RTC_STATUS_REG) & OMAP_RTC_STATUS_POWER_UP) { pr_info("%s: RTC power up reset detected.\n", - rtc_dev.name); + pdev->name); /* Clear OMAP_RTC_STATUS_POWER_UP */ CMOS_WRITE(OMAP_RTC_STATUS_POWER_UP, OMAP_RTC_STATUS_REG); } if (CMOS_READ(OMAP_RTC_STATUS_REG) & OMAP_RTC_STATUS_ALARM) { pr_debug("%s: Clearing RTC ALARM interrupt.\n", - rtc_dev.name); + pdev->name); /* Clear OMAP_RTC_STATUS_ALARM */ CMOS_WRITE(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG); } if (request_irq(INT_RTC_TIMER, rtc_interrupt, SA_INTERRUPT, - rtc_dev.name, NULL)) { + pdev->name, NULL)) { pr_debug("%s: RTC timer interrupt IRQ%d is not free.\n", - rtc_dev.name, INT_RTC_TIMER); + pdev->name, INT_RTC_TIMER); goto fail; } if (request_irq(INT_RTC_ALARM, rtc_interrupt, SA_INTERRUPT, - rtc_dev.name, NULL)) { + pdev->name, NULL)) { pr_debug("%s: RTC alarm interrupt IRQ%d is not free.\n", - rtc_dev.name, INT_RTC_ALARM); + pdev->name, INT_RTC_ALARM); free_irq(INT_RTC_TIMER, NULL); goto fail; } /* On boards with split power, RTC_ON_NOFF resets all but the RTC */ if (!(CMOS_READ(OMAP_RTC_CTRL_REG) & OMAP_RTC_CTRL_STOP)) { - pr_info("%s: Enabling RTC.\n", rtc_dev.name); + pr_info("%s: Enabling RTC.\n", pdev->name); CMOS_WRITE(OMAP_RTC_CTRL_STOP, OMAP_RTC_CTRL_REG); } else - pr_info("%s: RTC already running.\n", rtc_dev.name); + pr_info("%s: RTC already running.\n", pdev->name); spin_lock_init(&rtc_lock); misc_register(&rtc_dev); @@ -486,11 +496,11 @@ static int __init rtc_init(void) return 0; fail: - release_region(OMAP_RTC_VIRT_BASE, OMAP_RTC_SIZE); + release_resource(mem); return -EIO; } -static void __exit rtc_exit (void) +static int __exit omap_rtc_remove(struct device *dev) { free_irq (INT_RTC_TIMER, NULL); free_irq (INT_RTC_ALARM, NULL); @@ -498,7 +508,8 @@ static void __exit rtc_exit (void) remove_proc_entry ("driver/rtc", NULL); misc_deregister(&rtc_dev); - release_region (OMAP_RTC_VIRT_BASE, OMAP_RTC_SIZE); + release_resource(dev_get_drvdata(dev)); + return 0; } /* @@ -693,6 +704,23 @@ static void set_rtc_irq_bit(unsigned char bit) spin_unlock_irq(&rtc_lock); } +static struct device_driver omap_rtc_driver = { + .name = "omap_rtc", + .bus = &platform_bus_type, + .probe = omap_rtc_probe, + .remove = __exit_p(omap_rtc_remove), +}; + +static int __init rtc_init(void) +{ + return driver_register(&omap_rtc_driver); +} + +static void __exit rtc_exit(void) +{ + driver_unregister(&omap_rtc_driver); +} + module_init(rtc_init); module_exit(rtc_exit); -- 2.41.1