diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index ae24486f858a4a9d2e7482c67298c7e12c603b89..c535e8805a3b7052c2631685a86ff2096e271703 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -450,10 +450,19 @@ static struct amba_device uart3_device = {
 };
 
 
+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,
 };
 
 
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
index f66be12b856e21e435163712ad3c479e8b51921f..78ac1bddc8bc9c065a3abf0ab5f7b93324e94683 100644
--- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -147,6 +147,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))
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c
index f7a3283dd02947962ce5c71d3a221b121231a728..551332e4ed02a28122b72b817bf0682814ed13c2 100644
--- a/drivers/rtc/rtc-ep93xx.c
+++ b/drivers/rtc/rtc-ep93xx.c
@@ -12,32 +12,56 @@
 #include <linux/module.h>
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
-#include <mach/hardware.h>
+#include <linux/io.h>
+
+#define EP93XX_RTC_DATA			0x000
+#define EP93XX_RTC_MATCH		0x004
+#define EP93XX_RTC_STATUS		0x008
+#define  EP93XX_RTC_STATUS_INTR		 (1<<0)
+#define EP93XX_RTC_LOAD			0x00C
+#define EP93XX_RTC_CONTROL		0x010
+#define  EP93XX_RTC_CONTROL_MIE		 (1<<0)
+#define EP93XX_RTC_SWCOMP		0x108
+#define  EP93XX_RTC_SWCOMP_DEL_MASK	 0x001f0000
+#define  EP93XX_RTC_SWCOMP_DEL_SHIFT	 16
+#define  EP93XX_RTC_SWCOMP_INT_MASK	 0x0000ffff
+#define  EP93XX_RTC_SWCOMP_INT_SHIFT	 0
+
+#define DRV_VERSION "0.3"
 
-#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 DRV_VERSION "0.2"
+/*
+ * struct device dev.platform_data is used to store our private data
+ * because struct rtc_device does not have a variable to hold it.
+ */
+struct ep93xx_rtc {
+	void __iomem	*mmio_base;
+};
 
-static int ep93xx_get_swcomp(struct device *dev, unsigned short *preload,
+static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload,
 				unsigned short *delete)
 {
-	unsigned short comp = __raw_readl(EP93XX_RTC_SWCOMP);
+	struct ep93xx_rtc *ep93xx_rtc = dev->platform_data;
+	unsigned long comp;
+
+	comp = __raw_readl(ep93xx_rtc->mmio_base + EP93XX_RTC_SWCOMP);
 
 	if (preload)
-		*preload = comp & 0xffff;
+		*preload = (comp & EP93XX_RTC_SWCOMP_INT_MASK)
+				>> EP93XX_RTC_SWCOMP_INT_SHIFT;
 
 	if (delete)
-		*delete = (comp >> 16) & 0x1f;
+		*delete = (comp & EP93XX_RTC_SWCOMP_DEL_MASK)
+				>> EP93XX_RTC_SWCOMP_DEL_SHIFT;
 
 	return 0;
 }
 
 static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-	unsigned long time = __raw_readl(EP93XX_RTC_DATA);
+	struct ep93xx_rtc *ep93xx_rtc = dev->platform_data;
+	unsigned long time;
+
+	 time = __raw_readl(ep93xx_rtc->mmio_base + EP93XX_RTC_DATA);
 
 	rtc_time_to_tm(time, tm);
 	return 0;
@@ -45,7 +69,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);
+	struct ep93xx_rtc *ep93xx_rtc = dev->platform_data;
+
+	__raw_writel(secs + 1, ep93xx_rtc->mmio_base + EP93XX_RTC_LOAD);
 	return 0;
 }
 
@@ -53,7 +79,7 @@ static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq)
 {
 	unsigned short preload, delete;
 
-	ep93xx_get_swcomp(dev, &preload, &delete);
+	ep93xx_rtc_get_swcomp(dev, &preload, &delete);
 
 	seq_printf(seq, "preload\t\t: %d\n", preload);
 	seq_printf(seq, "delete\t\t: %d\n", delete);
@@ -67,54 +93,104 @@ static const struct rtc_class_ops ep93xx_rtc_ops = {
 	.proc		= ep93xx_rtc_proc,
 };
 
-static ssize_t ep93xx_sysfs_show_comp_preload(struct device *dev,
+static ssize_t ep93xx_rtc_show_comp_preload(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
 	unsigned short preload;
 
-	ep93xx_get_swcomp(dev, &preload, NULL);
+	ep93xx_rtc_get_swcomp(dev, &preload, NULL);
 
 	return sprintf(buf, "%d\n", preload);
 }
-static DEVICE_ATTR(comp_preload, S_IRUGO, ep93xx_sysfs_show_comp_preload, NULL);
+static DEVICE_ATTR(comp_preload, S_IRUGO, ep93xx_rtc_show_comp_preload, NULL);
 
-static ssize_t ep93xx_sysfs_show_comp_delete(struct device *dev,
+static ssize_t ep93xx_rtc_show_comp_delete(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
 	unsigned short delete;
 
-	ep93xx_get_swcomp(dev, NULL, &delete);
+	ep93xx_rtc_get_swcomp(dev, NULL, &delete);
 
 	return sprintf(buf, "%d\n", delete);
 }
-static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_sysfs_show_comp_delete, NULL);
+static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_rtc_show_comp_delete, NULL);
 
 
-static int __devinit ep93xx_rtc_probe(struct platform_device *dev)
+static int __init ep93xx_rtc_probe(struct platform_device *pdev)
 {
-	struct rtc_device *rtc = rtc_device_register("ep93xx",
-				&dev->dev, &ep93xx_rtc_ops, THIS_MODULE);
+	struct ep93xx_rtc *ep93xx_rtc;
+	struct resource *res;
+	struct rtc_device *rtc;
+	int err;
+
+	ep93xx_rtc = kzalloc(sizeof(struct ep93xx_rtc), GFP_KERNEL);
+	if (ep93xx_rtc == NULL)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL)
+		return -ENXIO;
+
+	res = request_mem_region(res->start, resource_size(res), pdev->name);
+	if (res == NULL)
+		return -EBUSY;
+
+	ep93xx_rtc->mmio_base = ioremap(res->start, resource_size(res));
+	if (ep93xx_rtc->mmio_base == NULL) {
+		err = -ENXIO;
+		goto fail;
+	}
 
+	pdev->dev.platform_data = ep93xx_rtc;
+
+	rtc = rtc_device_register(pdev->name,
+				&pdev->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);
+	platform_set_drvdata(pdev, rtc);
 
-	device_create_file(&dev->dev, &dev_attr_comp_preload);
-	device_create_file(&dev->dev, &dev_attr_comp_delete);
+	err = device_create_file(&pdev->dev, &dev_attr_comp_preload);
+	if (err)
+		goto fail;
+	err = device_create_file(&pdev->dev, &dev_attr_comp_delete);
+	if (err) {
+		device_remove_file(&pdev->dev, &dev_attr_comp_preload);
+		goto fail;
+	}
 
 	return 0;
+
+fail:
+	if (ep93xx_rtc->mmio_base) {
+		iounmap(ep93xx_rtc->mmio_base);
+		pdev->dev.platform_data = NULL;
+	}
+	release_mem_region(res->start, resource_size(res));
+	return err;
 }
 
-static int __devexit ep93xx_rtc_remove(struct platform_device *dev)
+static int __exit ep93xx_rtc_remove(struct platform_device *pdev)
 {
-	struct rtc_device *rtc = platform_get_drvdata(dev);
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct ep93xx_rtc *ep93xx_rtc = pdev->dev.platform_data;
+	struct resource *res;
+
+	/* cleanup sysfs */
+	device_remove_file(&pdev->dev, &dev_attr_comp_delete);
+	device_remove_file(&pdev->dev, &dev_attr_comp_preload);
+
+	rtc_device_unregister(rtc);
+
+	iounmap(ep93xx_rtc->mmio_base);
+	pdev->dev.platform_data = NULL;
 
- 	if (rtc)
-		rtc_device_unregister(rtc);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, resource_size(res));
 
-	platform_set_drvdata(dev, NULL);
+	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
@@ -122,23 +198,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_rtc_driver = {
 	.driver		= {
 		.name	= "ep93xx-rtc",
 		.owner	= THIS_MODULE,
 	},
-	.probe		= ep93xx_rtc_probe,
-	.remove		= __devexit_p(ep93xx_rtc_remove),
+	.remove		= __exit_p(ep93xx_rtc_remove),
 };
 
 static int __init ep93xx_rtc_init(void)
 {
-	return platform_driver_register(&ep93xx_rtc_platform_driver);
+        return platform_driver_probe(&ep93xx_rtc_driver, ep93xx_rtc_probe);
 }
 
 static void __exit ep93xx_rtc_exit(void)
 {
-	platform_driver_unregister(&ep93xx_rtc_platform_driver);
+	platform_driver_unregister(&ep93xx_rtc_driver);
 }
 
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");