@@ -449,11 +449,19 @@ static struct amba_device uart3_device = {
.periphid = 0x00041010,
};
+static struct resource ep93xx_rtc_resource[] = {
+ {
+ .start = EP93XX_RTC_PHYS_BASE,
+ .end = EP93XX_RTC_PHYS_BASE + 0x10c - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
static struct platform_device ep93xx_rtc_device = {
- .name = "ep93xx-rtc",
- .id = -1,
- .num_resources = 0,
+ .name = "ep93xx-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ep93xx_rtc_resource),
+ .resource = ep93xx_rtc_resource,
};
b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -146,6 +146,7 @@
#define EP93XX_PWM_BASE (EP93XX_APB_VIRT_BASE +
0x00110000)
#define EP93XX_RTC_BASE (EP93XX_APB_VIRT_BASE +
0x00120000)
+#define EP93XX_RTC_PHYS_BASE (EP93XX_APB_PHYS_BASE +
0x00120000)
#define EP93XX_SYSCON_BASE (EP93XX_APB_VIRT_BASE +
0x00130000)
#define EP93XX_SYSCON_REG(x) (EP93XX_SYSCON_BASE + (x))
@@ -11,20 +11,24 @@
#include <linux/module.h>
#include <linux/rtc.h>
+#include <linux/init.h>
#include <linux/platform_device.h>
-#include <mach/hardware.h>
+#include <linux/io.h>
-#define EP93XX_RTC_REG(x) (EP93XX_RTC_BASE + (x))
-#define EP93XX_RTC_DATA EP93XX_RTC_REG(0x0000)
-#define EP93XX_RTC_LOAD EP93XX_RTC_REG(0x000C)
-#define EP93XX_RTC_SWCOMP EP93XX_RTC_REG(0x0108)
+#define EP93XX_RTC_DATA 0x000
+#define EP93XX_RTC_MATCH 0x004
+#define EP93XX_RTC_STATUS 0x008
+#define EP93XX_RTC_LOAD 0x00C
+#define EP93XX_RTC_CONTROL 0x010
+#define EP93XX_RTC_SWCOMP 0x108
#define DRV_VERSION "0.2"
static int ep93xx_get_swcomp(struct device *dev, unsigned short
*preload,
unsigned short *delete)
{
- unsigned short comp = __raw_readl(EP93XX_RTC_SWCOMP);
+ void __iomem *mmio_base = dev->platform_data;
+ unsigned long comp = __raw_readl(mmio_base + EP93XX_RTC_SWCOMP);
if (preload)
This patch updates the rtc-ep93xx.c driver to use ioremap'ed addresses. This removes the dependency on <mach/hardware.h> and properly reports the memory addresses used by the driver in /proc/iomem. In addition, ep93xx_rtc_init() is updated to use platform_driver_probe() instead of platform_driver_register(). Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> --- *preload = comp & 0xffff; @@ -37,7 +41,8 @@ static int ep93xx_get_swcomp(struct device *dev, unsigned short *preload, static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm) { - unsigned long time = __raw_readl(EP93XX_RTC_DATA); + void __iomem *mmio_base = dev->platform_data; + unsigned long time = __raw_readl(mmio_base + EP93XX_RTC_DATA); rtc_time_to_tm(time, tm); return 0; @@ -45,7 +50,9 @@ static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm) static int ep93xx_rtc_set_mmss(struct device *dev, unsigned long secs) { - __raw_writel(secs + 1, EP93XX_RTC_LOAD); + void __iomem *mmio_base = dev->platform_data; + + __raw_writel(secs + 1, mmio_base + EP93XX_RTC_LOAD); return 0; } @@ -92,11 +99,32 @@ static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_sysfs_show_comp_delete, NULL); static int __devinit ep93xx_rtc_probe(struct platform_device *dev) { - struct rtc_device *rtc = rtc_device_register("ep93xx", - &dev->dev, &ep93xx_rtc_ops, THIS_MODULE); + struct resource *res; + void __iomem *mmio_base; + struct rtc_device *rtc; + int err; + + res = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (res == NULL) + return -ENXIO; + + res = request_mem_region(res->start, resource_size(res), dev->name); + if (res == NULL) + return -EBUSY; + + mmio_base = ioremap(res->start, resource_size(res)); + if (mmio_base == NULL) { + err = -ENXIO; + goto fail; + } + dev->dev.platform_data = mmio_base; + + rtc = rtc_device_register(dev->name, + &dev->dev, &ep93xx_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { - return PTR_ERR(rtc); + err = PTR_ERR(rtc); + goto fail; } platform_set_drvdata(dev, rtc); @@ -105,14 +133,29 @@ static int __devinit ep93xx_rtc_probe(struct platform_device *dev) device_create_file(&dev->dev, &dev_attr_comp_delete); return 0; + +fail: + if (mmio_base) { + iounmap(mmio_base); + dev->dev.platform_data = NULL; + } + release_mem_region(res->start, resource_size(res)); + return err; } static int __devexit ep93xx_rtc_remove(struct platform_device *dev) { struct rtc_device *rtc = platform_get_drvdata(dev); + void __iomem *mmio_base = dev->dev.platform_data; + struct resource *res; + + rtc_device_unregister(rtc); + + iounmap(mmio_base); + dev->dev.platform_data = NULL; - if (rtc) - rtc_device_unregister(rtc); + res = platform_get_resource(dev, IORESOURCE_MEM, 0); + release_mem_region(res->start, resource_size(res)); platform_set_drvdata(dev, NULL); @@ -122,23 +165,22 @@ static int __devexit ep93xx_rtc_remove(struct platform_device *dev) /* work with hotplug and coldplug */ MODULE_ALIAS("platform:ep93xx-rtc"); -static struct platform_driver ep93xx_rtc_platform_driver = { +static struct platform_driver ep93xx_rtcdrv = { .driver = { .name = "ep93xx-rtc", .owner = THIS_MODULE, }, - .probe = ep93xx_rtc_probe, .remove = __devexit_p(ep93xx_rtc_remove), }; static int __init ep93xx_rtc_init(void) { - return platform_driver_register(&ep93xx_rtc_platform_driver); + return platform_driver_probe(&ep93xx_rtcdrv, ep93xx_rtc_probe); } static void __exit ep93xx_rtc_exit(void) { - platform_driver_unregister(&ep93xx_rtc_platform_driver); + platform_driver_unregister(&ep93xx_rtcdrv); } MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to "rtc-linux". Membership options at http://groups.google.com/group/rtc-linux . Please read http://groups.google.com/group/rtc-linux/web/checklist before submitting a driver. -~----------~----~----~----~------~----~------~--~---