diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 08cbdb9..da2b3c4 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1087,4 +1087,14 @@ config RTC_DRV_MXC
 	   This driver can also be built as a module, if so, the module
 	   will be called "rtc-mxc".
 
+config RTC_DRV_M5441x
+	tristate "Freescale Coldfire M5441x RTC support"
+	depends on M5441x
+	help
+	  This enables support for the RTC on the Freescale Coldfire 5441x
+	  (54410/54415/54416/54417/54418).
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called rtc-m5441x.
+
 endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 2973921..a9ded2c 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_RTC_DRV_M41T94)	+= rtc-m41t94.o
 obj-$(CONFIG_RTC_DRV_M48T35)	+= rtc-m48t35.o
 obj-$(CONFIG_RTC_DRV_M48T59)	+= rtc-m48t59.o
 obj-$(CONFIG_RTC_DRV_M48T86)	+= rtc-m48t86.o
+obj-$(CONFIG_RTC_DRV_M5441x)	+= rtc-m5441x.o
 obj-$(CONFIG_RTC_DRV_MXC)	+= rtc-mxc.o
 obj-$(CONFIG_RTC_DRV_MAX6900)	+= rtc-max6900.o
 obj-$(CONFIG_RTC_DRV_MAX8925)	+= rtc-max8925.o
diff --git a/drivers/rtc/rtc-m5441x.c b/drivers/rtc/rtc-m5441x.c
new file mode 100644
index 0000000..ba677f3
--- /dev/null
+++ b/drivers/rtc/rtc-m5441x.c
@@ -0,0 +1,363 @@
+/*
+ * RTC driver for the Freescale Coldfire 5441x SoCs.
+ *
+ * Copyright(C) 2012, Steven King <sfking@fdwdc.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/rtc.h>
+
+static void __iomem *m5441x_rtc_base;
+static int m5441x_rtc_irq;
+static struct clk *m5441x_rtc_clk;
+
+#define M5441X_RTC_YEARMON	(m5441x_rtc_base + 0x00)
+#define M5441X_RTC_DAYS		(m5441x_rtc_base + 0x02)
+#define M5441X_RTC_HOURMIN	(m5441x_rtc_base + 0x04)
+#define M5441X_RTC_SECONDS	(m5441x_rtc_base + 0x06)
+#define M5441X_RTC_ALM_YRMON	(m5441x_rtc_base + 0x08)
+#define M5441X_RTC_ALM_DAYS	(m5441x_rtc_base + 0x0a)
+#define M5441X_RTC_ALM_HM	(m5441x_rtc_base + 0x0c)
+#define M5441X_RTC_ALM_SEC	(m5441x_rtc_base + 0x0e)
+#define M5441X_RTC_CR		(m5441x_rtc_base + 0x10)
+#define M5441X_RTC_CR_AM0	(0 << 2)	/* secs/mins/hrs */
+#define M5441X_RTC_CR_AM1	(1 << 2)	/* secs/mins/days */
+#define M5441X_RTC_CR_AM2	(2 << 2)	/* secs/mins/days/mons */
+#define M5441X_RTC_CR_AM3	(3 << 2)	/* alarm match all */
+#define M5441X_RTC_CR_DTDEN	(1 << 6)	/* DST enable */
+#define M5441X_RTC_CR_BCDEN	(1 << 7)	/* BCD enable */
+#define M5441X_RTC_CR_SWR	(1 << 8)	/* software reset */
+#define M5441X_RTC_SR		(m5441x_rtc_base + 0x12)
+#define M5441X_RTC_SR_INVAL	(1 << 0)	/* time invalid */
+#define M5441X_RTC_SR_CDON	(1 << 1)	/* Compensation done */
+#define M5441X_RTC_SR_BERR	(1 << 2)	/* Bus err */
+#define M5441X_RTC_SR_WPE	(1 << 4)	/* write protect enabled */
+#define M5441X_RTC_SR_PORB	(1 << 6)	/* power on reset boot */
+#define M5441X_RTC_ISR		(m5441x_rtc_base + 0x14)
+#define M5441X_RTC_ISR_STW	(1 << 1)	/* Stop watch */
+#define M5441X_RTC_ISR_ALM	(1 << 2)	/* Alarm */
+#define M5441X_RTC_ISR_DAY	(1 << 3)	/* day counter inc */
+#define M5441X_RTC_ISR_HR	(1 << 4)	/* hour counter inc */
+#define M5441X_RTC_ISR_MIN	(1 << 5)	/* minute counter inc */
+#define M5441X_RTC_ISR_1HZ	(1 << 6)	/* second counter inc */
+#define M5441X_RTC_ISR_2HZ	(1 << 7)	/* 2Hz counter inc */
+#define M5441X_RTC_IER		(m5441x_rtc_base + 0x16)
+#define M5441X_RTC_IER_STW	(1 << 1)	/* Stop watch */
+#define M5441X_RTC_IER_ALM	(1 << 2)	/* Alarm */
+#define M5441X_RTC_IER_DAY	(1 << 3)	/* day counter inc */
+#define M5441X_RTC_IER_HR	(1 << 4)	/* hour counter inc */
+#define M5441X_RTC_IER_MIN	(1 << 5)	/* minute counter inc */
+#define M5441X_RTC_IER_1HZ	(1 << 6)	/* second counter inc */
+#define M5441X_RTC_IER_2HZ	(1 << 7)	/* 2Hz counter inc */
+#define M5441X_RTC_COUNT_DN	(m5441x_rtc_base + 0x18)
+#define M5441X_RTC_CFG_DATA	(m5441x_rtc_base + 0x20)
+#define M5441X_RTC_DST_HOUR	(m5441x_rtc_base + 0x22)
+#define M5441X_RTC_DST_MON	(m5441x_rtc_base + 0x24)
+#define M5441X_RTC_DST_DAY	(m5441x_rtc_base + 0x26)
+#define M5441X_RTC_RTC_COMPEN	(m5441x_rtc_base + 0x28)
+#define M5441X_RTC_UP_CNTRH	(m5441x_rtc_base + 0x32)
+#define M5441X_RTC_UP_CNTRL	(m5441x_rtc_base + 0x24)
+#define M5441X_RTC_Standy_RAM	(m5441x_rtc_base + 0x40)
+
+static int m5441x_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	u16 r[4];
+
+	do {
+		r[0] = __raw_readw(M5441X_RTC_SECONDS);
+		r[1] = __raw_readw(M5441X_RTC_HOURMIN);
+		r[2] = __raw_readw(M5441X_RTC_DAYS);
+		r[3] = __raw_readw(M5441X_RTC_YEARMON);
+	} while (r[0] != __raw_readw(M5441X_RTC_SECONDS));
+
+	tm->tm_sec = r[0];
+	tm->tm_min = r[1] & 0xff;
+	tm->tm_hour = r[1] >> 8;
+	tm->tm_mday = (r[2] & 0xff) - 1;
+	tm->tm_wday = r[2] >> 8;
+	tm->tm_mon = (r[3] & 0xff) - 1;
+	tm->tm_year = (((s16)r[3]) >> 8) + 212;
+
+	return rtc_valid_tm(tm);
+}
+
+static int m5441x_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	u16 r[4];
+
+	if ((tm->tm_year < 84) || (tm->tm_year > 339))
+		return -EINVAL; /* 1984 <-> 2239 */
+
+	r[0] = tm->tm_sec;
+	r[1] = (tm->tm_hour << 8) | tm->tm_min;
+	r[2] = (tm->tm_wday << 8) | (tm->tm_mday + 1);
+	r[3] = ((tm->tm_year - 212) << 8) | (tm->tm_mon + 1);
+
+	/* disable write protect */
+	__raw_writew(0x0, M5441X_RTC_CR);
+	__raw_writew(0x1, M5441X_RTC_CR);
+	__raw_writew(0x3, M5441X_RTC_CR);
+	__raw_writew(0x2, M5441X_RTC_CR);
+
+	__raw_writew(r[0], M5441X_RTC_SECONDS);
+	__raw_writew(r[1], M5441X_RTC_HOURMIN);
+	__raw_writew(r[2], M5441X_RTC_DAYS);
+	__raw_writew(r[3], M5441X_RTC_YEARMON);
+
+	/* enable write protect */
+	__raw_writew(0x2, M5441X_RTC_CR);
+
+	return 0;
+}
+
+static int m5441x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	u16 r[4];
+
+	r[0] = __raw_readw(M5441X_RTC_ALM_SEC);
+	r[1] = __raw_readw(M5441X_RTC_ALM_HM);
+	r[2] = __raw_readw(M5441X_RTC_ALM_DAYS);
+	r[3] = __raw_readw(M5441X_RTC_ALM_YRMON);
+
+	alm->time.tm_sec = r[0] & 0xff;
+	alm->time.tm_min = r[1] & 0xff;
+	alm->time.tm_hour = r[1] >> 8;
+	alm->time.tm_mday = (r[2] & 0xff) - 1;
+	alm->time.tm_mon = (r[3] & 0xff) - 1;
+	alm->time.tm_year = (((s16)r[3]) >> 8) + 212;
+
+	alm->enabled = !!(__raw_readw(M5441X_RTC_IER) & M5441X_RTC_IER_ALM);
+
+	return 0;
+}
+
+static int m5441x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	u16 r[4];
+
+	if ((alm->time.tm_year < 84) || (alm->time.tm_year > 339))
+		return -EINVAL;
+
+	r[0] = alm->time.tm_sec;
+	r[1] = (alm->time.tm_hour << 8) | alm->time.tm_min;
+	r[2] = alm->time.tm_mday + 1;
+	r[3] = ((alm->time.tm_year - 212) << 8) | (alm->time.tm_mon + 1);
+
+	local_irq_disable();
+
+	/* disable write protect */
+	__raw_writew(0x0, M5441X_RTC_CR);
+	__raw_writew(0x1, M5441X_RTC_CR);
+	__raw_writew(0x3, M5441X_RTC_CR);
+	__raw_writew(0x2, M5441X_RTC_CR);
+
+	__raw_writew(r[0], M5441X_RTC_ALM_SEC);
+	__raw_writew(r[1], M5441X_RTC_ALM_HM);
+	__raw_writew(r[2], M5441X_RTC_ALM_DAYS);
+	__raw_writew(r[3], M5441X_RTC_ALM_YRMON);
+
+	r[0] = __raw_readw(M5441X_RTC_IER);
+	if (alm->enabled)
+		r[0] |= M5441X_RTC_IER_ALM;
+	else
+		r[0] &= ~M5441X_RTC_IER_ALM;
+	__raw_writew(r[0], M5441X_RTC_IER);
+
+	/* enable write protect */
+	__raw_writew(0x2, M5441X_RTC_CR);
+
+	local_irq_enable();
+
+	return 0;
+}
+
+static int m5441x_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
+{
+	u16 r;
+
+	local_irq_disable();
+
+	/* disable write protect */
+	__raw_writew(0x0, M5441X_RTC_CR);
+	__raw_writew(0x1, M5441X_RTC_CR);
+	__raw_writew(0x3, M5441X_RTC_CR);
+	__raw_writew(0x2, M5441X_RTC_CR);
+
+	r = __raw_readw(M5441X_RTC_IER);
+	if (enable)
+		r |= M5441X_RTC_IER_ALM;
+	else
+		r &= ~M5441X_RTC_IER_ALM;
+	__raw_writew(r, M5441X_RTC_IER);
+
+	/* enable write protect */
+	__raw_writew(0x2, M5441X_RTC_CR);
+
+	local_irq_enable();
+
+	return 0;
+}
+
+static struct rtc_class_ops m5441x_rtc_ops = {
+	.read_time		= m5441x_rtc_read_time,
+	.set_time		= m5441x_rtc_set_time,
+	.read_alarm		= m5441x_rtc_read_alarm,
+	.set_alarm		= m5441x_rtc_set_alarm,
+	.alarm_irq_enable	= m5441x_rtc_alarm_irq_enable,
+};
+
+static irqreturn_t m5441x_rtc_irq_handler(int irq, void *rtc)
+{
+	unsigned long events = 0;
+	u16 r;
+
+	/* disable write protect */
+	__raw_writew(0x0, M5441X_RTC_CR);
+	__raw_writew(0x1, M5441X_RTC_CR);
+	__raw_writew(0x3, M5441X_RTC_CR);
+	__raw_writew(0x2, M5441X_RTC_CR);
+
+	while ((r = __raw_readw(M5441X_RTC_ISR)) != 0) {
+		if (r & M5441X_RTC_ISR_ALM)
+			events |= RTC_IRQF | RTC_AF;
+		if (r & M5441X_RTC_ISR_1HZ)
+			events |= RTC_IRQF | RTC_UF;
+		__raw_writew(r, M5441X_RTC_ISR);
+	}
+
+	/* enable write protect */
+	__raw_writew(0x2, M5441X_RTC_CR);
+
+	if (events)
+		rtc_update_irq(rtc, 1, events);
+	return IRQ_HANDLED;
+}
+
+static int __devinit m5441x_rtc_probe(struct platform_device *pdev)
+{
+	struct rtc_device *m5441x_rtc;
+	struct resource *res;
+	int status;
+
+	m5441x_rtc_irq = platform_get_irq(pdev, 0);
+	if (m5441x_rtc_irq < 0) {
+		dev_dbg(&pdev->dev, "platform_get_irq failed\n");
+		return -ENOENT;
+	}
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_dbg(&pdev->dev, "platform_get_resource failed\n");
+		return -ENOENT;
+	}
+	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
+		dev_dbg(&pdev->dev, "request_mem_region failed\n");
+		return -EBUSY;
+	}
+
+	m5441x_rtc_base = ioremap(res->start, resource_size(res));
+	if (!m5441x_rtc_base) {
+		dev_dbg(&pdev->dev, "ioremap failed\n");
+		status = -ENXIO;
+		goto fail0;
+	}
+
+	m5441x_rtc_clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(m5441x_rtc_clk)) {
+		dev_dbg(&pdev->dev, "clk_get failed\n");
+		status = PTR_ERR(m5441x_rtc_clk);
+		goto fail1;
+	}
+
+	m5441x_rtc = rtc_device_register("mcfrtc", &pdev->dev, &m5441x_rtc_ops,
+			THIS_MODULE);
+	if (IS_ERR(m5441x_rtc)) {
+		dev_dbg(&pdev->dev, "rtc_device_register failed\n");
+		status = PTR_ERR(m5441x_rtc);
+		goto fail2;
+	}
+
+	platform_set_drvdata(pdev, m5441x_rtc);
+
+	if (__raw_readw(M5441X_RTC_SR) & M5441X_RTC_SR_PORB)
+		dev_info(&pdev->dev, "power lost? RTC time maybe invalid\n");
+
+	/* disable write protect */
+	__raw_writew(0x0, M5441X_RTC_CR);
+	__raw_writew(0x1, M5441X_RTC_CR);
+	__raw_writew(0x3, M5441X_RTC_CR);
+	__raw_writew(0x2, M5441X_RTC_CR);
+	/* clear any previous alarms */
+	__raw_writew(M5441X_RTC_CR_SWR, M5441X_RTC_CR);
+	/* alarm match on seconds/mmins/days/months/year */
+	__raw_writew(M5441X_RTC_CR_AM3, M5441X_RTC_CR);
+	/* 1Hz alarm */
+	__raw_writew(M5441X_RTC_IER_1HZ, M5441X_RTC_IER);
+	/* enable write protect */
+	__raw_writew(0x2, M5441X_RTC_CR);
+
+	status = request_irq(m5441x_rtc_irq, m5441x_rtc_irq_handler, 0,
+			pdev->name, m5441x_rtc);
+	if (status) {
+		dev_dbg(&pdev->dev, "request_irq failed\n");
+		goto fail3;
+	}
+	return 0;
+
+fail3:
+	platform_set_drvdata(pdev, NULL);
+	rtc_device_unregister(m5441x_rtc);
+fail2:
+	clk_disable(m5441x_rtc_clk);
+	clk_put(m5441x_rtc_clk);
+fail1:
+	iounmap(m5441x_rtc_base);
+fail0:
+	release_mem_region(res->start, resource_size(res));
+	dev_dbg(&pdev->dev, "probe failed\n");
+
+	return status;
+}
+
+static int __devexit m5441x_rtc_remove(struct platform_device *pdev)
+{
+	struct rtc_device *m5441x_rtc = platform_get_drvdata(pdev);
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	free_irq(m5441x_rtc_irq, m5441x_rtc);
+	platform_set_drvdata(pdev, NULL);
+	rtc_device_unregister(m5441x_rtc);
+	clk_disable(m5441x_rtc_clk);
+	clk_put(m5441x_rtc_clk);
+	iounmap(m5441x_rtc_base);
+	release_mem_region(res->start, resource_size(res));
+
+	return 0;
+}
+
+static struct platform_driver m5441x_rtc_driver = {
+	.driver.name	= "mcfrtc",
+	.driver.owner	= THIS_MODULE,
+	.remove		= __devexit_p(m5441x_rtc_remove),
+};
+
+static int __init m5441x_rtc_init(void)
+{
+	return platform_driver_probe(&m5441x_rtc_driver, m5441x_rtc_probe);
+}
+module_init(m5441x_rtc_init);
+
+static void __exit m5441x_rtc_exit(void)
+{
+	platform_driver_unregister(&m5441x_rtc_driver);
+}
+module_exit(m5441x_rtc_exit);
+
+MODULE_AUTHOR("Steven King <sfking@fdwdc.com>");
+MODULE_DESCRIPTION("M5441x RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:rtc");
