rtc-mc13xxx.c revision 77bf2ea8de78ce7dd842409a847b888e720f62d8
11c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König/*
21c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König * Real Time Clock driver for Freescale MC13XXX PMIC
31c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König *
41c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König * (C) 2009 Sascha Hauer, Pengutronix
51c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König * (C) 2009 Uwe Kleine-Koenig, Pengutronix
61c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König *
71c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König * This program is free software; you can redistribute it and/or modify
81c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König * it under the terms of the GNU General Public License version 2 as
91c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König * published by the Free Software Foundation.
101c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König */
111c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
121c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König#include <linux/mfd/mc13xxx.h>
131c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König#include <linux/platform_device.h>
141c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König#include <linux/kernel.h>
151c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König#include <linux/module.h>
161c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König#include <linux/slab.h>
171c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König#include <linux/rtc.h>
181c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
191c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König#define DRIVER_NAME "mc13xxx-rtc"
201c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
211c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König#define MC13XXX_RTCTOD	20
221c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König#define MC13XXX_RTCTODA	21
231c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König#define MC13XXX_RTCDAY	22
241c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König#define MC13XXX_RTCDAYA	23
251c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
261c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königstruct mc13xxx_rtc {
271c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct rtc_device *rtc;
281c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx *mc13xxx;
291c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	int valid;
301c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König};
311c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
321c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königstatic int mc13xxx_rtc_irq_enable_unlocked(struct device *dev,
331c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		unsigned int enabled, int irq)
341c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König{
351c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
361c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	int (*func)(struct mc13xxx *mc13xxx, int irq);
371c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
381c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (!priv->valid)
391c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		return -ENODATA;
401c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
411c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	func = enabled ? mc13xxx_irq_unmask : mc13xxx_irq_mask;
421c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	return func(priv->mc13xxx, irq);
431c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König}
441c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
451c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königstatic int mc13xxx_rtc_irq_enable(struct device *dev,
461c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		unsigned int enabled, int irq)
471c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König{
481c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
491c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	int ret;
501c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
511c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_lock(priv->mc13xxx);
521c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
531c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_rtc_irq_enable_unlocked(dev, enabled, irq);
541c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
551c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_unlock(priv->mc13xxx);
561c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
571c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	return ret;
581c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König}
591c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
601c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königstatic int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
611c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König{
621c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
631c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	unsigned int seconds, days1, days2;
641c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	unsigned long s1970;
651c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	int ret;
661c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
671c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_lock(priv->mc13xxx);
681c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
691c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (!priv->valid) {
701c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		ret = -ENODATA;
711c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
721c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	}
731c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
741c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days1);
751c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (unlikely(ret))
761c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
771c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
781c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTOD, &seconds);
791c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (unlikely(ret))
801c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
811c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
821c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days2);
831c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königout:
841c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_unlock(priv->mc13xxx);
851c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
861c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (ret)
871c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		return ret;
881c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
891c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (days2 == days1 + 1) {
901c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		if (seconds >= 86400 / 2)
911c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König			days2 = days1;
921c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		else
931c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König			days1 = days2;
941c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	}
951c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
961c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (days1 != days2)
971c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		return -EIO;
981c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
991c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	s1970 = days1 * 86400 + seconds;
1001c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1011c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	rtc_time_to_tm(s1970, tm);
1021c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1031c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	return rtc_valid_tm(tm);
1041c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König}
1051c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1061c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königstatic int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs)
1071c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König{
1081c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
1091c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	unsigned int seconds, days;
1101c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	unsigned int alarmseconds;
1111c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	int ret;
1121c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1131c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	seconds = secs % 86400;
1141c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	days = secs / 86400;
1151c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1161c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_lock(priv->mc13xxx);
1171c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1181c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	/*
1191c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	 * temporarily invalidate alarm to prevent triggering it when the day is
1201c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	 * already updated while the time isn't yet.
1211c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	 */
1221c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &alarmseconds);
1231c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (unlikely(ret))
1241c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
1251c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1261c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (alarmseconds < 86400) {
1271c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		ret = mc13xxx_reg_write(priv->mc13xxx,
1281c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König				MC13XXX_RTCTODA, 0x1ffff);
1291c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		if (unlikely(ret))
1301c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König			goto out;
1311c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	}
1321c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1331c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	/*
1341c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	 * write seconds=0 to prevent a day switch between writing days
1351c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	 * and seconds below
1361c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	 */
1371c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, 0);
1381c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (unlikely(ret))
1391c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
1401c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1411c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAY, days);
1421c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (unlikely(ret))
1431c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
1441c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1451c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, seconds);
1461c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (unlikely(ret))
1471c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
1481c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1491c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	/* restore alarm */
1501c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (alarmseconds < 86400) {
1511c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		ret = mc13xxx_reg_write(priv->mc13xxx,
1521c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König				MC13XXX_RTCTODA, alarmseconds);
1531c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		if (unlikely(ret))
1541c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König			goto out;
1551c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	}
1561c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1571c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_RTCRST);
1581c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (unlikely(ret))
1591c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
1601c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1611c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_irq_unmask(priv->mc13xxx, MC13XXX_IRQ_RTCRST);
1621c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königout:
1631c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	priv->valid = !ret;
1641c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1651c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_unlock(priv->mc13xxx);
1661c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1671c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	return ret;
1681c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König}
1691c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1701c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königstatic int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
1711c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König{
1721c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
1731c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	unsigned seconds, days;
1741c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	unsigned long s1970;
1751c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	int enabled, pending;
1761c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	int ret;
1771c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1781c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_lock(priv->mc13xxx);
1791c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1801c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &seconds);
1811c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (unlikely(ret))
1821c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
1831c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (seconds >= 86400) {
1841c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		ret = -ENODATA;
1851c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
1861c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	}
1871c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1881c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days);
1891c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (unlikely(ret))
1901c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
1911c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1921c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_irq_status(priv->mc13xxx, MC13XXX_IRQ_TODA,
1931c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König			&enabled, &pending);
1941c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1951c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königout:
1961c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_unlock(priv->mc13xxx);
1971c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
1981c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (ret)
1991c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		return ret;
2001c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2011c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	alarm->enabled = enabled;
2021c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	alarm->pending = pending;
2031c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2041c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	s1970 = days * 86400 + seconds;
2051c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2061c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	rtc_time_to_tm(s1970, &alarm->time);
2071c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	dev_dbg(dev, "%s: %lu\n", __func__, s1970);
2081c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2091c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	return 0;
2101c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König}
2111c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2121c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königstatic int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
2131c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König{
2141c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
2151c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	unsigned long s1970;
2161c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	unsigned seconds, days;
2171c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	int ret;
2181c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2191c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_lock(priv->mc13xxx);
2201c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2211c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	/* disable alarm to prevent false triggering */
2221c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, 0x1ffff);
2231c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (unlikely(ret))
2241c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
2251c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2261c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_TODA);
2271c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (unlikely(ret))
2281c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
2291c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2301c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = rtc_tm_to_time(&alarm->time, &s1970);
2311c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (unlikely(ret))
2321c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
2331c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2341c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	dev_dbg(dev, "%s: o%2.s %lu\n", __func__, alarm->enabled ? "n" : "ff",
2351c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König			s1970);
2361c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2371c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_rtc_irq_enable_unlocked(dev, alarm->enabled,
2381c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König			MC13XXX_IRQ_TODA);
2391c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (unlikely(ret))
2401c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
2411c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2421c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	seconds = s1970 % 86400;
2431c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	days = s1970 / 86400;
2441c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2451c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAYA, days);
2461c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (unlikely(ret))
2471c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto out;
2481c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2491c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, seconds);
2501c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2511c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königout:
2521c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_unlock(priv->mc13xxx);
2531c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2541c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	return ret;
2551c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König}
2561c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2571c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königstatic irqreturn_t mc13xxx_rtc_alarm_handler(int irq, void *dev)
2581c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König{
2591c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx_rtc *priv = dev;
2601c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx *mc13xxx = priv->mc13xxx;
2611c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2621c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	dev_dbg(&priv->rtc->dev, "Alarm\n");
2631c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2641c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_AF);
2651c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2661c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_irq_ack(mc13xxx, irq);
2671c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2681c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	return IRQ_HANDLED;
2691c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König}
2701c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2711c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königstatic irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev)
2721c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König{
2731c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx_rtc *priv = dev;
2741c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx *mc13xxx = priv->mc13xxx;
2751c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2761c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	dev_dbg(&priv->rtc->dev, "1HZ\n");
2771c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2781c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF);
2791c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2801c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_irq_ack(mc13xxx, irq);
2811c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2821c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	return IRQ_HANDLED;
2831c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König}
2841c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2851c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königstatic int mc13xxx_rtc_alarm_irq_enable(struct device *dev,
2861c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		unsigned int enabled)
2871c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König{
2881c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	return mc13xxx_rtc_irq_enable(dev, enabled, MC13XXX_IRQ_TODA);
2891c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König}
2901c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2911c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königstatic const struct rtc_class_ops mc13xxx_rtc_ops = {
2921c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	.read_time = mc13xxx_rtc_read_time,
2931c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	.set_mmss = mc13xxx_rtc_set_mmss,
2941c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	.read_alarm = mc13xxx_rtc_read_alarm,
2951c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	.set_alarm = mc13xxx_rtc_set_alarm,
2961c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	.alarm_irq_enable = mc13xxx_rtc_alarm_irq_enable,
2971c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König};
2981c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
2991c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königstatic irqreturn_t mc13xxx_rtc_reset_handler(int irq, void *dev)
3001c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König{
3011c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx_rtc *priv = dev;
3021c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx *mc13xxx = priv->mc13xxx;
3031c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3041c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	dev_dbg(&priv->rtc->dev, "RTCRST\n");
3051c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	priv->valid = 0;
3061c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3071c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_irq_mask(mc13xxx, irq);
3081c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3091c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	return IRQ_HANDLED;
3101c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König}
3111c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
312db5cf8d1ac4ac3fa06d89345154ce20068aeb097Uwe Kleine-Königstatic int __init mc13xxx_rtc_probe(struct platform_device *pdev)
3131c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König{
3141c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	int ret;
3151c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx_rtc *priv;
3161c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx *mc13xxx;
3171c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	int rtcrst_pending;
3181c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
319a379fd2458d78d3286c8103aa479839b073c89feJingoo Han	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
3201c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (!priv)
3211c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		return -ENOMEM;
3221c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3231c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx = dev_get_drvdata(pdev->dev.parent);
3241c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	priv->mc13xxx = mc13xxx;
3251c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3261c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	platform_set_drvdata(pdev, priv);
3271c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3281c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_lock(mc13xxx);
3291c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3301c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_RTCRST,
3311c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König			mc13xxx_rtc_reset_handler, DRIVER_NAME, priv);
3321c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (ret)
3331c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto err_reset_irq_request;
3341c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3351c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_irq_status(mc13xxx, MC13XXX_IRQ_RTCRST,
3361c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König			NULL, &rtcrst_pending);
3371c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (ret)
3381c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto err_reset_irq_status;
3391c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3401c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	priv->valid = !rtcrst_pending;
3411c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3421c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_1HZ,
3431c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König			mc13xxx_rtc_update_handler, DRIVER_NAME, priv);
3441c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (ret)
3451c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto err_update_irq_request;
3461c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3471c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_TODA,
3481c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König			mc13xxx_rtc_alarm_handler, DRIVER_NAME, priv);
3491c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (ret)
3501c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		goto err_alarm_irq_request;
3511c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
352156229b352b999cafb86a21b50912975e39b7f44Uwe Kleine-König	mc13xxx_unlock(mc13xxx);
353156229b352b999cafb86a21b50912975e39b7f44Uwe Kleine-König
354a379fd2458d78d3286c8103aa479839b073c89feJingoo Han	priv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
355a379fd2458d78d3286c8103aa479839b073c89feJingoo Han					&mc13xxx_rtc_ops, THIS_MODULE);
3561c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	if (IS_ERR(priv->rtc)) {
3571c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		ret = PTR_ERR(priv->rtc);
3581c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
359156229b352b999cafb86a21b50912975e39b7f44Uwe Kleine-König		mc13xxx_lock(mc13xxx);
360156229b352b999cafb86a21b50912975e39b7f44Uwe Kleine-König
3611c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_TODA, priv);
3621c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königerr_alarm_irq_request:
3631c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3641c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_1HZ, priv);
3651c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königerr_update_irq_request:
3661c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3671c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königerr_reset_irq_status:
3681c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3691c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv);
3701c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königerr_reset_irq_request:
3711c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
372156229b352b999cafb86a21b50912975e39b7f44Uwe Kleine-König		mc13xxx_unlock(mc13xxx);
3731c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	}
3741c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3751c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	return ret;
3761c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König}
3771c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
37877bf2ea8de78ce7dd842409a847b888e720f62d8Alexander Shiyanstatic int mc13xxx_rtc_remove(struct platform_device *pdev)
3791c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König{
3801c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	struct mc13xxx_rtc *priv = platform_get_drvdata(pdev);
3811c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3821c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_lock(priv->mc13xxx);
3831c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3841c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_TODA, priv);
3851c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_1HZ, priv);
3861c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_RTCRST, priv);
3871c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3881c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	mc13xxx_unlock(priv->mc13xxx);
3891c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
3901c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	return 0;
3911c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König}
3921c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
393a46481d7af1e6c59c03f3ddac400d9054f804952Axel Linstatic const struct platform_device_id mc13xxx_rtc_idtable[] = {
3941c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	{
3951c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		.name = "mc13783-rtc",
3961c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	}, {
3971c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		.name = "mc13892-rtc",
39819a1ac505d5f3545ebc5b0a195d65cef4da94bb5Uwe Kleine-König	}, {
39919a1ac505d5f3545ebc5b0a195d65cef4da94bb5Uwe Kleine-König		.name = "mc34708-rtc",
4001c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	},
4010f636fc16f80fe64261ce39440e49a259ff2b0daUwe Kleine-König	{ /* sentinel */ }
4021c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König};
4030f636fc16f80fe64261ce39440e49a259ff2b0daUwe Kleine-KönigMODULE_DEVICE_TABLE(platform, mc13xxx_rtc_idtable);
4041c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
4051c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-Königstatic struct platform_driver mc13xxx_rtc_driver = {
4061c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	.id_table = mc13xxx_rtc_idtable,
40777bf2ea8de78ce7dd842409a847b888e720f62d8Alexander Shiyan	.remove = mc13xxx_rtc_remove,
4081c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	.driver = {
4091c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		.name = DRIVER_NAME,
4101c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König		.owner = THIS_MODULE,
4111c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König	},
4121c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König};
4131c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
41409fb7ad15aa62116f96e0f7b62c7723e636786f1Jingoo Hanmodule_platform_driver_probe(mc13xxx_rtc_driver, &mc13xxx_rtc_probe);
4151c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-König
4161c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-KönigMODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
4171c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-KönigMODULE_DESCRIPTION("RTC driver for Freescale MC13XXX PMIC");
4181c97872b80691f6bd3e46ec431a0d59dc75cb8daUwe Kleine-KönigMODULE_LICENSE("GPL v2");
419