summary refs log tree commit diff
path: root/drivers/rtc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-12-18 18:18:03 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-18 18:18:03 -0800
commitb0b3a37b908b5906524c11f3ca12cd7c9d4adc1c (patch)
tree1fd9e48f602bef936322b6bc526db7ffa80bda09 /drivers/rtc
parent3be134e5152f08e8bd3c2afdaac723f64d93c2bb (diff)
parentd3e5925902dc0f639efc3641e07fca2bd7af5441 (diff)
downloadlinux-b0b3a37b908b5906524c11f3ca12cd7c9d4adc1c.tar.gz
Merge tag 'rtc-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni:
  "Subsystem:
   - non-modular drivers are now explicitly non-modular

  New driver:
    - Epson Toyocom rtc-7301sf/dg

  Drivers:
   - cmos: reject unsupported alarm values wrt the RTC capabilities
   - ds1307: ACPI support
   - jz4740: DT support, jz4780 handling, can now be used as a system
     power controller
   - mcp795: many fixes, in particular proper month handling
   - twl: driver is now DT only"

* tag 'rtc-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (31 commits)
  rtc: mcp795: Fix whitespace and indentation.
  rtc: mcp795: Prefer using the BIT() macro.
  rtc: mcp795: fix month write resetting date to 1.
  rtc: mcp795: fix time range difference between linux and RTC chip.
  rtc: mcp795: fix bitmask value for leap year (LP).
  rtc: mcp795: use bcd2bin/bin2bcd.
  rtc: add support for EPSON TOYOCOM RTC-7301SF/DG
  rtc: ds1307: Add ACPI support
  rtc: imxdi: (trivial) fix a typo
  rtc: ds1374: Merge conditional + WARN_ON()
  rtc: twl: make driver DT only
  rtc: twl: kill static variables
  rtc: fix typos in Kconfig
  rtc: jz4740: make the driver builtin only
  rtc: jz4740: remove unused EXPORT_SYMBOL
  Documentation: bindings: fix twl-rtc documentation
  rtc: Enable compile testing for Maxim and Samsung drivers
  MIPS: jz4740: Remove obsolete code
  MIPS: qi_lb60: Probe RTC driver from DT and use it as power controller
  MIPS: jz4740: DTS: Probe the jz4740-rtc driver from devicetree
  ...
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig38
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-cmos.c75
-rw-r--r--drivers/rtc/rtc-ds1307.c52
-rw-r--r--drivers/rtc/rtc-ds1374.c4
-rw-r--r--drivers/rtc/rtc-imxdi.c2
-rw-r--r--drivers/rtc/rtc-jz4740.c154
-rw-r--r--drivers/rtc/rtc-lib.c4
-rw-r--r--drivers/rtc/rtc-mcp795.c122
-rw-r--r--drivers/rtc/rtc-pcf85063.c7
-rw-r--r--drivers/rtc/rtc-r7301.c453
-rw-r--r--drivers/rtc/rtc-starfire.c10
-rw-r--r--drivers/rtc/rtc-sun4v.c10
-rw-r--r--drivers/rtc/rtc-twl.c202
14 files changed, 975 insertions, 159 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index e859d148aba9..c93c5a8fba32 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -303,7 +303,7 @@ config RTC_DRV_MAX6900
 
 config RTC_DRV_MAX8907
 	tristate "Maxim MAX8907"
-	depends on MFD_MAX8907
+	depends on MFD_MAX8907 || COMPILE_TEST
 	help
 	  If you say yes here you will get support for the
 	  RTC of Maxim MAX8907 PMIC.
@@ -343,7 +343,7 @@ config RTC_DRV_MAX8997
 
 config RTC_DRV_MAX77686
 	tristate "Maxim MAX77686"
-	depends on MFD_MAX77686 || MFD_MAX77620
+	depends on MFD_MAX77686 || MFD_MAX77620 || COMPILE_TEST
 	help
 	  If you say yes here you will get support for the
 	  RTC of Maxim MAX77686/MAX77620/MAX77802 PMIC.
@@ -481,6 +481,7 @@ config RTC_DRV_TWL92330
 config RTC_DRV_TWL4030
 	tristate "TI TWL4030/TWL5030/TWL6030/TPS659x0"
 	depends on TWL4030_CORE
+	depends on OF
 	help
 	  If you say yes here you get support for the RTC on the
 	  TWL4030/TWL5030/TWL6030 family chips, used mostly with OMAP3 platforms.
@@ -602,7 +603,8 @@ config RTC_DRV_RV8803
 
 config RTC_DRV_S5M
 	tristate "Samsung S2M/S5M series"
-	depends on MFD_SEC_CORE
+	depends on MFD_SEC_CORE || COMPILE_TEST
+	select REGMAP_IRQ
 	help
 	  If you say yes here you will get support for the
 	  RTC of Samsung S2MPS14 and S5M PMIC series.
@@ -820,8 +822,8 @@ config RTC_DRV_RV3029_HWMON
 
 comment "Platform RTC drivers"
 
-# this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h>
-# requires <asm/mc146818rtc.h> defining CMOS_READ/CMOS_WRITE, and a
+# this 'CMOS' RTC driver is arch dependent because it requires
+# <asm/mc146818rtc.h> defining CMOS_READ/CMOS_WRITE, and a
 # global rtc_lock ... it's not yet just another platform_device.
 
 config RTC_DRV_CMOS
@@ -1549,14 +1551,11 @@ config RTC_DRV_MPC5121
 	  will be called rtc-mpc5121.
 
 config RTC_DRV_JZ4740
-	tristate "Ingenic JZ4740 SoC"
-	depends on MACH_JZ4740 || COMPILE_TEST
+	bool "Ingenic JZ4740 SoC"
+	depends on MACH_INGENIC || COMPILE_TEST
 	help
-	  If you say yes here you get support for the Ingenic JZ4740 SoC RTC
-	  controller.
-
-	  This driver can also be buillt as a module. If so, the module
-	  will be called rtc-jz4740.
+	  If you say yes here you get support for the Ingenic JZ47xx SoCs RTC
+	  controllers.
 
 config RTC_DRV_LPC24XX
 	tristate "NXP RTC for LPC178x/18xx/408x/43xx"
@@ -1567,7 +1566,7 @@ config RTC_DRV_LPC24XX
 	  NXP LPC178x/18xx/408x/43xx devices.
 
 	  If you have one of the devices above enable this driver to use
-	  the hardware RTC. This driver can also be buillt as a module. If
+	  the hardware RTC. This driver can also be built as a module. If
 	  so, the module will be called rtc-lpc24xx.
 
 config RTC_DRV_LPC32XX
@@ -1576,7 +1575,7 @@ config RTC_DRV_LPC32XX
 	help
 	  This enables support for the NXP RTC in the LPC32XX
 
-	  This driver can also be buillt as a module. If so, the module
+	  This driver can also be built as a module. If so, the module
 	  will be called rtc-lpc32xx.
 
 config RTC_DRV_PM8XXX
@@ -1706,6 +1705,17 @@ config RTC_DRV_PIC32
 	   This driver can also be built as a module. If so, the module
 	   will be called rtc-pic32
 
+config RTC_DRV_R7301
+	tristate "EPSON TOYOCOM RTC-7301SF/DG"
+	select REGMAP_MMIO
+	depends on OF && HAS_IOMEM
+	help
+	   If you say yes here you get support for the EPSON TOYOCOM
+	   RTC-7301SF/DG chips.
+
+	   This driver can also be built as a module. If so, the module
+	   will be called rtc-r7301.
+
 comment "HID Sensor RTC drivers"
 
 config RTC_DRV_HID_SENSOR_TIME
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 1ac694a330c8..f13ab1c5c222 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -120,6 +120,7 @@ obj-$(CONFIG_RTC_DRV_PM8XXX)	+= rtc-pm8xxx.o
 obj-$(CONFIG_RTC_DRV_PS3)	+= rtc-ps3.o
 obj-$(CONFIG_RTC_DRV_PUV3)	+= rtc-puv3.o
 obj-$(CONFIG_RTC_DRV_PXA)	+= rtc-pxa.o
+obj-$(CONFIG_RTC_DRV_R7301)	+= rtc-r7301.o
 obj-$(CONFIG_RTC_DRV_R9701)	+= rtc-r9701.o
 obj-$(CONFIG_RTC_DRV_RC5T583)	+= rtc-rc5t583.o
 obj-$(CONFIG_RTC_DRV_RK808)	+= rtc-rk808.o
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 38aa8e1906c2..f4a96dbdabf2 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -332,14 +332,86 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask)
 	cmos_checkintr(cmos, rtc_control);
 }
 
+static int cmos_validate_alarm(struct device *dev, struct rtc_wkalrm *t)
+{
+	struct cmos_rtc *cmos = dev_get_drvdata(dev);
+	struct rtc_time now;
+
+	cmos_read_time(dev, &now);
+
+	if (!cmos->day_alrm) {
+		time64_t t_max_date;
+		time64_t t_alrm;
+
+		t_max_date = rtc_tm_to_time64(&now);
+		t_max_date += 24 * 60 * 60 - 1;
+		t_alrm = rtc_tm_to_time64(&t->time);
+		if (t_alrm > t_max_date) {
+			dev_err(dev,
+				"Alarms can be up to one day in the future\n");
+			return -EINVAL;
+		}
+	} else if (!cmos->mon_alrm) {
+		struct rtc_time max_date = now;
+		time64_t t_max_date;
+		time64_t t_alrm;
+		int max_mday;
+
+		if (max_date.tm_mon == 11) {
+			max_date.tm_mon = 0;
+			max_date.tm_year += 1;
+		} else {
+			max_date.tm_mon += 1;
+		}
+		max_mday = rtc_month_days(max_date.tm_mon, max_date.tm_year);
+		if (max_date.tm_mday > max_mday)
+			max_date.tm_mday = max_mday;
+
+		t_max_date = rtc_tm_to_time64(&max_date);
+		t_max_date -= 1;
+		t_alrm = rtc_tm_to_time64(&t->time);
+		if (t_alrm > t_max_date) {
+			dev_err(dev,
+				"Alarms can be up to one month in the future\n");
+			return -EINVAL;
+		}
+	} else {
+		struct rtc_time max_date = now;
+		time64_t t_max_date;
+		time64_t t_alrm;
+		int max_mday;
+
+		max_date.tm_year += 1;
+		max_mday = rtc_month_days(max_date.tm_mon, max_date.tm_year);
+		if (max_date.tm_mday > max_mday)
+			max_date.tm_mday = max_mday;
+
+		t_max_date = rtc_tm_to_time64(&max_date);
+		t_max_date -= 1;
+		t_alrm = rtc_tm_to_time64(&t->time);
+		if (t_alrm > t_max_date) {
+			dev_err(dev,
+				"Alarms can be up to one year in the future\n");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 {
 	struct cmos_rtc	*cmos = dev_get_drvdata(dev);
 	unsigned char mon, mday, hrs, min, sec, rtc_control;
+	int ret;
 
 	if (!is_valid_irq(cmos->irq))
 		return -EIO;
 
+	ret = cmos_validate_alarm(dev, t);
+	if (ret < 0)
+		return ret;
+
 	mon = t->time.tm_mon + 1;
 	mday = t->time.tm_mday;
 	hrs = t->time.tm_hour;
@@ -707,9 +779,6 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
 
 	spin_unlock_irq(&rtc_lock);
 
-	/* FIXME:
-	 * <asm-generic/rtc.h> doesn't know 12-hour mode either.
-	 */
 	if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) {
 		dev_warn(dev, "only 24-hr supported\n");
 		retval = -ENXIO;
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 4e31036ee259..4ad97be48043 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -11,6 +11,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/acpi.h>
 #include <linux/bcd.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
@@ -191,6 +192,26 @@ static const struct i2c_device_id ds1307_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, ds1307_id);
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id ds1307_acpi_ids[] = {
+	{ .id = "DS1307", .driver_data = ds_1307 },
+	{ .id = "DS1337", .driver_data = ds_1337 },
+	{ .id = "DS1338", .driver_data = ds_1338 },
+	{ .id = "DS1339", .driver_data = ds_1339 },
+	{ .id = "DS1388", .driver_data = ds_1388 },
+	{ .id = "DS1340", .driver_data = ds_1340 },
+	{ .id = "DS3231", .driver_data = ds_3231 },
+	{ .id = "M41T00", .driver_data = m41t00 },
+	{ .id = "MCP7940X", .driver_data = mcp794xx },
+	{ .id = "MCP7941X", .driver_data = mcp794xx },
+	{ .id = "PT7C4338", .driver_data = ds_1307 },
+	{ .id = "RX8025", .driver_data = rx_8025 },
+	{ .id = "ISL12057", .driver_data = ds_1337 },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, ds1307_acpi_ids);
+#endif
+
 /*----------------------------------------------------------------------*/
 
 #define BLOCK_DATA_MAX_TRIES 10
@@ -874,17 +895,17 @@ static u8 do_trickle_setup_ds1339(struct i2c_client *client,
 	return setup;
 }
 
-static void ds1307_trickle_of_init(struct i2c_client *client,
-				   struct chip_desc *chip)
+static void ds1307_trickle_init(struct i2c_client *client,
+				struct chip_desc *chip)
 {
 	uint32_t ohms = 0;
 	bool diode = true;
 
 	if (!chip->do_trickle_setup)
 		goto out;
-	if (of_property_read_u32(client->dev.of_node, "trickle-resistor-ohms" , &ohms))
+	if (device_property_read_u32(&client->dev, "trickle-resistor-ohms", &ohms))
 		goto out;
-	if (of_property_read_bool(client->dev.of_node, "trickle-diode-disable"))
+	if (device_property_read_bool(&client->dev, "trickle-diode-disable"))
 		diode = false;
 	chip->trickle_charger_setup = chip->do_trickle_setup(client,
 							     ohms, diode);
@@ -1268,7 +1289,7 @@ static int ds1307_probe(struct i2c_client *client,
 	struct ds1307		*ds1307;
 	int			err = -ENODEV;
 	int			tmp, wday;
-	struct chip_desc	*chip = &chips[id->driver_data];
+	struct chip_desc	*chip;
 	struct i2c_adapter	*adapter = to_i2c_adapter(client->dev.parent);
 	bool			want_irq = false;
 	bool			ds1307_can_wakeup_device = false;
@@ -1297,11 +1318,23 @@ static int ds1307_probe(struct i2c_client *client,
 	i2c_set_clientdata(client, ds1307);
 
 	ds1307->client	= client;
-	ds1307->type	= id->driver_data;
+	if (id) {
+		chip = &chips[id->driver_data];
+		ds1307->type = id->driver_data;
+	} else {
+		const struct acpi_device_id *acpi_id;
+
+		acpi_id = acpi_match_device(ACPI_PTR(ds1307_acpi_ids),
+					    &client->dev);
+		if (!acpi_id)
+			return -ENODEV;
+		chip = &chips[acpi_id->driver_data];
+		ds1307->type = acpi_id->driver_data;
+	}
 
-	if (!pdata && client->dev.of_node)
-		ds1307_trickle_of_init(client, chip);
-	else if (pdata && pdata->trickle_charger_setup)
+	if (!pdata)
+		ds1307_trickle_init(client, chip);
+	else if (pdata->trickle_charger_setup)
 		chip->trickle_charger_setup = pdata->trickle_charger_setup;
 
 	if (chip->trickle_charger_setup && chip->trickle_charger_reg) {
@@ -1678,6 +1711,7 @@ static int ds1307_remove(struct i2c_client *client)
 static struct i2c_driver ds1307_driver = {
 	.driver = {
 		.name	= "rtc-ds1307",
+		.acpi_match_table = ACPI_PTR(ds1307_acpi_ids),
 	},
 	.probe		= ds1307_probe,
 	.remove		= ds1307_remove,
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 3b3049c8c9e0..52429f0a57cc 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -89,10 +89,8 @@ static int ds1374_read_rtc(struct i2c_client *client, u32 *time,
 	int ret;
 	int i;
 
-	if (nbytes > 4) {
-		WARN_ON(1);
+	if (WARN_ON(nbytes > 4))
 		return -EINVAL;
-	}
 
 	ret = i2c_smbus_read_i2c_block_data(client, reg, nbytes, buf);
 
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c
index 8d8049bdfaf6..67b56b80dc70 100644
--- a/drivers/rtc/rtc-imxdi.c
+++ b/drivers/rtc/rtc-imxdi.c
@@ -67,7 +67,7 @@
 #define DSR_ETAD  (1 << 21)      /* External tamper A detected */
 #define DSR_EBD   (1 << 20)      /* External boot detected */
 #define DSR_SAD   (1 << 19)      /* SCC alarm detected */
-#define DSR_TTD   (1 << 18)      /* Temperatur tamper detected */
+#define DSR_TTD   (1 << 18)      /* Temperature tamper detected */
 #define DSR_CTD   (1 << 17)      /* Clock tamper detected */
 #define DSR_VTD   (1 << 16)      /* Voltage tamper detected */
 #define DSR_WBF   (1 << 10)      /* Write Busy Flag (synchronous) */
diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c
index 5e14651b71a8..72918c1ba092 100644
--- a/drivers/rtc/rtc-jz4740.c
+++ b/drivers/rtc/rtc-jz4740.c
@@ -14,10 +14,12 @@
  *
  */
 
+#include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 #include <linux/rtc.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
@@ -27,8 +29,14 @@
 #define JZ_REG_RTC_SEC_ALARM	0x08
 #define JZ_REG_RTC_REGULATOR	0x0C
 #define JZ_REG_RTC_HIBERNATE	0x20
+#define JZ_REG_RTC_WAKEUP_FILTER	0x24
+#define JZ_REG_RTC_RESET_COUNTER	0x28
 #define JZ_REG_RTC_SCRATCHPAD	0x34
 
+/* The following are present on the jz4780 */
+#define JZ_REG_RTC_WENR	0x3C
+#define JZ_RTC_WENR_WEN	BIT(31)
+
 #define JZ_RTC_CTRL_WRDY	BIT(7)
 #define JZ_RTC_CTRL_1HZ		BIT(6)
 #define JZ_RTC_CTRL_1HZ_IRQ	BIT(5)
@@ -37,16 +45,34 @@
 #define JZ_RTC_CTRL_AE		BIT(2)
 #define JZ_RTC_CTRL_ENABLE	BIT(0)
 
+/* Magic value to enable writes on jz4780 */
+#define JZ_RTC_WENR_MAGIC	0xA55A
+
+#define JZ_RTC_WAKEUP_FILTER_MASK	0x0000FFE0
+#define JZ_RTC_RESET_COUNTER_MASK	0x00000FE0
+
+enum jz4740_rtc_type {
+	ID_JZ4740,
+	ID_JZ4780,
+};
+
 struct jz4740_rtc {
 	void __iomem *base;
+	enum jz4740_rtc_type type;
 
 	struct rtc_device *rtc;
+	struct clk *clk;
 
 	int irq;
 
 	spinlock_t lock;
+
+	unsigned int min_wakeup_pin_assert_time;
+	unsigned int reset_pin_assert_time;
 };
 
+static struct device *dev_for_power_off;
+
 static inline uint32_t jz4740_rtc_reg_read(struct jz4740_rtc *rtc, size_t reg)
 {
 	return readl(rtc->base + reg);
@@ -64,11 +90,33 @@ static int jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc)
 	return timeout ? 0 : -EIO;
 }
 
+static inline int jz4780_rtc_enable_write(struct jz4740_rtc *rtc)
+{
+	uint32_t ctrl;
+	int ret, timeout = 1000;
+
+	ret = jz4740_rtc_wait_write_ready(rtc);
+	if (ret != 0)
+		return ret;
+
+	writel(JZ_RTC_WENR_MAGIC, rtc->base + JZ_REG_RTC_WENR);
+
+	do {
+		ctrl = readl(rtc->base + JZ_REG_RTC_WENR);
+	} while (!(ctrl & JZ_RTC_WENR_WEN) && --timeout);
+
+	return timeout ? 0 : -EIO;
+}
+
 static inline int jz4740_rtc_reg_write(struct jz4740_rtc *rtc, size_t reg,
 	uint32_t val)
 {
-	int ret;
-	ret = jz4740_rtc_wait_write_ready(rtc);
+	int ret = 0;
+
+	if (rtc->type >= ID_JZ4780)
+		ret = jz4780_rtc_enable_write(rtc);
+	if (ret == 0)
+		ret = jz4740_rtc_wait_write_ready(rtc);
 	if (ret == 0)
 		writel(val, rtc->base + reg);
 
@@ -203,12 +251,57 @@ static irqreturn_t jz4740_rtc_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-void jz4740_rtc_poweroff(struct device *dev)
+static void jz4740_rtc_poweroff(struct device *dev)
 {
 	struct jz4740_rtc *rtc = dev_get_drvdata(dev);
 	jz4740_rtc_reg_write(rtc, JZ_REG_RTC_HIBERNATE, 1);
 }
-EXPORT_SYMBOL_GPL(jz4740_rtc_poweroff);
+
+static void jz4740_rtc_power_off(void)
+{
+	struct jz4740_rtc *rtc = dev_get_drvdata(dev_for_power_off);
+	unsigned long rtc_rate;
+	unsigned long wakeup_filter_ticks;
+	unsigned long reset_counter_ticks;
+
+	clk_prepare_enable(rtc->clk);
+
+	rtc_rate = clk_get_rate(rtc->clk);
+
+	/*
+	 * Set minimum wakeup pin assertion time: 100 ms.
+	 * Range is 0 to 2 sec if RTC is clocked at 32 kHz.
+	 */
+	wakeup_filter_ticks =
+		(rtc->min_wakeup_pin_assert_time * rtc_rate) / 1000;
+	if (wakeup_filter_ticks < JZ_RTC_WAKEUP_FILTER_MASK)
+		wakeup_filter_ticks &= JZ_RTC_WAKEUP_FILTER_MASK;
+	else
+		wakeup_filter_ticks = JZ_RTC_WAKEUP_FILTER_MASK;
+	jz4740_rtc_reg_write(rtc,
+			     JZ_REG_RTC_WAKEUP_FILTER, wakeup_filter_ticks);
+
+	/*
+	 * Set reset pin low-level assertion time after wakeup: 60 ms.
+	 * Range is 0 to 125 ms if RTC is clocked at 32 kHz.
+	 */
+	reset_counter_ticks = (rtc->reset_pin_assert_time * rtc_rate) / 1000;
+	if (reset_counter_ticks < JZ_RTC_RESET_COUNTER_MASK)
+		reset_counter_ticks &= JZ_RTC_RESET_COUNTER_MASK;
+	else
+		reset_counter_ticks = JZ_RTC_RESET_COUNTER_MASK;
+	jz4740_rtc_reg_write(rtc,
+			     JZ_REG_RTC_RESET_COUNTER, reset_counter_ticks);
+
+	jz4740_rtc_poweroff(dev_for_power_off);
+	machine_halt();
+}
+
+static const struct of_device_id jz4740_rtc_of_match[] = {
+	{ .compatible = "ingenic,jz4740-rtc", .data = (void *)ID_JZ4740 },
+	{ .compatible = "ingenic,jz4780-rtc", .data = (void *)ID_JZ4780 },
+	{},
+};
 
 static int jz4740_rtc_probe(struct platform_device *pdev)
 {
@@ -216,11 +309,20 @@ static int jz4740_rtc_probe(struct platform_device *pdev)
 	struct jz4740_rtc *rtc;
 	uint32_t scratchpad;
 	struct resource *mem;
+	const struct platform_device_id *id = platform_get_device_id(pdev);
+	const struct of_device_id *of_id = of_match_device(
+			jz4740_rtc_of_match, &pdev->dev);
+	struct device_node *np = pdev->dev.of_node;
 
 	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
 	if (!rtc)
 		return -ENOMEM;
 
+	if (of_id)
+		rtc->type = (enum jz4740_rtc_type)of_id->data;
+	else
+		rtc->type = id->driver_data;
+
 	rtc->irq = platform_get_irq(pdev, 0);
 	if (rtc->irq < 0) {
 		dev_err(&pdev->dev, "Failed to get platform irq\n");
@@ -232,6 +334,12 @@ static int jz4740_rtc_probe(struct platform_device *pdev)
 	if (IS_ERR(rtc->base))
 		return PTR_ERR(rtc->base);
 
+	rtc->clk = devm_clk_get(&pdev->dev, "rtc");
+	if (IS_ERR(rtc->clk)) {
+		dev_err(&pdev->dev, "Failed to get RTC clock\n");
+		return PTR_ERR(rtc->clk);
+	}
+
 	spin_lock_init(&rtc->lock);
 
 	platform_set_drvdata(pdev, rtc);
@@ -263,6 +371,27 @@ static int jz4740_rtc_probe(struct platform_device *pdev)
 		}
 	}
 
+	if (np && of_device_is_system_power_controller(np)) {
+		if (!pm_power_off) {
+			/* Default: 60ms */
+			rtc->reset_pin_assert_time = 60;
+			of_property_read_u32(np, "reset-pin-assert-time-ms",
+					     &rtc->reset_pin_assert_time);
+
+			/* Default: 100ms */
+			rtc->min_wakeup_pin_assert_time = 100;
+			of_property_read_u32(np,
+					     "min-wakeup-pin-assert-time-ms",
+					     &rtc->min_wakeup_pin_assert_time);
+
+			dev_for_power_off = &pdev->dev;
+			pm_power_off = jz4740_rtc_power_off;
+		} else {
+			dev_warn(&pdev->dev,
+				 "Poweroff handler already present!\n");
+		}
+	}
+
 	return 0;
 }
 
@@ -295,17 +424,20 @@ static const struct dev_pm_ops jz4740_pm_ops = {
 #define JZ4740_RTC_PM_OPS NULL
 #endif  /* CONFIG_PM */
 
+static const struct platform_device_id jz4740_rtc_ids[] = {
+	{ "jz4740-rtc", ID_JZ4740 },
+	{ "jz4780-rtc", ID_JZ4780 },
+	{}
+};
+
 static struct platform_driver jz4740_rtc_driver = {
 	.probe	 = jz4740_rtc_probe,
 	.driver	 = {
 		.name  = "jz4740-rtc",
 		.pm    = JZ4740_RTC_PM_OPS,
+		.of_match_table = of_match_ptr(jz4740_rtc_of_match),
 	},
+	.id_table = jz4740_rtc_ids,
 };
 
-module_platform_driver(jz4740_rtc_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("RTC driver for the JZ4740 SoC\n");
-MODULE_ALIAS("platform:jz4740-rtc");
+builtin_platform_driver(jz4740_rtc_driver);
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
index e6bfb9c42a10..1ae7da5cfc60 100644
--- a/drivers/rtc/rtc-lib.c
+++ b/drivers/rtc/rtc-lib.c
@@ -11,7 +11,7 @@
  * published by the Free Software Foundation.
 */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/rtc.h>
 
 static const unsigned char rtc_days_in_month[] = {
@@ -148,5 +148,3 @@ struct rtc_time rtc_ktime_to_tm(ktime_t kt)
 	return ret;
 }
 EXPORT_SYMBOL_GPL(rtc_ktime_to_tm);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-mcp795.c b/drivers/rtc/rtc-mcp795.c
index 4021fd04cb0a..ce75e421ba00 100644
--- a/drivers/rtc/rtc-mcp795.c
+++ b/drivers/rtc/rtc-mcp795.c
@@ -12,7 +12,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- * */
+ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -21,6 +21,8 @@
 #include <linux/spi/spi.h>
 #include <linux/rtc.h>
 #include <linux/of.h>
+#include <linux/bcd.h>
+#include <linux/delay.h>
 
 /* MCP795 Instructions, see datasheet table 3-1 */
 #define MCP795_EEREAD	0x03
@@ -29,7 +31,7 @@
 #define MCP795_EEWREN	0x06
 #define MCP795_SRREAD	0x05
 #define MCP795_SRWRITE	0x01
-#define MCP795_READ		0x13
+#define MCP795_READ	0x13
 #define MCP795_WRITE	0x12
 #define MCP795_UNLOCK	0x14
 #define MCP795_IDWRITE	0x32
@@ -37,8 +39,17 @@
 #define MCP795_CLRWDT	0x44
 #define MCP795_CLRRAM	0x54
 
-#define MCP795_ST_BIT	0x80
-#define MCP795_24_BIT	0x40
+/* MCP795 RTCC registers, see datasheet table 4-1 */
+#define MCP795_REG_SECONDS	0x01
+#define MCP795_REG_DAY		0x04
+#define MCP795_REG_MONTH	0x06
+#define MCP795_REG_CONTROL	0x08
+
+#define MCP795_ST_BIT		BIT(7)
+#define MCP795_24_BIT		BIT(6)
+#define MCP795_LP_BIT		BIT(5)
+#define MCP795_EXTOSC_BIT	BIT(3)
+#define MCP795_OSCON_BIT	BIT(5)
 
 static int mcp795_rtcc_read(struct device *dev, u8 addr, u8 *buf, u8 count)
 {
@@ -93,30 +104,97 @@ static int mcp795_rtcc_set_bits(struct device *dev, u8 addr, u8 mask, u8 state)
 	return ret;
 }
 
+static int mcp795_stop_oscillator(struct device *dev, bool *extosc)
+{
+	int retries = 5;
+	int ret;
+	u8 data;
+
+	ret = mcp795_rtcc_set_bits(dev, MCP795_REG_SECONDS, MCP795_ST_BIT, 0);
+	if (ret)
+		return ret;
+	ret = mcp795_rtcc_read(dev, MCP795_REG_CONTROL, &data, 1);
+	if (ret)
+		return ret;
+	*extosc = !!(data & MCP795_EXTOSC_BIT);
+	ret = mcp795_rtcc_set_bits(
+				dev, MCP795_REG_CONTROL, MCP795_EXTOSC_BIT, 0);
+	if (ret)
+		return ret;
+	/* wait for the OSCON bit to clear */
+	do {
+		usleep_range(700, 800);
+		ret = mcp795_rtcc_read(dev, MCP795_REG_DAY, &data, 1);
+		if (ret)
+			break;
+		if (!(data & MCP795_OSCON_BIT))
+			break;
+
+	} while (--retries);
+
+	return !retries ? -EIO : ret;
+}
+
+static int mcp795_start_oscillator(struct device *dev, bool *extosc)
+{
+	if (extosc) {
+		u8 data = *extosc ? MCP795_EXTOSC_BIT : 0;
+		int ret;
+
+		ret = mcp795_rtcc_set_bits(
+			dev, MCP795_REG_CONTROL, MCP795_EXTOSC_BIT, data);
+		if (ret)
+			return ret;
+	}
+	return mcp795_rtcc_set_bits(
+			dev, MCP795_REG_SECONDS, MCP795_ST_BIT, MCP795_ST_BIT);
+}
+
 static int mcp795_set_time(struct device *dev, struct rtc_time *tim)
 {
 	int ret;
 	u8 data[7];
+	bool extosc;
+
+	/* Stop RTC and store current value of EXTOSC bit */
+	ret = mcp795_stop_oscillator(dev, &extosc);
+	if (ret)
+		return ret;
 
 	/* Read first, so we can leave config bits untouched */
-	ret = mcp795_rtcc_read(dev, 0x01, data, sizeof(data));
+	ret = mcp795_rtcc_read(dev, MCP795_REG_SECONDS, data, sizeof(data));
 
 	if (ret)
 		return ret;
 
-	data[0] = (data[0] & 0x80) | ((tim->tm_sec / 10) << 4) | (tim->tm_sec % 10);
-	data[1] = (data[1] & 0x80) | ((tim->tm_min / 10) << 4) | (tim->tm_min % 10);
-	data[2] = ((tim->tm_hour / 10) << 4) | (tim->tm_hour % 10);
-	data[4] = ((tim->tm_mday / 10) << 4) | ((tim->tm_mday) % 10);
-	data[5] = (data[5] & 0x10) | (tim->tm_mon / 10) | (tim->tm_mon % 10);
+	data[0] = (data[0] & 0x80) | bin2bcd(tim->tm_sec);
+	data[1] = (data[1] & 0x80) | bin2bcd(tim->tm_min);
+	data[2] = bin2bcd(tim->tm_hour);
+	data[4] = bin2bcd(tim->tm_mday);
+	data[5] = (data[5] & MCP795_LP_BIT) | bin2bcd(tim->tm_mon + 1);
 
 	if (tim->tm_year > 100)
 		tim->tm_year -= 100;
 
-	data[6] = ((tim->tm_year / 10) << 4) | (tim->tm_year % 10);
+	data[6] = bin2bcd(tim->tm_year);
+
+	/* Always write the date and month using a separate Write command.
+	 * This is a workaround for a know silicon issue that some combinations
+	 * of date and month values may result in the date being reset to 1.
+	 */
+	ret = mcp795_rtcc_write(dev, MCP795_REG_SECONDS, data, 5);
+	if (ret)
+		return ret;
 
-	ret = mcp795_rtcc_write(dev, 0x01, data, sizeof(data));
+	ret = mcp795_rtcc_write(dev, MCP795_REG_MONTH, &data[5], 2);
+	if (ret)
+		return ret;
 
+	/* Start back RTC and restore previous value of EXTOSC bit.
+	 * There is no need to clear EXTOSC bit when the previous value was 0
+	 * because it was already cleared when stopping the RTC oscillator.
+	 */
+	ret = mcp795_start_oscillator(dev, extosc ? &extosc : NULL);
 	if (ret)
 		return ret;
 
@@ -132,17 +210,17 @@ static int mcp795_read_time(struct device *dev, struct rtc_time *tim)
 	int ret;
 	u8 data[7];
 
-	ret = mcp795_rtcc_read(dev, 0x01, data, sizeof(data));
+	ret = mcp795_rtcc_read(dev, MCP795_REG_SECONDS, data, sizeof(data));
 
 	if (ret)
 		return ret;
 
-	tim->tm_sec		= ((data[0] & 0x70) >> 4) * 10 + (data[0] & 0x0f);
-	tim->tm_min		= ((data[1] & 0x70) >> 4) * 10 + (data[1] & 0x0f);
-	tim->tm_hour	= ((data[2] & 0x30) >> 4) * 10 + (data[2] & 0x0f);
-	tim->tm_mday	= ((data[4] & 0x30) >> 4) * 10 + (data[4] & 0x0f);
-	tim->tm_mon		= ((data[5] & 0x10) >> 4) * 10 + (data[5] & 0x0f);
-	tim->tm_year	= ((data[6] & 0xf0) >> 4) * 10 + (data[6] & 0x0f) + 100; /* Assume we are in 20xx */
+	tim->tm_sec	= bcd2bin(data[0] & 0x7F);
+	tim->tm_min	= bcd2bin(data[1] & 0x7F);
+	tim->tm_hour	= bcd2bin(data[2] & 0x3F);
+	tim->tm_mday	= bcd2bin(data[4] & 0x3F);
+	tim->tm_mon	= bcd2bin(data[5] & 0x1F) - 1;
+	tim->tm_year	= bcd2bin(data[6]) + 100; /* Assume we are in 20xx */
 
 	dev_dbg(dev, "Read from mcp795: %04d-%02d-%02d %02d:%02d:%02d\n",
 				tim->tm_year + 1900, tim->tm_mon, tim->tm_mday,
@@ -169,13 +247,13 @@ static int mcp795_probe(struct spi_device *spi)
 		return ret;
 	}
 
-	/* Start the oscillator */
-	mcp795_rtcc_set_bits(&spi->dev, 0x01, MCP795_ST_BIT, MCP795_ST_BIT);
+	/* Start the oscillator but don't set the value of EXTOSC bit */
+	mcp795_start_oscillator(&spi->dev, NULL);
 	/* Clear the 12 hour mode flag*/
 	mcp795_rtcc_set_bits(&spi->dev, 0x03, MCP795_24_BIT, 0);
 
 	rtc = devm_rtc_device_register(&spi->dev, "rtc-mcp795",
-								&mcp795_rtc_ops, THIS_MODULE);
+					&mcp795_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc))
 		return PTR_ERR(rtc);
 
diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
index efb0a08ac117..a06dff994c83 100644
--- a/drivers/rtc/rtc-pcf85063.c
+++ b/drivers/rtc/rtc-pcf85063.c
@@ -191,12 +191,19 @@ static int pcf85063_probe(struct i2c_client *client,
 				const struct i2c_device_id *id)
 {
 	struct rtc_device *rtc;
+	int err;
 
 	dev_dbg(&client->dev, "%s\n", __func__);
 
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
 		return -ENODEV;
 
+	err = i2c_smbus_read_byte_data(client, PCF85063_REG_CTRL1);
+	if (err < 0) {
+		dev_err(&client->dev, "RTC chip is not present\n");
+		return err;
+	}
+
 	rtc = devm_rtc_device_register(&client->dev,
 				       pcf85063_driver.driver.name,
 				       &pcf85063_rtc_ops, THIS_MODULE);
diff --git a/drivers/rtc/rtc-r7301.c b/drivers/rtc/rtc-r7301.c
new file mode 100644
index 000000000000..28d540885f3d
--- /dev/null
+++ b/drivers/rtc/rtc-r7301.c
@@ -0,0 +1,453 @@
+/*
+ * EPSON TOYOCOM RTC-7301SF/DG Driver
+ *
+ * Copyright (c) 2016 Akinobu Mita <akinobu.mita@gmail.com>
+ *
+ * Based on rtc-rp5c01.c
+ *
+ * Datasheet: http://www5.epsondevice.com/en/products/parallel/rtc7301sf.html
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/regmap.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#define DRV_NAME "rtc-r7301"
+
+#define RTC7301_1_SEC		0x0	/* Bank 0 and Band 1 */
+#define RTC7301_10_SEC		0x1	/* Bank 0 and Band 1 */
+#define RTC7301_AE		BIT(3)
+#define RTC7301_1_MIN		0x2	/* Bank 0 and Band 1 */
+#define RTC7301_10_MIN		0x3	/* Bank 0 and Band 1 */
+#define RTC7301_1_HOUR		0x4	/* Bank 0 and Band 1 */
+#define RTC7301_10_HOUR		0x5	/* Bank 0 and Band 1 */
+#define RTC7301_DAY_OF_WEEK	0x6	/* Bank 0 and Band 1 */
+#define RTC7301_1_DAY		0x7	/* Bank 0 and Band 1 */
+#define RTC7301_10_DAY		0x8	/* Bank 0 and Band 1 */
+#define RTC7301_1_MONTH		0x9	/* Bank 0 */
+#define RTC7301_10_MONTH	0xa	/* Bank 0 */
+#define RTC7301_1_YEAR		0xb	/* Bank 0 */
+#define RTC7301_10_YEAR		0xc	/* Bank 0 */
+#define RTC7301_100_YEAR	0xd	/* Bank 0 */
+#define RTC7301_1000_YEAR	0xe	/* Bank 0 */
+#define RTC7301_ALARM_CONTROL	0xe	/* Bank 1 */
+#define RTC7301_ALARM_CONTROL_AIE	BIT(0)
+#define RTC7301_ALARM_CONTROL_AF	BIT(1)
+#define RTC7301_TIMER_CONTROL	0xe	/* Bank 2 */
+#define RTC7301_TIMER_CONTROL_TIE	BIT(0)
+#define RTC7301_TIMER_CONTROL_TF	BIT(1)
+#define RTC7301_CONTROL		0xf	/* All banks */
+#define RTC7301_CONTROL_BUSY		BIT(0)
+#define RTC7301_CONTROL_STOP		BIT(1)
+#define RTC7301_CONTROL_BANK_SEL_0	BIT(2)
+#define RTC7301_CONTROL_BANK_SEL_1	BIT(3)
+
+struct rtc7301_priv {
+	struct regmap *regmap;
+	int irq;
+	spinlock_t lock;
+	u8 bank;
+};
+
+static const struct regmap_config rtc7301_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 8,
+	.reg_stride = 4,
+};
+
+static u8 rtc7301_read(struct rtc7301_priv *priv, unsigned int reg)
+{
+	int reg_stride = regmap_get_reg_stride(priv->regmap);
+	unsigned int val;
+
+	regmap_read(priv->regmap, reg_stride * reg, &val);
+
+	return val & 0xf;
+}
+
+static void rtc7301_write(struct rtc7301_priv *priv, u8 val, unsigned int reg)
+{
+	int reg_stride = regmap_get_reg_stride(priv->regmap);
+
+	regmap_write(priv->regmap, reg_stride * reg, val);
+}
+
+static void rtc7301_update_bits(struct rtc7301_priv *priv, unsigned int reg,
+				u8 mask, u8 val)
+{
+	int reg_stride = regmap_get_reg_stride(priv->regmap);
+
+	regmap_update_bits(priv->regmap, reg_stride * reg, mask, val);
+}
+
+static int rtc7301_wait_while_busy(struct rtc7301_priv *priv)
+{
+	int retries = 100;
+
+	while (retries-- > 0) {
+		u8 val;
+
+		val = rtc7301_read(priv, RTC7301_CONTROL);
+		if (!(val & RTC7301_CONTROL_BUSY))
+			return 0;
+
+		usleep_range(200, 300);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static void rtc7301_stop(struct rtc7301_priv *priv)
+{
+	rtc7301_update_bits(priv, RTC7301_CONTROL, RTC7301_CONTROL_STOP,
+			    RTC7301_CONTROL_STOP);
+}
+
+static void rtc7301_start(struct rtc7301_priv *priv)
+{
+	rtc7301_update_bits(priv, RTC7301_CONTROL, RTC7301_CONTROL_STOP, 0);
+}
+
+static void rtc7301_select_bank(struct rtc7301_priv *priv, u8 bank)
+{
+	u8 val = 0;
+
+	if (bank == priv->bank)
+		return;
+
+	if (bank & BIT(0))
+		val |= RTC7301_CONTROL_BANK_SEL_0;
+	if (bank & BIT(1))
+		val |= RTC7301_CONTROL_BANK_SEL_1;
+
+	rtc7301_update_bits(priv, RTC7301_CONTROL,
+			    RTC7301_CONTROL_BANK_SEL_0 |
+			    RTC7301_CONTROL_BANK_SEL_1, val);
+
+	priv->bank = bank;
+}
+
+static void rtc7301_get_time(struct rtc7301_priv *priv, struct rtc_time *tm,
+			     bool alarm)
+{
+	int year;
+
+	tm->tm_sec = rtc7301_read(priv, RTC7301_1_SEC);
+	tm->tm_sec += (rtc7301_read(priv, RTC7301_10_SEC) & ~RTC7301_AE) * 10;
+	tm->tm_min = rtc7301_read(priv, RTC7301_1_MIN);
+	tm->tm_min += (rtc7301_read(priv, RTC7301_10_MIN) & ~RTC7301_AE) * 10;
+	tm->tm_hour = rtc7301_read(priv, RTC7301_1_HOUR);
+	tm->tm_hour += (rtc7301_read(priv, RTC7301_10_HOUR) & ~RTC7301_AE) * 10;
+	tm->tm_mday = rtc7301_read(priv, RTC7301_1_DAY);
+	tm->tm_mday += (rtc7301_read(priv, RTC7301_10_DAY) & ~RTC7301_AE) * 10;
+
+	if (alarm) {
+		tm->tm_wday = -1;
+		tm->tm_mon = -1;
+		tm->tm_year = -1;
+		tm->tm_yday = -1;
+		tm->tm_isdst = -1;
+		return;
+	}
+
+	tm->tm_wday = (rtc7301_read(priv, RTC7301_DAY_OF_WEEK) & ~RTC7301_AE);
+	tm->tm_mon = rtc7301_read(priv, RTC7301_10_MONTH) * 10 +
+		     rtc7301_read(priv, RTC7301_1_MONTH) - 1;
+	year = rtc7301_read(priv, RTC7301_1000_YEAR) * 1000 +
+	       rtc7301_read(priv, RTC7301_100_YEAR) * 100 +
+	       rtc7301_read(priv, RTC7301_10_YEAR) * 10 +
+	       rtc7301_read(priv, RTC7301_1_YEAR);
+
+	tm->tm_year = year - 1900;
+}
+
+static void rtc7301_write_time(struct rtc7301_priv *priv, struct rtc_time *tm,
+			       bool alarm)
+{
+	int year;
+
+	rtc7301_write(priv, tm->tm_sec % 10, RTC7301_1_SEC);
+	rtc7301_write(priv, tm->tm_sec / 10, RTC7301_10_SEC);
+
+	rtc7301_write(priv, tm->tm_min % 10, RTC7301_1_MIN);
+	rtc7301_write(priv, tm->tm_min / 10, RTC7301_10_MIN);
+
+	rtc7301_write(priv, tm->tm_hour % 10, RTC7301_1_HOUR);
+	rtc7301_write(priv, tm->tm_hour / 10, RTC7301_10_HOUR);
+
+	rtc7301_write(priv, tm->tm_mday % 10, RTC7301_1_DAY);
+	rtc7301_write(priv, tm->tm_mday / 10, RTC7301_10_DAY);
+
+	/* Don't care for alarm register */
+	rtc7301_write(priv, alarm ? RTC7301_AE : tm->tm_wday,
+		      RTC7301_DAY_OF_WEEK);
+
+	if (alarm)
+		return;
+
+	rtc7301_write(priv, (tm->tm_mon + 1) % 10, RTC7301_1_MONTH);
+	rtc7301_write(priv, (tm->tm_mon + 1) / 10, RTC7301_10_MONTH);
+
+	year = tm->tm_year + 1900;
+
+	rtc7301_write(priv, year % 10, RTC7301_1_YEAR);
+	rtc7301_write(priv, (year / 10) % 10, RTC7301_10_YEAR);
+	rtc7301_write(priv, (year / 100) % 10, RTC7301_100_YEAR);
+	rtc7301_write(priv, year / 1000, RTC7301_1000_YEAR);
+}
+
+static void rtc7301_alarm_irq(struct rtc7301_priv *priv, unsigned int enabled)
+{
+	rtc7301_update_bits(priv, RTC7301_ALARM_CONTROL,
+			    RTC7301_ALARM_CONTROL_AF |
+			    RTC7301_ALARM_CONTROL_AIE,
+			    enabled ? RTC7301_ALARM_CONTROL_AIE : 0);
+}
+
+static int rtc7301_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct rtc7301_priv *priv = dev_get_drvdata(dev);
+	unsigned long flags;
+	int err;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	rtc7301_select_bank(priv, 0);
+
+	err = rtc7301_wait_while_busy(priv);
+	if (!err)
+		rtc7301_get_time(priv, tm, false);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return err ? err : rtc_valid_tm(tm);
+}
+
+static int rtc7301_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct rtc7301_priv *priv = dev_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	rtc7301_stop(priv);
+	usleep_range(200, 300);
+	rtc7301_select_bank(priv, 0);
+	rtc7301_write_time(priv, tm, false);
+	rtc7301_start(priv);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+static int rtc7301_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct rtc7301_priv *priv = dev_get_drvdata(dev);
+	unsigned long flags;
+	u8 alrm_ctrl;
+
+	if (priv->irq <= 0)
+		return -EINVAL;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	rtc7301_select_bank(priv, 1);
+	rtc7301_get_time(priv, &alarm->time, true);
+
+	alrm_ctrl = rtc7301_read(priv, RTC7301_ALARM_CONTROL);
+
+	alarm->enabled = !!(alrm_ctrl & RTC7301_ALARM_CONTROL_AIE);
+	alarm->pending = !!(alrm_ctrl & RTC7301_ALARM_CONTROL_AF);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+static int rtc7301_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct rtc7301_priv *priv = dev_get_drvdata(dev);
+	unsigned long flags;
+
+	if (priv->irq <= 0)
+		return -EINVAL;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	rtc7301_select_bank(priv, 1);
+	rtc7301_write_time(priv, &alarm->time, true);
+	rtc7301_alarm_irq(priv, alarm->enabled);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+static int rtc7301_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+	struct rtc7301_priv *priv = dev_get_drvdata(dev);
+	unsigned long flags;
+
+	if (priv->irq <= 0)
+		return -EINVAL;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	rtc7301_select_bank(priv, 1);
+	rtc7301_alarm_irq(priv, enabled);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+static const struct rtc_class_ops rtc7301_rtc_ops = {
+	.read_time	= rtc7301_read_time,
+	.set_time	= rtc7301_set_time,
+	.read_alarm	= rtc7301_read_alarm,
+	.set_alarm	= rtc7301_set_alarm,
+	.alarm_irq_enable = rtc7301_alarm_irq_enable,
+};
+
+static irqreturn_t rtc7301_irq_handler(int irq, void *dev_id)
+{
+	struct rtc_device *rtc = dev_id;
+	struct rtc7301_priv *priv = dev_get_drvdata(rtc->dev.parent);
+	unsigned long flags;
+	irqreturn_t ret = IRQ_NONE;
+	u8 alrm_ctrl;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	rtc7301_select_bank(priv, 1);
+
+	alrm_ctrl = rtc7301_read(priv, RTC7301_ALARM_CONTROL);
+	if (alrm_ctrl & RTC7301_ALARM_CONTROL_AF) {
+		ret = IRQ_HANDLED;
+		rtc7301_alarm_irq(priv, false);
+		rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return ret;
+}
+
+static void rtc7301_init(struct rtc7301_priv *priv)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	rtc7301_select_bank(priv, 2);
+	rtc7301_write(priv, 0, RTC7301_TIMER_CONTROL);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int __init rtc7301_rtc_probe(struct platform_device *dev)
+{
+	struct resource *res;
+	void __iomem *regs;
+	struct rtc7301_priv *priv;
+	struct rtc_device *rtc;
+	int ret;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	regs = devm_ioremap_resource(&dev->dev, res);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	priv->regmap = devm_regmap_init_mmio(&dev->dev, regs,
+					     &rtc7301_regmap_config);
+	if (IS_ERR(priv->regmap))
+		return PTR_ERR(priv->regmap);
+
+	priv->irq = platform_get_irq(dev, 0);
+
+	spin_lock_init(&priv->lock);
+	priv->bank = -1;
+
+	rtc7301_init(priv);
+
+	platform_set_drvdata(dev, priv);
+
+	rtc = devm_rtc_device_register(&dev->dev, DRV_NAME, &rtc7301_rtc_ops,
+				       THIS_MODULE);
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
+
+	if (priv->irq > 0) {
+		ret = devm_request_irq(&dev->dev, priv->irq,
+				       rtc7301_irq_handler, IRQF_SHARED,
+				       dev_name(&dev->dev), rtc);
+		if (ret) {
+			priv->irq = 0;
+			dev_err(&dev->dev, "unable to request IRQ\n");
+		} else {
+			device_set_wakeup_capable(&dev->dev, true);
+		}
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+
+static int rtc7301_suspend(struct device *dev)
+{
+	struct rtc7301_priv *priv = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		enable_irq_wake(priv->irq);
+
+	return 0;
+}
+
+static int rtc7301_resume(struct device *dev)
+{
+	struct rtc7301_priv *priv = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		disable_irq_wake(priv->irq);
+
+	return 0;
+}
+
+#endif
+
+static SIMPLE_DEV_PM_OPS(rtc7301_pm_ops, rtc7301_suspend, rtc7301_resume);
+
+static const struct of_device_id rtc7301_dt_match[] = {
+	{ .compatible = "epson,rtc7301sf" },
+	{ .compatible = "epson,rtc7301dg" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, rtc7301_dt_match);
+
+static struct platform_driver rtc7301_rtc_driver = {
+	.driver	= {
+		.name = DRV_NAME,
+		.of_match_table = rtc7301_dt_match,
+		.pm = &rtc7301_pm_ops,
+	},
+};
+
+module_platform_driver_probe(rtc7301_rtc_driver, rtc7301_rtc_probe);
+
+MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("EPSON TOYOCOM RTC-7301SF/DG Driver");
+MODULE_ALIAS("platform:rtc-r7301");
diff --git a/drivers/rtc/rtc-starfire.c b/drivers/rtc/rtc-starfire.c
index 83a057a03060..7fc36973fa33 100644
--- a/drivers/rtc/rtc-starfire.c
+++ b/drivers/rtc/rtc-starfire.c
@@ -1,20 +1,18 @@
 /* rtc-starfire.c: Starfire platform RTC driver.
  *
+ * Author: David S. Miller
+ * License: GPL
+ *
  * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
 
 #include <asm/oplib.h>
 
-MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
-MODULE_DESCRIPTION("Starfire RTC driver");
-MODULE_LICENSE("GPL");
-
 static u32 starfire_get_time(void)
 {
 	static char obp_gettod[32];
@@ -57,4 +55,4 @@ static struct platform_driver starfire_rtc_driver = {
 	},
 };
 
-module_platform_driver_probe(starfire_rtc_driver, starfire_rtc_probe);
+builtin_platform_driver_probe(starfire_rtc_driver, starfire_rtc_probe);
diff --git a/drivers/rtc/rtc-sun4v.c b/drivers/rtc/rtc-sun4v.c
index 7c696c12f28f..11bc562eba5d 100644
--- a/drivers/rtc/rtc-sun4v.c
+++ b/drivers/rtc/rtc-sun4v.c
@@ -1,12 +1,14 @@
 /* rtc-sun4v.c: Hypervisor based RTC for SUN4V systems.
  *
+ * Author: David S. Miller
+ * License: GPL
+ *
  * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/rtc.h>
@@ -98,8 +100,4 @@ static struct platform_driver sun4v_rtc_driver = {
 	},
 };
 
-module_platform_driver_probe(sun4v_rtc_driver, sun4v_rtc_probe);
-
-MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
-MODULE_DESCRIPTION("SUN4V RTC driver");
-MODULE_LICENSE("GPL");
+builtin_platform_driver_probe(sun4v_rtc_driver, sun4v_rtc_probe);
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index 176720b7b9e5..c18c39212ce6 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -33,6 +33,10 @@
 
 #include <linux/i2c/twl.h>
 
+enum twl_class {
+	TWL_4030 = 0,
+	TWL_6030,
+};
 
 /*
  * RTC block register offsets (use TWL_MODULE_RTC)
@@ -136,16 +140,30 @@ static const u8 twl6030_rtc_reg_map[] = {
 #define ALL_TIME_REGS		6
 
 /*----------------------------------------------------------------------*/
-static u8  *rtc_reg_map;
+struct twl_rtc {
+	struct device *dev;
+	struct rtc_device *rtc;
+	u8 *reg_map;
+	/*
+	 * Cache the value for timer/alarm interrupts register; this is
+	 * only changed by callers holding rtc ops lock (or resume).
+	 */
+	unsigned char rtc_irq_bits;
+	bool wake_enabled;
+#ifdef CONFIG_PM_SLEEP
+	unsigned char irqstat;
+#endif
+	enum twl_class class;
+};
 
 /*
  * Supports 1 byte read from TWL RTC register.
  */
-static int twl_rtc_read_u8(u8 *data, u8 reg)
+static int twl_rtc_read_u8(struct twl_rtc *twl_rtc, u8 *data, u8 reg)
 {
 	int ret;
 
-	ret = twl_i2c_read_u8(TWL_MODULE_RTC, data, (rtc_reg_map[reg]));
+	ret = twl_i2c_read_u8(TWL_MODULE_RTC, data, (twl_rtc->reg_map[reg]));
 	if (ret < 0)
 		pr_err("Could not read TWL register %X - error %d\n", reg, ret);
 	return ret;
@@ -154,11 +172,11 @@ static int twl_rtc_read_u8(u8 *data, u8 reg)
 /*
  * Supports 1 byte write to TWL RTC registers.
  */
-static int twl_rtc_write_u8(u8 data, u8 reg)
+static int twl_rtc_write_u8(struct twl_rtc *twl_rtc, u8 data, u8 reg)
 {
 	int ret;
 
-	ret = twl_i2c_write_u8(TWL_MODULE_RTC, data, (rtc_reg_map[reg]));
+	ret = twl_i2c_write_u8(TWL_MODULE_RTC, data, (twl_rtc->reg_map[reg]));
 	if (ret < 0)
 		pr_err("Could not write TWL register %X - error %d\n",
 		       reg, ret);
@@ -166,28 +184,22 @@ static int twl_rtc_write_u8(u8 data, u8 reg)
 }
 
 /*
- * Cache the value for timer/alarm interrupts register; this is
- * only changed by callers holding rtc ops lock (or resume).
- */
-static unsigned char rtc_irq_bits;
-
-/*
  * Enable 1/second update and/or alarm interrupts.
  */
-static int set_rtc_irq_bit(unsigned char bit)
+static int set_rtc_irq_bit(struct twl_rtc *twl_rtc, unsigned char bit)
 {
 	unsigned char val;
 	int ret;
 
 	/* if the bit is set, return from here */
-	if (rtc_irq_bits & bit)
+	if (twl_rtc->rtc_irq_bits & bit)
 		return 0;
 
-	val = rtc_irq_bits | bit;
+	val = twl_rtc->rtc_irq_bits | bit;
 	val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M;
-	ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
+	ret = twl_rtc_write_u8(twl_rtc, val, REG_RTC_INTERRUPTS_REG);
 	if (ret == 0)
-		rtc_irq_bits = val;
+		twl_rtc->rtc_irq_bits = val;
 
 	return ret;
 }
@@ -195,19 +207,19 @@ static int set_rtc_irq_bit(unsigned char bit)
 /*
  * Disable update and/or alarm interrupts.
  */
-static int mask_rtc_irq_bit(unsigned char bit)
+static int mask_rtc_irq_bit(struct twl_rtc *twl_rtc, unsigned char bit)
 {
 	unsigned char val;
 	int ret;
 
 	/* if the bit is clear, return from here */
-	if (!(rtc_irq_bits & bit))
+	if (!(twl_rtc->rtc_irq_bits & bit))
 		return 0;
 
-	val = rtc_irq_bits & ~bit;
-	ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
+	val = twl_rtc->rtc_irq_bits & ~bit;
+	ret = twl_rtc_write_u8(twl_rtc, val, REG_RTC_INTERRUPTS_REG);
 	if (ret == 0)
-		rtc_irq_bits = val;
+		twl_rtc->rtc_irq_bits = val;
 
 	return ret;
 }
@@ -215,21 +227,23 @@ static int mask_rtc_irq_bit(unsigned char bit)
 static int twl_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
 {
 	struct platform_device *pdev = to_platform_device(dev);
+	struct twl_rtc *twl_rtc = dev_get_drvdata(dev);
 	int irq = platform_get_irq(pdev, 0);
-	static bool twl_rtc_wake_enabled;
 	int ret;
 
 	if (enabled) {
-		ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
-		if (device_can_wakeup(dev) && !twl_rtc_wake_enabled) {
+		ret = set_rtc_irq_bit(twl_rtc,
+				      BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+		if (device_can_wakeup(dev) && !twl_rtc->wake_enabled) {
 			enable_irq_wake(irq);
-			twl_rtc_wake_enabled = true;
+			twl_rtc->wake_enabled = true;
 		}
 	} else {
-		ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
-		if (twl_rtc_wake_enabled) {
+		ret = mask_rtc_irq_bit(twl_rtc,
+				       BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+		if (twl_rtc->wake_enabled) {
 			disable_irq_wake(irq);
-			twl_rtc_wake_enabled = false;
+			twl_rtc->wake_enabled = false;
 		}
 	}
 
@@ -247,21 +261,23 @@ static int twl_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
  */
 static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
+	struct twl_rtc *twl_rtc = dev_get_drvdata(dev);
 	unsigned char rtc_data[ALL_TIME_REGS];
 	int ret;
 	u8 save_control;
 	u8 rtc_control;
 
-	ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
+	ret = twl_rtc_read_u8(twl_rtc, &save_control, REG_RTC_CTRL_REG);
 	if (ret < 0) {
 		dev_err(dev, "%s: reading CTRL_REG, error %d\n", __func__, ret);
 		return ret;
 	}
 	/* for twl6030/32 make sure BIT_RTC_CTRL_REG_GET_TIME_M is clear */
-	if (twl_class_is_6030()) {
+	if (twl_rtc->class == TWL_6030) {
 		if (save_control & BIT_RTC_CTRL_REG_GET_TIME_M) {
 			save_control &= ~BIT_RTC_CTRL_REG_GET_TIME_M;
-			ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+			ret = twl_rtc_write_u8(twl_rtc, save_control,
+					       REG_RTC_CTRL_REG);
 			if (ret < 0) {
 				dev_err(dev, "%s clr GET_TIME, error %d\n",
 					__func__, ret);
@@ -274,17 +290,17 @@ static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm)
 	rtc_control = save_control | BIT_RTC_CTRL_REG_GET_TIME_M;
 
 	/* for twl6030/32 enable read access to static shadowed registers */
-	if (twl_class_is_6030())
+	if (twl_rtc->class == TWL_6030)
 		rtc_control |= BIT_RTC_CTRL_REG_RTC_V_OPT;
 
-	ret = twl_rtc_write_u8(rtc_control, REG_RTC_CTRL_REG);
+	ret = twl_rtc_write_u8(twl_rtc, rtc_control, REG_RTC_CTRL_REG);
 	if (ret < 0) {
 		dev_err(dev, "%s: writing CTRL_REG, error %d\n", __func__, ret);
 		return ret;
 	}
 
 	ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data,
-			(rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS);
+			(twl_rtc->reg_map[REG_SECONDS_REG]), ALL_TIME_REGS);
 
 	if (ret < 0) {
 		dev_err(dev, "%s: reading data, error %d\n", __func__, ret);
@@ -292,8 +308,8 @@ static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm)
 	}
 
 	/* for twl6030 restore original state of rtc control register */
-	if (twl_class_is_6030()) {
-		ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+	if (twl_rtc->class == TWL_6030) {
+		ret = twl_rtc_write_u8(twl_rtc, save_control, REG_RTC_CTRL_REG);
 		if (ret < 0) {
 			dev_err(dev, "%s: restore CTRL_REG, error %d\n",
 				__func__, ret);
@@ -313,6 +329,7 @@ static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm)
 
 static int twl_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
+	struct twl_rtc *twl_rtc = dev_get_drvdata(dev);
 	unsigned char save_control;
 	unsigned char rtc_data[ALL_TIME_REGS];
 	int ret;
@@ -325,18 +342,18 @@ static int twl_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	rtc_data[5] = bin2bcd(tm->tm_year - 100);
 
 	/* Stop RTC while updating the TC registers */
-	ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
+	ret = twl_rtc_read_u8(twl_rtc, &save_control, REG_RTC_CTRL_REG);
 	if (ret < 0)
 		goto out;
 
 	save_control &= ~BIT_RTC_CTRL_REG_STOP_RTC_M;
-	ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+	ret = twl_rtc_write_u8(twl_rtc, save_control, REG_RTC_CTRL_REG);
 	if (ret < 0)
 		goto out;
 
 	/* update all the time registers in one shot */
 	ret = twl_i2c_write(TWL_MODULE_RTC, rtc_data,
-		(rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS);
+		(twl_rtc->reg_map[REG_SECONDS_REG]), ALL_TIME_REGS);
 	if (ret < 0) {
 		dev_err(dev, "rtc_set_time error %d\n", ret);
 		goto out;
@@ -344,7 +361,7 @@ static int twl_rtc_set_time(struct device *dev, struct rtc_time *tm)
 
 	/* Start back RTC */
 	save_control |= BIT_RTC_CTRL_REG_STOP_RTC_M;
-	ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+	ret = twl_rtc_write_u8(twl_rtc, save_control, REG_RTC_CTRL_REG);
 
 out:
 	return ret;
@@ -355,11 +372,12 @@ out:
  */
 static int twl_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
 {
+	struct twl_rtc *twl_rtc = dev_get_drvdata(dev);
 	unsigned char rtc_data[ALL_TIME_REGS];
 	int ret;
 
 	ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data,
-			(rtc_reg_map[REG_ALARM_SECONDS_REG]), ALL_TIME_REGS);
+			twl_rtc->reg_map[REG_ALARM_SECONDS_REG], ALL_TIME_REGS);
 	if (ret < 0) {
 		dev_err(dev, "rtc_read_alarm error %d\n", ret);
 		return ret;
@@ -374,7 +392,7 @@ static int twl_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
 	alm->time.tm_year = bcd2bin(rtc_data[5]) + 100;
 
 	/* report cached alarm enable state */
-	if (rtc_irq_bits & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M)
+	if (twl_rtc->rtc_irq_bits & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M)
 		alm->enabled = 1;
 
 	return ret;
@@ -382,6 +400,8 @@ static int twl_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
 
 static int twl_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 {
+	struct twl_rtc *twl_rtc = dev_get_drvdata(dev);
+
 	unsigned char alarm_data[ALL_TIME_REGS];
 	int ret;
 
@@ -398,7 +418,7 @@ static int twl_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 
 	/* update all the alarm registers in one shot */
 	ret = twl_i2c_write(TWL_MODULE_RTC, alarm_data,
-		(rtc_reg_map[REG_ALARM_SECONDS_REG]), ALL_TIME_REGS);
+			twl_rtc->reg_map[REG_ALARM_SECONDS_REG], ALL_TIME_REGS);
 	if (ret) {
 		dev_err(dev, "rtc_set_alarm error %d\n", ret);
 		goto out;
@@ -410,14 +430,15 @@ out:
 	return ret;
 }
 
-static irqreturn_t twl_rtc_interrupt(int irq, void *rtc)
+static irqreturn_t twl_rtc_interrupt(int irq, void *data)
 {
+	struct twl_rtc *twl_rtc = data;
 	unsigned long events;
 	int ret = IRQ_NONE;
 	int res;
 	u8 rd_reg;
 
-	res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
+	res = twl_rtc_read_u8(twl_rtc, &rd_reg, REG_RTC_STATUS_REG);
 	if (res)
 		goto out;
 	/*
@@ -431,12 +452,12 @@ static irqreturn_t twl_rtc_interrupt(int irq, void *rtc)
 	else
 		events = RTC_IRQF | RTC_PF;
 
-	res = twl_rtc_write_u8(BIT_RTC_STATUS_REG_ALARM_M,
-				   REG_RTC_STATUS_REG);
+	res = twl_rtc_write_u8(twl_rtc, BIT_RTC_STATUS_REG_ALARM_M,
+			       REG_RTC_STATUS_REG);
 	if (res)
 		goto out;
 
-	if (twl_class_is_4030()) {
+	if (twl_rtc->class == TWL_4030) {
 		/* Clear on Read enabled. RTC_IT bit of TWL4030_INT_PWR_ISR1
 		 * needs 2 reads to clear the interrupt. One read is done in
 		 * do_twl_pwrirq(). Doing the second read, to clear
@@ -455,7 +476,7 @@ static irqreturn_t twl_rtc_interrupt(int irq, void *rtc)
 	}
 
 	/* Notify RTC core on event */
-	rtc_update_irq(rtc, 1, events);
+	rtc_update_irq(twl_rtc->rtc, 1, events);
 
 	ret = IRQ_HANDLED;
 out:
@@ -474,21 +495,36 @@ static const struct rtc_class_ops twl_rtc_ops = {
 
 static int twl_rtc_probe(struct platform_device *pdev)
 {
-	struct rtc_device *rtc;
+	struct twl_rtc *twl_rtc;
+	struct device_node *np = pdev->dev.of_node;
 	int ret = -EINVAL;
 	int irq = platform_get_irq(pdev, 0);
 	u8 rd_reg;
 
+	if (!np) {
+		dev_err(&pdev->dev, "no DT info\n");
+		return -EINVAL;
+	}
+
 	if (irq <= 0)
 		return ret;
 
-	/* Initialize the register map */
-	if (twl_class_is_4030())
-		rtc_reg_map = (u8 *)twl4030_rtc_reg_map;
-	else
-		rtc_reg_map = (u8 *)twl6030_rtc_reg_map;
+	twl_rtc = devm_kzalloc(&pdev->dev, sizeof(*twl_rtc), GFP_KERNEL);
+	if (!twl_rtc)
+		return -ENOMEM;
 
-	ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
+	if (twl_class_is_4030()) {
+		twl_rtc->class = TWL_4030;
+		twl_rtc->reg_map = (u8 *)twl4030_rtc_reg_map;
+	} else if (twl_class_is_6030()) {
+		twl_rtc->class = TWL_6030;
+		twl_rtc->reg_map = (u8 *)twl6030_rtc_reg_map;
+	} else {
+		dev_err(&pdev->dev, "TWL Class not supported.\n");
+		return -EINVAL;
+	}
+
+	ret = twl_rtc_read_u8(twl_rtc, &rd_reg, REG_RTC_STATUS_REG);
 	if (ret < 0)
 		return ret;
 
@@ -499,11 +535,11 @@ static int twl_rtc_probe(struct platform_device *pdev)
 		dev_warn(&pdev->dev, "Pending Alarm interrupt detected.\n");
 
 	/* Clear RTC Power up reset and pending alarm interrupts */
-	ret = twl_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG);
+	ret = twl_rtc_write_u8(twl_rtc, rd_reg, REG_RTC_STATUS_REG);
 	if (ret < 0)
 		return ret;
 
-	if (twl_class_is_6030()) {
+	if (twl_rtc->class == TWL_6030) {
 		twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
 			REG_INT_MSK_LINE_A);
 		twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
@@ -511,40 +547,42 @@ static int twl_rtc_probe(struct platform_device *pdev)
 	}
 
 	dev_info(&pdev->dev, "Enabling TWL-RTC\n");
-	ret = twl_rtc_write_u8(BIT_RTC_CTRL_REG_STOP_RTC_M, REG_RTC_CTRL_REG);
+	ret = twl_rtc_write_u8(twl_rtc, BIT_RTC_CTRL_REG_STOP_RTC_M,
+			       REG_RTC_CTRL_REG);
 	if (ret < 0)
 		return ret;
 
 	/* ensure interrupts are disabled, bootloaders can be strange */
-	ret = twl_rtc_write_u8(0, REG_RTC_INTERRUPTS_REG);
+	ret = twl_rtc_write_u8(twl_rtc, 0, REG_RTC_INTERRUPTS_REG);
 	if (ret < 0)
 		dev_warn(&pdev->dev, "unable to disable interrupt\n");
 
 	/* init cached IRQ enable bits */
-	ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
+	ret = twl_rtc_read_u8(twl_rtc, &twl_rtc->rtc_irq_bits,
+			      REG_RTC_INTERRUPTS_REG);
 	if (ret < 0)
 		return ret;
 
+	platform_set_drvdata(pdev, twl_rtc);
 	device_init_wakeup(&pdev->dev, 1);
 
-	rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
+	twl_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
 					&twl_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc)) {
+	if (IS_ERR(twl_rtc->rtc)) {
 		dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
-			PTR_ERR(rtc));
-		return PTR_ERR(rtc);
+			PTR_ERR(twl_rtc->rtc));
+		return PTR_ERR(twl_rtc->rtc);
 	}
 
 	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
 					twl_rtc_interrupt,
 					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
-					dev_name(&rtc->dev), rtc);
+					dev_name(&twl_rtc->rtc->dev), twl_rtc);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "IRQ is not free.\n");
 		return ret;
 	}
 
-	platform_set_drvdata(pdev, rtc);
 	return 0;
 }
 
@@ -554,10 +592,12 @@ static int twl_rtc_probe(struct platform_device *pdev)
  */
 static int twl_rtc_remove(struct platform_device *pdev)
 {
+	struct twl_rtc *twl_rtc = platform_get_drvdata(pdev);
+
 	/* leave rtc running, but disable irqs */
-	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
-	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
-	if (twl_class_is_6030()) {
+	mask_rtc_irq_bit(twl_rtc, BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+	mask_rtc_irq_bit(twl_rtc, BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+	if (twl_rtc->class == TWL_6030) {
 		twl6030_interrupt_mask(TWL6030_RTC_INT_MASK,
 			REG_INT_MSK_LINE_A);
 		twl6030_interrupt_mask(TWL6030_RTC_INT_MASK,
@@ -569,40 +609,40 @@ static int twl_rtc_remove(struct platform_device *pdev)
 
 static void twl_rtc_shutdown(struct platform_device *pdev)
 {
+	struct twl_rtc *twl_rtc = platform_get_drvdata(pdev);
+
 	/* mask timer interrupts, but leave alarm interrupts on to enable
 	   power-on when alarm is triggered */
-	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+	mask_rtc_irq_bit(twl_rtc, BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
 }
 
 #ifdef CONFIG_PM_SLEEP
-static unsigned char irqstat;
-
 static int twl_rtc_suspend(struct device *dev)
 {
-	irqstat = rtc_irq_bits;
+	struct twl_rtc *twl_rtc = dev_get_drvdata(dev);
+
+	twl_rtc->irqstat = twl_rtc->rtc_irq_bits;
 
-	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+	mask_rtc_irq_bit(twl_rtc, BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
 	return 0;
 }
 
 static int twl_rtc_resume(struct device *dev)
 {
-	set_rtc_irq_bit(irqstat);
+	struct twl_rtc *twl_rtc = dev_get_drvdata(dev);
+
+	set_rtc_irq_bit(twl_rtc, twl_rtc->irqstat);
 	return 0;
 }
 #endif
 
 static SIMPLE_DEV_PM_OPS(twl_rtc_pm_ops, twl_rtc_suspend, twl_rtc_resume);
 
-#ifdef CONFIG_OF
 static const struct of_device_id twl_rtc_of_match[] = {
 	{.compatible = "ti,twl4030-rtc", },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, twl_rtc_of_match);
-#endif
-
-MODULE_ALIAS("platform:twl_rtc");
 
 static struct platform_driver twl4030rtc_driver = {
 	.probe		= twl_rtc_probe,
@@ -611,7 +651,7 @@ static struct platform_driver twl4030rtc_driver = {
 	.driver		= {
 		.name		= "twl_rtc",
 		.pm		= &twl_rtc_pm_ops,
-		.of_match_table = of_match_ptr(twl_rtc_of_match),
+		.of_match_table = twl_rtc_of_match,
 	},
 };