summary refs log tree commit diff
path: root/drivers/rtc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-06 03:09:16 +0900
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-06 03:09:16 +0900
commit11126c611e10abb18b6f1ed0300c0548c3906b54 (patch)
tree246227ad730c1e68f5a9c03db57cd4592abe7687 /drivers/rtc
parent67966e088b0c7dc926f4ce19565ebf208e18d058 (diff)
parent33e2a4227ddff7c18921ac175fae3ab0e3ff8a76 (diff)
downloadlinux-11126c611e10abb18b6f1ed0300c0548c3906b54.tar.gz
Merge branch 'akpm' (Andrew's patch-bomb)
Merge misc patches from Andrew Morton:
 "The MM tree is rather stuck while I wait to find out what the heck is
  happening with sched/numa.  Probably I'll need to route around all the
  code which was added to -next, sigh.

  So this is "everything else", or at least most of it - other small
  bits are still awaiting resolutions of various kinds."

* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (180 commits)
  lib/decompress.c add __init to decompress_method and data
  kernel/resource.c: fix stack overflow in __reserve_region_with_split()
  omfs: convert to use beXX_add_cpu()
  taskstats: cgroupstats_user_cmd() may leak on error
  aoe: update aoe-internal version number to 50
  aoe: update documentation to better reflect aoe-plus-udev usage
  aoe: remove unused code
  aoe: make dynamic block minor numbers the default
  aoe: update and specify AoE address guards and error messages
  aoe: retain static block device numbers for backwards compatibility
  aoe: support more AoE addresses with dynamic block device minor numbers
  aoe: update documentation with new URL and VM settings reference
  aoe: update copyright year in touched files
  aoe: update internal version number to 49
  aoe: remove unused code and add cosmetic improvements
  aoe: increase net_device reference count while using it
  aoe: associate frames with the AoE storage target
  aoe: disallow unsupported AoE minor addresses
  aoe: do revalidation steps in order
  aoe: failover remote interface based on aoe_deadsecs parameter
  ...
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig87
-rw-r--r--drivers/rtc/Makefile5
-rw-r--r--drivers/rtc/class.c9
-rw-r--r--drivers/rtc/hctosys.c4
-rw-r--r--drivers/rtc/rtc-at91sam9.c13
-rw-r--r--drivers/rtc/rtc-coh901331.c3
-rw-r--r--drivers/rtc/rtc-ds1672.c26
-rw-r--r--drivers/rtc/rtc-ds2404.c303
-rw-r--r--drivers/rtc/rtc-em3027.c17
-rw-r--r--drivers/rtc/rtc-isl1208.c21
-rw-r--r--drivers/rtc/rtc-jz4740.c2
-rw-r--r--drivers/rtc/rtc-m41t80.c157
-rw-r--r--drivers/rtc/rtc-max8907.c244
-rw-r--r--drivers/rtc/rtc-mxc.c30
-rw-r--r--drivers/rtc/rtc-pcf8563.c13
-rw-r--r--drivers/rtc/rtc-proc.c24
-rw-r--r--drivers/rtc/rtc-rc5t583.c331
-rw-r--r--drivers/rtc/rtc-rs5c372.c7
-rw-r--r--drivers/rtc/rtc-s35390a.c129
-rw-r--r--drivers/rtc/rtc-s3c.c4
-rw-r--r--drivers/rtc/rtc-snvs.c350
-rw-r--r--drivers/rtc/rtc-spear.c12
-rw-r--r--drivers/rtc/rtc-sysfs.c6
-rw-r--r--drivers/rtc/rtc-tps65910.c349
-rw-r--r--drivers/rtc/rtc-x1205.c92
25 files changed, 1982 insertions, 256 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index fabc99a75c65..e069f176a82d 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -19,7 +19,6 @@ if RTC_CLASS
 
 config RTC_HCTOSYS
 	bool "Set system time from RTC on startup and resume"
-	depends on RTC_CLASS = y
 	default y
 	help
 	  If you say yes here, the system time (wall clock) will be set using
@@ -51,7 +50,6 @@ config RTC_HCTOSYS_DEVICE
 
 config RTC_DEBUG
 	bool "RTC debug support"
-	depends on RTC_CLASS = y
 	help
 	  Say yes here to enable debugging support in the RTC framework
 	  and individual RTC drivers.
@@ -61,7 +59,6 @@ comment "RTC interfaces"
 config RTC_INTF_SYSFS
 	boolean "/sys/class/rtc/rtcN (sysfs)"
 	depends on SYSFS
-	default RTC_CLASS
 	help
 	  Say yes here if you want to use your RTCs using sysfs interfaces,
 	  /sys/class/rtc/rtc0 through /sys/.../rtcN.
@@ -69,19 +66,19 @@ config RTC_INTF_SYSFS
 	  If unsure, say Y.
 
 config RTC_INTF_PROC
-	boolean "/proc/driver/rtc (procfs for rtc0)"
+	boolean "/proc/driver/rtc (procfs for rtcN)"
 	depends on PROC_FS
-	default RTC_CLASS
 	help
-	  Say yes here if you want to use your first RTC through the proc
-	  interface, /proc/driver/rtc. Other RTCs will not be available
-	  through that API.
+	  Say yes here if you want to use your system clock RTC through
+	  the proc interface, /proc/driver/rtc.
+	  Other RTCs will not be available through that API.
+	  If there is no RTC for the system clock, then the first RTC(rtc0)
+	  is used by default.
 
 	  If unsure, say Y.
 
 config RTC_INTF_DEV
 	boolean "/dev/rtcN (character devices)"
-	default RTC_CLASS
 	help
 	  Say yes here if you want to use your RTCs using the /dev
 	  interfaces, which "udev" sets up as /dev/rtc0 through
@@ -127,7 +124,7 @@ if I2C
 
 config RTC_DRV_88PM860X
 	tristate "Marvell 88PM860x"
-	depends on RTC_CLASS && I2C && MFD_88PM860X
+	depends on I2C && MFD_88PM860X
 	help
 	  If you say yes here you get support for RTC function in Marvell
 	  88PM860x chips.
@@ -137,7 +134,7 @@ config RTC_DRV_88PM860X
 
 config RTC_DRV_88PM80X
 	tristate "Marvell 88PM80x"
-	depends on RTC_CLASS && I2C && MFD_88PM800
+	depends on I2C && MFD_88PM800
 	help
 	  If you say yes here you get support for RTC function in Marvell
 	  88PM80x chips.
@@ -165,7 +162,7 @@ config RTC_DRV_DS1307
 
 config RTC_DRV_DS1374
 	tristate "Dallas/Maxim DS1374"
-	depends on RTC_CLASS && I2C
+	depends on I2C
 	help
 	  If you say yes here you get support for Dallas Semiconductor
 	  DS1374 real-time clock chips. If an interrupt is associated
@@ -185,7 +182,7 @@ config RTC_DRV_DS1672
 
 config RTC_DRV_DS3232
 	tristate "Dallas/Maxim DS3232"
-	depends on RTC_CLASS && I2C
+	depends on I2C
 	help
 	  If you say yes here you get support for Dallas Semiconductor
 	  DS3232 real-time clock chips. If an interrupt is associated
@@ -203,6 +200,16 @@ config RTC_DRV_MAX6900
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-max6900.
 
+config RTC_DRV_MAX8907
+	tristate "Maxim MAX8907"
+	depends on MFD_MAX8907
+	help
+	  If you say yes here you will get support for the
+	  RTC of Maxim MAX8907 PMIC.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-max8907.
+
 config RTC_DRV_MAX8925
 	tristate "Maxim MAX8925"
 	depends on MFD_MAX8925
@@ -325,7 +332,7 @@ config RTC_DRV_TWL92330
 
 config RTC_DRV_TWL4030
 	tristate "TI TWL4030/TWL5030/TWL6030/TPS659x0"
-	depends on RTC_CLASS && TWL4030_CORE
+	depends on TWL4030_CORE
 	help
 	  If you say yes here you get support for the RTC on the
 	  TWL4030/TWL5030/TWL6030 family chips, used mostly with OMAP3 platforms.
@@ -333,6 +340,26 @@ config RTC_DRV_TWL4030
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-twl.
 
+config RTC_DRV_TPS65910
+	tristate "TI TPS65910 RTC driver"
+	depends on RTC_CLASS && MFD_TPS65910
+	help
+	  If you say yes here you get support for the RTC on the
+	  TPS65910 chips.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-tps65910.
+
+config RTC_DRV_RC5T583
+	tristate "RICOH 5T583 RTC driver"
+	depends on MFD_RC5T583
+	help
+	  If you say yes here you get support for the RTC on the
+	  RICOH 5T583 chips.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-rc5t583.
+
 config RTC_DRV_S35390A
 	tristate "Seiko Instruments S-35390A"
 	select BITREVERSE
@@ -538,7 +565,6 @@ config RTC_DRV_DS1302
 
 config RTC_DRV_DS1511
 	tristate "Dallas DS1511"
-	depends on RTC_CLASS
 	help
 	  If you say yes here you get support for the
 	  Dallas DS1511 timekeeping/watchdog chip.
@@ -583,7 +609,6 @@ config RTC_DRV_EFI
 
 config RTC_DRV_STK17TA8
 	tristate "Simtek STK17TA8"
-	depends on RTC_CLASS
 	help
 	  If you say yes here you get support for the
 	  Simtek STK17TA8 timekeeping chip.
@@ -658,6 +683,15 @@ config RTC_DRV_V3020
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-v3020.
 
+config RTC_DRV_DS2404
+	tristate "Dallas DS2404"
+	help
+	  If you say yes here you get support for the
+	  Dallas DS2404 RTC chip.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-ds2404.
+
 config RTC_DRV_WM831X
 	tristate "Wolfson Microelectronics WM831x RTC"
 	depends on MFD_WM831X
@@ -704,6 +738,7 @@ config RTC_DRV_AB3100
 config RTC_DRV_AB8500
 	tristate "ST-Ericsson AB8500 RTC"
 	depends on AB8500_CORE
+	select RTC_INTF_DEV
 	select RTC_INTF_DEV_UIE_EMUL
 	help
 	  Select this to enable the ST-Ericsson AB8500 power management IC RTC
@@ -711,7 +746,7 @@ config RTC_DRV_AB8500
 
 config RTC_DRV_NUC900
 	tristate "NUC910/NUC920 RTC driver"
-	depends on RTC_CLASS && ARCH_W90X900
+	depends on ARCH_W90X900
 	help
 	  If you say yes here you get support for the RTC subsystem of the
 	  NUC910/NUC920 used in embedded systems.
@@ -731,7 +766,6 @@ config RTC_DRV_DAVINCI
 config RTC_DRV_IMXDI
 	tristate "Freescale IMX DryIce Real Time Clock"
 	depends on SOC_IMX25
-	depends on RTC_CLASS
 	help
 	   Support for Freescale IMX DryIce RTC
 
@@ -791,7 +825,7 @@ config RTC_DRV_SA1100
 
 config RTC_DRV_SH
 	tristate "SuperH On-Chip RTC"
-	depends on RTC_CLASS && SUPERH && HAVE_CLK
+	depends on SUPERH && HAVE_CLK
 	help
 	  Say Y here to enable support for the on-chip RTC found in
 	  most SuperH processors.
@@ -1023,7 +1057,6 @@ config RTC_DRV_MPC5121
 
 config RTC_DRV_JZ4740
 	tristate "Ingenic JZ4740 SoC"
-	depends on RTC_CLASS
 	depends on MACH_JZ4740
 	help
 	  If you say yes here you get support for the Ingenic JZ4740 SoC RTC
@@ -1053,7 +1086,7 @@ config RTC_DRV_PM8XXX
 
 config RTC_DRV_TEGRA
 	tristate "NVIDIA Tegra Internal RTC driver"
-	depends on RTC_CLASS && ARCH_TEGRA
+	depends on ARCH_TEGRA
 	help
 	  If you say yes here you get support for the
 	  Tegra 200 series internal RTC module.
@@ -1090,7 +1123,6 @@ config RTC_DRV_LOONGSON1
 config RTC_DRV_MXC
 	tristate "Freescale MXC Real Time Clock"
 	depends on ARCH_MXC
-	depends on RTC_CLASS
 	help
 	   If you say yes here you get support for the Freescale MXC
 	   RTC module.
@@ -1098,4 +1130,15 @@ config RTC_DRV_MXC
 	   This driver can also be built as a module, if so, the module
 	   will be called "rtc-mxc".
 
+config RTC_DRV_SNVS
+	tristate "Freescale SNVS RTC support"
+	depends on HAS_IOMEM
+	depends on OF
+	help
+	   If you say yes here you get support for the Freescale SNVS
+	   Low Power (LP) RTC module.
+
+	   This driver can also be built as a module, if so, the module
+	   will be called "rtc-snvs".
+
 endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 0d5b2b66f90d..56297f0fd388 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_RTC_DRV_DS1511)	+= rtc-ds1511.o
 obj-$(CONFIG_RTC_DRV_DS1553)	+= rtc-ds1553.o
 obj-$(CONFIG_RTC_DRV_DS1672)	+= rtc-ds1672.o
 obj-$(CONFIG_RTC_DRV_DS1742)	+= rtc-ds1742.o
+obj-$(CONFIG_RTC_DRV_DS2404)    += rtc-ds2404.o
 obj-$(CONFIG_RTC_DRV_DS3232)	+= rtc-ds3232.o
 obj-$(CONFIG_RTC_DRV_DS3234)	+= rtc-ds3234.o
 obj-$(CONFIG_RTC_DRV_EFI)	+= rtc-efi.o
@@ -64,6 +65,7 @@ obj-$(CONFIG_RTC_DRV_M48T59)	+= rtc-m48t59.o
 obj-$(CONFIG_RTC_DRV_M48T86)	+= rtc-m48t86.o
 obj-$(CONFIG_RTC_DRV_MXC)	+= rtc-mxc.o
 obj-$(CONFIG_RTC_DRV_MAX6900)	+= rtc-max6900.o
+obj-$(CONFIG_RTC_DRV_MAX8907)	+= rtc-max8907.o
 obj-$(CONFIG_RTC_DRV_MAX8925)	+= rtc-max8925.o
 obj-$(CONFIG_RTC_DRV_MAX8998)	+= rtc-max8998.o
 obj-$(CONFIG_RTC_DRV_MAX6902)	+= rtc-max6902.o
@@ -85,6 +87,7 @@ 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_R9701)	+= rtc-r9701.o
+obj-$(CONFIG_RTC_DRV_RC5T583)	+= rtc-rc5t583.o
 obj-$(CONFIG_RTC_DRV_RP5C01)	+= rtc-rp5c01.o
 obj-$(CONFIG_RTC_DRV_RS5C313)	+= rtc-rs5c313.o
 obj-$(CONFIG_RTC_DRV_RS5C348)	+= rtc-rs5c348.o
@@ -96,6 +99,7 @@ obj-$(CONFIG_RTC_DRV_S35390A)	+= rtc-s35390a.o
 obj-$(CONFIG_RTC_DRV_S3C)	+= rtc-s3c.o
 obj-$(CONFIG_RTC_DRV_SA1100)	+= rtc-sa1100.o
 obj-$(CONFIG_RTC_DRV_SH)	+= rtc-sh.o
+obj-$(CONFIG_RTC_DRV_SNVS)	+= rtc-snvs.o
 obj-$(CONFIG_RTC_DRV_SPEAR)	+= rtc-spear.o
 obj-$(CONFIG_RTC_DRV_STARFIRE)	+= rtc-starfire.o
 obj-$(CONFIG_RTC_DRV_STK17TA8)	+= rtc-stk17ta8.o
@@ -105,6 +109,7 @@ obj-$(CONFIG_RTC_DRV_TEGRA)	+= rtc-tegra.o
 obj-$(CONFIG_RTC_DRV_TEST)	+= rtc-test.o
 obj-$(CONFIG_RTC_DRV_TILE)	+= rtc-tile.o
 obj-$(CONFIG_RTC_DRV_TWL4030)	+= rtc-twl.o
+obj-$(CONFIG_RTC_DRV_TPS65910)	+= rtc-tps65910.o
 obj-$(CONFIG_RTC_DRV_TX4939)	+= rtc-tx4939.o
 obj-$(CONFIG_RTC_DRV_V3020)	+= rtc-v3020.o
 obj-$(CONFIG_RTC_DRV_VR41XX)	+= rtc-vr41xx.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index dc4c2748bbc3..f8a0aab218cb 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -31,8 +31,12 @@ static void rtc_device_release(struct device *dev)
 	kfree(rtc);
 }
 
-#if defined(CONFIG_PM) && defined(CONFIG_RTC_HCTOSYS_DEVICE)
+#ifdef CONFIG_RTC_HCTOSYS_DEVICE
+/* Result of the last RTC to system clock attempt. */
+int rtc_hctosys_ret = -ENODEV;
+#endif
 
+#if defined(CONFIG_PM) && defined(CONFIG_RTC_HCTOSYS_DEVICE)
 /*
  * On suspend(), measure the delta between one RTC and the
  * system's wall clock; restore it on resume().
@@ -84,6 +88,7 @@ static int rtc_resume(struct device *dev)
 	struct timespec		new_system, new_rtc;
 	struct timespec		sleep_time;
 
+	rtc_hctosys_ret = -ENODEV;
 	if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
 		return 0;
 
@@ -117,6 +122,7 @@ static int rtc_resume(struct device *dev)
 
 	if (sleep_time.tv_sec >= 0)
 		timekeeping_inject_sleeptime(&sleep_time);
+	rtc_hctosys_ret = 0;
 	return 0;
 }
 
@@ -238,6 +244,7 @@ void rtc_device_unregister(struct rtc_device *rtc)
 		rtc_proc_del_device(rtc);
 		device_unregister(&rtc->dev);
 		rtc->ops = NULL;
+		ida_simple_remove(&rtc_ida, rtc->id);
 		mutex_unlock(&rtc->ops_lock);
 		put_device(&rtc->dev);
 	}
diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c
index bc90b091f195..4aa60d74004e 100644
--- a/drivers/rtc/hctosys.c
+++ b/drivers/rtc/hctosys.c
@@ -22,8 +22,6 @@
  * the best guess is to add 0.5s.
  */
 
-int rtc_hctosys_ret = -ENODEV;
-
 static int __init rtc_hctosys(void)
 {
 	int err = -ENODEV;
@@ -56,7 +54,7 @@ static int __init rtc_hctosys(void)
 
 	rtc_tm_to_time(&tm, &tv.tv_sec);
 
-	do_settimeofday(&tv);
+	err = do_settimeofday(&tv);
 
 	dev_info(rtc->dev.parent,
 		"setting system clock to "
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index 1dd61f402b04..2dfe7a2fb998 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -473,18 +473,7 @@ static struct platform_driver at91_rtc_driver = {
 	},
 };
 
-static int __init at91_rtc_init(void)
-{
-	return platform_driver_register(&at91_rtc_driver);
-}
-module_init(at91_rtc_init);
-
-static void __exit at91_rtc_exit(void)
-{
-	platform_driver_unregister(&at91_rtc_driver);
-}
-module_exit(at91_rtc_exit);
-
+module_platform_driver(at91_rtc_driver);
 
 MODULE_AUTHOR("Michel Benoit");
 MODULE_DESCRIPTION("RTC driver for Atmel AT91SAM9x");
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c
index 76b2156d3c62..c8115b83e5ab 100644
--- a/drivers/rtc/rtc-coh901331.c
+++ b/drivers/rtc/rtc-coh901331.c
@@ -276,8 +276,7 @@ static void coh901331_shutdown(struct platform_device *pdev)
 
 	clk_enable(rtap->clk);
 	writel(0, rtap->virtbase + COH901331_IRQ_MASK);
-	clk_disable(rtap->clk);
-	clk_unprepare(rtap->clk);
+	clk_disable_unprepare(rtap->clk);
 }
 
 static struct platform_driver coh901331_driver = {
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c
index 7fa67d0df172..45d65c0b3a85 100644
--- a/drivers/rtc/rtc-ds1672.c
+++ b/drivers/rtc/rtc-ds1672.c
@@ -37,8 +37,17 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm)
 	unsigned char buf[4];
 
 	struct i2c_msg msgs[] = {
-		{client->addr, 0, 1, &addr},	/* setup read ptr */
-		{client->addr, I2C_M_RD, 4, buf},	/* read date */
+		{/* setup read ptr */
+			.addr = client->addr,
+			.len = 1,
+			.buf = &addr
+		},
+		{/* read date */
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = 4,
+			.buf = buf
+		},
 	};
 
 	/* read date registers */
@@ -99,8 +108,17 @@ static int ds1672_get_control(struct i2c_client *client, u8 *status)
 	unsigned char addr = DS1672_REG_CONTROL;
 
 	struct i2c_msg msgs[] = {
-		{client->addr, 0, 1, &addr},	/* setup read ptr */
-		{client->addr, I2C_M_RD, 1, status},	/* read control */
+		{/* setup read ptr */
+			.addr = client->addr,
+			.len = 1,
+			.buf = &addr
+		},
+		{/* read control */
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = status
+		},
 	};
 
 	/* read control register */
diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c
new file mode 100644
index 000000000000..5ea9df7c8c31
--- /dev/null
+++ b/drivers/rtc/rtc-ds2404.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2012 Sven Schnelle <svens@stackframe.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/rtc.h>
+#include <linux/types.h>
+#include <linux/bcd.h>
+#include <linux/rtc-ds2404.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+
+#include <linux/io.h>
+
+#define DS2404_STATUS_REG 0x200
+#define DS2404_CONTROL_REG 0x201
+#define DS2404_RTC_REG 0x202
+
+#define DS2404_WRITE_SCRATCHPAD_CMD 0x0f
+#define DS2404_READ_SCRATCHPAD_CMD 0xaa
+#define DS2404_COPY_SCRATCHPAD_CMD 0x55
+#define DS2404_READ_MEMORY_CMD 0xf0
+
+struct ds2404;
+
+struct ds2404_chip_ops {
+	int (*map_io)(struct ds2404 *chip, struct platform_device *pdev,
+		      struct ds2404_platform_data *pdata);
+	void (*unmap_io)(struct ds2404 *chip);
+};
+
+#define DS2404_RST	0
+#define DS2404_CLK	1
+#define DS2404_DQ	2
+
+struct ds2404_gpio {
+	const char *name;
+	unsigned int gpio;
+};
+
+struct ds2404 {
+	struct ds2404_gpio *gpio;
+	struct ds2404_chip_ops *ops;
+	struct rtc_device *rtc;
+};
+
+static struct ds2404_gpio ds2404_gpio[] = {
+	{ "RTC RST", 0 },
+	{ "RTC CLK", 0 },
+	{ "RTC DQ", 0 },
+};
+
+static int ds2404_gpio_map(struct ds2404 *chip, struct platform_device *pdev,
+			  struct ds2404_platform_data *pdata)
+{
+	int i, err;
+
+	ds2404_gpio[DS2404_RST].gpio = pdata->gpio_rst;
+	ds2404_gpio[DS2404_CLK].gpio = pdata->gpio_clk;
+	ds2404_gpio[DS2404_DQ].gpio = pdata->gpio_dq;
+
+	for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++) {
+		err = gpio_request(ds2404_gpio[i].gpio, ds2404_gpio[i].name);
+		if (err) {
+			printk(KERN_ERR "error mapping gpio %s: %d\n",
+				ds2404_gpio[i].name, err);
+			goto err_request;
+		}
+		if (i != DS2404_DQ)
+			gpio_direction_output(ds2404_gpio[i].gpio, 1);
+	}
+
+	chip->gpio = ds2404_gpio;
+	return 0;
+
+err_request:
+	while (--i >= 0)
+		gpio_free(ds2404_gpio[i].gpio);
+	return err;
+}
+
+static void ds2404_gpio_unmap(struct ds2404 *chip)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++)
+		gpio_free(ds2404_gpio[i].gpio);
+}
+
+static struct ds2404_chip_ops ds2404_gpio_ops = {
+	.map_io		= ds2404_gpio_map,
+	.unmap_io	= ds2404_gpio_unmap,
+};
+
+static void ds2404_reset(struct device *dev)
+{
+	gpio_set_value(ds2404_gpio[DS2404_RST].gpio, 0);
+	udelay(1000);
+	gpio_set_value(ds2404_gpio[DS2404_RST].gpio, 1);
+	gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0);
+	gpio_direction_output(ds2404_gpio[DS2404_DQ].gpio, 0);
+	udelay(10);
+}
+
+static void ds2404_write_byte(struct device *dev, u8 byte)
+{
+	int i;
+
+	gpio_direction_output(ds2404_gpio[DS2404_DQ].gpio, 1);
+	for (i = 0; i < 8; i++) {
+		gpio_set_value(ds2404_gpio[DS2404_DQ].gpio, byte & (1 << i));
+		udelay(10);
+		gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 1);
+		udelay(10);
+		gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0);
+		udelay(10);
+	}
+}
+
+static u8 ds2404_read_byte(struct device *dev)
+{
+	int i;
+	u8 ret = 0;
+
+	gpio_direction_input(ds2404_gpio[DS2404_DQ].gpio);
+
+	for (i = 0; i < 8; i++) {
+		gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0);
+		udelay(10);
+		if (gpio_get_value(ds2404_gpio[DS2404_DQ].gpio))
+			ret |= 1 << i;
+		gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 1);
+		udelay(10);
+	}
+	return ret;
+}
+
+static void ds2404_read_memory(struct device *dev, u16 offset,
+			       int length, u8 *out)
+{
+	ds2404_reset(dev);
+	ds2404_write_byte(dev, DS2404_READ_MEMORY_CMD);
+	ds2404_write_byte(dev, offset & 0xff);
+	ds2404_write_byte(dev, (offset >> 8) & 0xff);
+	while (length--)
+		*out++ = ds2404_read_byte(dev);
+}
+
+static void ds2404_write_memory(struct device *dev, u16 offset,
+				int length, u8 *out)
+{
+	int i;
+	u8 ta01, ta02, es;
+
+	ds2404_reset(dev);
+	ds2404_write_byte(dev, DS2404_WRITE_SCRATCHPAD_CMD);
+	ds2404_write_byte(dev, offset & 0xff);
+	ds2404_write_byte(dev, (offset >> 8) & 0xff);
+
+	for (i = 0; i < length; i++)
+		ds2404_write_byte(dev, out[i]);
+
+	ds2404_reset(dev);
+	ds2404_write_byte(dev, DS2404_READ_SCRATCHPAD_CMD);
+
+	ta01 = ds2404_read_byte(dev);
+	ta02 = ds2404_read_byte(dev);
+	es = ds2404_read_byte(dev);
+
+	for (i = 0; i < length; i++) {
+		if (out[i] != ds2404_read_byte(dev)) {
+			printk(KERN_ERR "read invalid data\n");
+			return;
+		}
+	}
+
+	ds2404_reset(dev);
+	ds2404_write_byte(dev, DS2404_COPY_SCRATCHPAD_CMD);
+	ds2404_write_byte(dev, ta01);
+	ds2404_write_byte(dev, ta02);
+	ds2404_write_byte(dev, es);
+
+	gpio_direction_input(ds2404_gpio[DS2404_DQ].gpio);
+	while (gpio_get_value(ds2404_gpio[DS2404_DQ].gpio))
+		;
+}
+
+static void ds2404_enable_osc(struct device *dev)
+{
+	u8 in[1] = { 0x10 }; /* enable oscillator */
+	ds2404_write_memory(dev, 0x201, 1, in);
+}
+
+static int ds2404_read_time(struct device *dev, struct rtc_time *dt)
+{
+	unsigned long time = 0;
+
+	ds2404_read_memory(dev, 0x203, 4, (u8 *)&time);
+	time = le32_to_cpu(time);
+
+	rtc_time_to_tm(time, dt);
+	return rtc_valid_tm(dt);
+}
+
+static int ds2404_set_mmss(struct device *dev, unsigned long secs)
+{
+	u32 time = cpu_to_le32(secs);
+	ds2404_write_memory(dev, 0x203, 4, (u8 *)&time);
+	return 0;
+}
+
+static const struct rtc_class_ops ds2404_rtc_ops = {
+	.read_time	= ds2404_read_time,
+	.set_mmss	= ds2404_set_mmss,
+};
+
+static int rtc_probe(struct platform_device *pdev)
+{
+	struct ds2404_platform_data *pdata = pdev->dev.platform_data;
+	struct ds2404 *chip;
+	int retval = -EBUSY;
+
+	chip = kzalloc(sizeof(struct ds2404), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->ops = &ds2404_gpio_ops;
+
+	retval = chip->ops->map_io(chip, pdev, pdata);
+	if (retval)
+		goto err_chip;
+
+	dev_info(&pdev->dev, "using GPIOs RST:%d, CLK:%d, DQ:%d\n",
+		 chip->gpio[DS2404_RST].gpio, chip->gpio[DS2404_CLK].gpio,
+		 chip->gpio[DS2404_DQ].gpio);
+
+	platform_set_drvdata(pdev, chip);
+
+	chip->rtc = rtc_device_register("ds2404",
+				&pdev->dev, &ds2404_rtc_ops, THIS_MODULE);
+	if (IS_ERR(chip->rtc)) {
+		retval = PTR_ERR(chip->rtc);
+		goto err_io;
+	}
+
+	ds2404_enable_osc(&pdev->dev);
+	return 0;
+
+err_io:
+	chip->ops->unmap_io(chip);
+err_chip:
+	kfree(chip);
+	return retval;
+}
+
+static int rtc_remove(struct platform_device *dev)
+{
+	struct ds2404 *chip = platform_get_drvdata(dev);
+	struct rtc_device *rtc = chip->rtc;
+
+	if (rtc)
+		rtc_device_unregister(rtc);
+
+	chip->ops->unmap_io(chip);
+	kfree(chip);
+
+	return 0;
+}
+
+static struct platform_driver rtc_device_driver = {
+	.probe	= rtc_probe,
+	.remove = rtc_remove,
+	.driver = {
+		.name	= "ds2404",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static __init int ds2404_init(void)
+{
+	return platform_driver_register(&rtc_device_driver);
+}
+
+static __exit void ds2404_exit(void)
+{
+	platform_driver_unregister(&rtc_device_driver);
+}
+
+module_init(ds2404_init);
+module_exit(ds2404_exit);
+
+MODULE_DESCRIPTION("DS2404 RTC");
+MODULE_AUTHOR("Sven Schnelle");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ds2404");
diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c
index 0104ea7ebe50..f6c24ce35d36 100644
--- a/drivers/rtc/rtc-em3027.c
+++ b/drivers/rtc/rtc-em3027.c
@@ -49,8 +49,17 @@ static int em3027_get_time(struct device *dev, struct rtc_time *tm)
 	unsigned char buf[7];
 
 	struct i2c_msg msgs[] = {
-		{client->addr, 0, 1, &addr},		/* setup read addr */
-		{client->addr, I2C_M_RD, 7, buf},	/* read time/date */
+		{/* setup read addr */
+			.addr = client->addr,
+			.len = 1,
+			.buf = &addr
+		},
+		{/* read time/date */
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = 7,
+			.buf = buf
+		},
 	};
 
 	/* read time/date registers */
@@ -76,7 +85,9 @@ static int em3027_set_time(struct device *dev, struct rtc_time *tm)
 	unsigned char buf[8];
 
 	struct i2c_msg msg = {
-		client->addr, 0, 8, buf,	/* write time/date */
+		.addr = client->addr,
+		.len = 8,
+		.buf = buf,	/* write time/date */
 	};
 
 	buf[0] = EM3027_REG_WATCH_SEC;
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index dd2aeee6c66a..26c81f233606 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -68,9 +68,17 @@ isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[],
 {
 	u8 reg_addr[1] = { reg };
 	struct i2c_msg msgs[2] = {
-		{client->addr, 0, sizeof(reg_addr), reg_addr}
-		,
-		{client->addr, I2C_M_RD, len, buf}
+		{
+			.addr = client->addr,
+			.len = sizeof(reg_addr),
+			.buf = reg_addr
+		},
+		{
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = len,
+			.buf = buf
+		}
 	};
 	int ret;
 
@@ -90,7 +98,11 @@ isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[],
 {
 	u8 i2c_buf[ISL1208_REG_USR2 + 2];
 	struct i2c_msg msgs[1] = {
-		{client->addr, 0, len + 1, i2c_buf}
+		{
+			.addr = client->addr,
+			.len = len + 1,
+			.buf = i2c_buf
+		}
 	};
 	int ret;
 
@@ -697,6 +709,7 @@ isl1208_remove(struct i2c_client *client)
 
 static const struct i2c_device_id isl1208_id[] = {
 	{ "isl1208", 0 },
+	{ "isl1218", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, isl1208_id);
diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c
index 05ab227eeff7..1224182d3eab 100644
--- a/drivers/rtc/rtc-jz4740.c
+++ b/drivers/rtc/rtc-jz4740.c
@@ -42,7 +42,7 @@ struct jz4740_rtc {
 
 	struct rtc_device *rtc;
 
-	unsigned int irq;
+	int irq;
 
 	spinlock_t lock;
 };
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 4e0f84af99a7..b885bcd08908 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -213,163 +213,14 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	return m41t80_set_datetime(to_i2c_client(dev), tm);
 }
 
-static int m41t80_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	int rc;
-
-	rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
-	if (rc < 0)
-		goto err;
-
-	if (enabled)
-		rc |= M41T80_ALMON_AFE;
-	else
-		rc &= ~M41T80_ALMON_AFE;
-
-	if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0)
-		goto err;
-
-	return 0;
-err:
-	return -EIO;
-}
-
-static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	u8 wbuf[1 + M41T80_ALARM_REG_SIZE];
-	u8 *buf = &wbuf[1];
-	u8 *reg = buf - M41T80_REG_ALARM_MON;
-	u8 dt_addr[1] = { M41T80_REG_ALARM_MON };
-	struct i2c_msg msgs_in[] = {
-		{
-			.addr	= client->addr,
-			.flags	= 0,
-			.len	= 1,
-			.buf	= dt_addr,
-		},
-		{
-			.addr	= client->addr,
-			.flags	= I2C_M_RD,
-			.len	= M41T80_ALARM_REG_SIZE,
-			.buf	= buf,
-		},
-	};
-	struct i2c_msg msgs[] = {
-		{
-			.addr	= client->addr,
-			.flags	= 0,
-			.len	= 1 + M41T80_ALARM_REG_SIZE,
-			.buf	= wbuf,
-		 },
-	};
-
-	if (i2c_transfer(client->adapter, msgs_in, 2) < 0) {
-		dev_err(&client->dev, "read error\n");
-		return -EIO;
-	}
-	reg[M41T80_REG_ALARM_MON] &= ~(0x1f | M41T80_ALMON_AFE);
-	reg[M41T80_REG_ALARM_DAY] = 0;
-	reg[M41T80_REG_ALARM_HOUR] &= ~(0x3f | 0x80);
-	reg[M41T80_REG_ALARM_MIN] = 0;
-	reg[M41T80_REG_ALARM_SEC] = 0;
-
-	wbuf[0] = M41T80_REG_ALARM_MON; /* offset into rtc's regs */
-	reg[M41T80_REG_ALARM_SEC] |= t->time.tm_sec >= 0 ?
-		bin2bcd(t->time.tm_sec) : 0x80;
-	reg[M41T80_REG_ALARM_MIN] |= t->time.tm_min >= 0 ?
-		bin2bcd(t->time.tm_min) : 0x80;
-	reg[M41T80_REG_ALARM_HOUR] |= t->time.tm_hour >= 0 ?
-		bin2bcd(t->time.tm_hour) : 0x80;
-	reg[M41T80_REG_ALARM_DAY] |= t->time.tm_mday >= 0 ?
-		bin2bcd(t->time.tm_mday) : 0x80;
-	if (t->time.tm_mon >= 0)
-		reg[M41T80_REG_ALARM_MON] |= bin2bcd(t->time.tm_mon + 1);
-	else
-		reg[M41T80_REG_ALARM_DAY] |= 0x40;
-
-	if (i2c_transfer(client->adapter, msgs, 1) != 1) {
-		dev_err(&client->dev, "write error\n");
-		return -EIO;
-	}
-
-	if (t->enabled) {
-		reg[M41T80_REG_ALARM_MON] |= M41T80_ALMON_AFE;
-		if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
-					      reg[M41T80_REG_ALARM_MON]) < 0) {
-			dev_err(&client->dev, "write error\n");
-			return -EIO;
-		}
-	}
-	return 0;
-}
-
-static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	u8 buf[M41T80_ALARM_REG_SIZE + 1]; /* all alarm regs and flags */
-	u8 dt_addr[1] = { M41T80_REG_ALARM_MON };
-	u8 *reg = buf - M41T80_REG_ALARM_MON;
-	struct i2c_msg msgs[] = {
-		{
-			.addr	= client->addr,
-			.flags	= 0,
-			.len	= 1,
-			.buf	= dt_addr,
-		},
-		{
-			.addr	= client->addr,
-			.flags	= I2C_M_RD,
-			.len	= M41T80_ALARM_REG_SIZE + 1,
-			.buf	= buf,
-		},
-	};
-
-	if (i2c_transfer(client->adapter, msgs, 2) < 0) {
-		dev_err(&client->dev, "read error\n");
-		return -EIO;
-	}
-	t->time.tm_sec = -1;
-	t->time.tm_min = -1;
-	t->time.tm_hour = -1;
-	t->time.tm_mday = -1;
-	t->time.tm_mon = -1;
-	if (!(reg[M41T80_REG_ALARM_SEC] & 0x80))
-		t->time.tm_sec = bcd2bin(reg[M41T80_REG_ALARM_SEC] & 0x7f);
-	if (!(reg[M41T80_REG_ALARM_MIN] & 0x80))
-		t->time.tm_min = bcd2bin(reg[M41T80_REG_ALARM_MIN] & 0x7f);
-	if (!(reg[M41T80_REG_ALARM_HOUR] & 0x80))
-		t->time.tm_hour = bcd2bin(reg[M41T80_REG_ALARM_HOUR] & 0x3f);
-	if (!(reg[M41T80_REG_ALARM_DAY] & 0x80))
-		t->time.tm_mday = bcd2bin(reg[M41T80_REG_ALARM_DAY] & 0x3f);
-	if (!(reg[M41T80_REG_ALARM_DAY] & 0x40))
-		t->time.tm_mon = bcd2bin(reg[M41T80_REG_ALARM_MON] & 0x1f) - 1;
-	t->time.tm_year = -1;
-	t->time.tm_wday = -1;
-	t->time.tm_yday = -1;
-	t->time.tm_isdst = -1;
-	t->enabled = !!(reg[M41T80_REG_ALARM_MON] & M41T80_ALMON_AFE);
-	t->pending = !!(reg[M41T80_REG_FLAGS] & M41T80_FLAGS_AF);
-	return 0;
-}
-
+/*
+ * XXX - m41t80 alarm functionality is reported broken.
+ * until it is fixed, don't register alarm functions.
+ */
 static struct rtc_class_ops m41t80_rtc_ops = {
 	.read_time = m41t80_rtc_read_time,
 	.set_time = m41t80_rtc_set_time,
-	/*
-	 * XXX - m41t80 alarm functionality is reported broken.
-	 * until it is fixed, don't register alarm functions.
-	 *
-	.read_alarm = m41t80_rtc_read_alarm,
-	.set_alarm = m41t80_rtc_set_alarm,
-	*/
 	.proc = m41t80_rtc_proc,
-	/*
-	 * See above comment on broken alarm
-	 *
-	.alarm_irq_enable = m41t80_rtc_alarm_irq_enable,
-	*/
 };
 
 #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
diff --git a/drivers/rtc/rtc-max8907.c b/drivers/rtc/rtc-max8907.c
new file mode 100644
index 000000000000..e094ffa434f8
--- /dev/null
+++ b/drivers/rtc/rtc-max8907.c
@@ -0,0 +1,244 @@
+/*
+ * RTC driver for Maxim MAX8907
+ *
+ * Copyright (c) 2011-2012, NVIDIA Corporation.
+ *
+ * Based on drivers/rtc/rtc-max8925.c,
+ * Copyright (C) 2009-2010 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bcd.h>
+#include <linux/i2c.h>
+#include <linux/mfd/max8907.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/rtc.h>
+#include <linux/slab.h>
+
+enum {
+	RTC_SEC = 0,
+	RTC_MIN,
+	RTC_HOUR,
+	RTC_WEEKDAY,
+	RTC_DATE,
+	RTC_MONTH,
+	RTC_YEAR1,
+	RTC_YEAR2,
+};
+
+#define TIME_NUM			8
+#define ALARM_1SEC			(1 << 7)
+#define HOUR_12				(1 << 7)
+#define HOUR_AM_PM			(1 << 5)
+#define ALARM0_IRQ			(1 << 3)
+#define ALARM1_IRQ			(1 << 2)
+#define ALARM0_STATUS			(1 << 2)
+#define ALARM1_STATUS			(1 << 1)
+
+struct max8907_rtc {
+	struct max8907		*max8907;
+	struct regmap		*regmap;
+	struct rtc_device	*rtc_dev;
+	int			irq;
+};
+
+static irqreturn_t max8907_irq_handler(int irq, void *data)
+{
+	struct max8907_rtc *rtc = data;
+
+	regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x7f, 0);
+
+	rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
+
+	return IRQ_HANDLED;
+}
+
+static void regs_to_tm(u8 *regs, struct rtc_time *tm)
+{
+	tm->tm_year = bcd2bin(regs[RTC_YEAR2]) * 100 +
+		bcd2bin(regs[RTC_YEAR1]) - 1900;
+	tm->tm_mon = bcd2bin(regs[RTC_MONTH] & 0x1f) - 1;
+	tm->tm_mday = bcd2bin(regs[RTC_DATE] & 0x3f);
+	tm->tm_wday = (regs[RTC_WEEKDAY] & 0x07) - 1;
+	if (regs[RTC_HOUR] & HOUR_12) {
+		tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x01f);
+		if (tm->tm_hour == 12)
+			tm->tm_hour = 0;
+		if (regs[RTC_HOUR] & HOUR_AM_PM)
+			tm->tm_hour += 12;
+	} else {
+		tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x03f);
+	}
+	tm->tm_min = bcd2bin(regs[RTC_MIN] & 0x7f);
+	tm->tm_sec = bcd2bin(regs[RTC_SEC] & 0x7f);
+}
+
+static void tm_to_regs(struct rtc_time *tm, u8 *regs)
+{
+	u8 high, low;
+
+	high = (tm->tm_year + 1900) / 100;
+	low = tm->tm_year % 100;
+	regs[RTC_YEAR2] = bin2bcd(high);
+	regs[RTC_YEAR1] = bin2bcd(low);
+	regs[RTC_MONTH] = bin2bcd(tm->tm_mon + 1);
+	regs[RTC_DATE] = bin2bcd(tm->tm_mday);
+	regs[RTC_WEEKDAY] = tm->tm_wday + 1;
+	regs[RTC_HOUR] = bin2bcd(tm->tm_hour);
+	regs[RTC_MIN] = bin2bcd(tm->tm_min);
+	regs[RTC_SEC] = bin2bcd(tm->tm_sec);
+}
+
+static int max8907_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct max8907_rtc *rtc = dev_get_drvdata(dev);
+	u8 regs[TIME_NUM];
+	int ret;
+
+	ret = regmap_bulk_read(rtc->regmap, MAX8907_REG_RTC_SEC, regs,
+			       TIME_NUM);
+	if (ret < 0)
+		return ret;
+
+	regs_to_tm(regs, tm);
+
+	return 0;
+}
+
+static int max8907_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct max8907_rtc *rtc = dev_get_drvdata(dev);
+	u8 regs[TIME_NUM];
+
+	tm_to_regs(tm, regs);
+
+	return regmap_bulk_write(rtc->regmap, MAX8907_REG_RTC_SEC, regs,
+				 TIME_NUM);
+}
+
+static int max8907_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct max8907_rtc *rtc = dev_get_drvdata(dev);
+	u8 regs[TIME_NUM];
+	unsigned int val;
+	int ret;
+
+	ret = regmap_bulk_read(rtc->regmap, MAX8907_REG_ALARM0_SEC, regs,
+			       TIME_NUM);
+	if (ret < 0)
+		return ret;
+
+	regs_to_tm(regs, &alrm->time);
+
+	ret = regmap_read(rtc->regmap, MAX8907_REG_ALARM0_CNTL, &val);
+	if (ret < 0)
+		return ret;
+
+	alrm->enabled = !!(val & 0x7f);
+
+	return 0;
+}
+
+static int max8907_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct max8907_rtc *rtc = dev_get_drvdata(dev);
+	u8 regs[TIME_NUM];
+	int ret;
+
+	tm_to_regs(&alrm->time, regs);
+
+	/* Disable alarm while we update the target time */
+	ret = regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x7f, 0);
+	if (ret < 0)
+		return ret;
+
+	ret = regmap_bulk_write(rtc->regmap, MAX8907_REG_ALARM0_SEC, regs,
+				TIME_NUM);
+	if (ret < 0)
+		return ret;
+
+	if (alrm->enabled)
+		ret = regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL,
+					 0x7f, 0x7f);
+
+	return ret;
+}
+
+static const struct rtc_class_ops max8907_rtc_ops = {
+	.read_time	= max8907_rtc_read_time,
+	.set_time	= max8907_rtc_set_time,
+	.read_alarm	= max8907_rtc_read_alarm,
+	.set_alarm	= max8907_rtc_set_alarm,
+};
+
+static int __devinit max8907_rtc_probe(struct platform_device *pdev)
+{
+	struct max8907 *max8907 = dev_get_drvdata(pdev->dev.parent);
+	struct max8907_rtc *rtc;
+	int ret;
+
+	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
+	if (!rtc)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, rtc);
+
+	rtc->max8907 = max8907;
+	rtc->regmap = max8907->regmap_rtc;
+
+	rtc->rtc_dev = rtc_device_register("max8907-rtc", &pdev->dev,
+					&max8907_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc->rtc_dev)) {
+		ret = PTR_ERR(rtc->rtc_dev);
+		dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
+		return ret;
+	}
+
+	rtc->irq = regmap_irq_get_virq(max8907->irqc_rtc,
+				       MAX8907_IRQ_RTC_ALARM0);
+	if (rtc->irq < 0) {
+		ret = rtc->irq;
+		goto err_unregister;
+	}
+
+	ret = request_threaded_irq(rtc->irq, NULL, max8907_irq_handler,
+				   IRQF_ONESHOT, "max8907-alarm0", rtc);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to request IRQ%d: %d\n",
+			rtc->irq, ret);
+		goto err_unregister;
+	}
+
+	return 0;
+
+err_unregister:
+	rtc_device_unregister(rtc->rtc_dev);
+	return ret;
+}
+
+static int __devexit max8907_rtc_remove(struct platform_device *pdev)
+{
+	struct max8907_rtc *rtc = platform_get_drvdata(pdev);
+
+	free_irq(rtc->irq, rtc);
+	rtc_device_unregister(rtc->rtc_dev);
+
+	return 0;
+}
+
+static struct platform_driver max8907_rtc_driver = {
+	.driver = {
+		.name = "max8907-rtc",
+		.owner = THIS_MODULE,
+	},
+	.probe = max8907_rtc_probe,
+	.remove = __devexit_p(max8907_rtc_remove),
+};
+module_platform_driver(max8907_rtc_driver);
+
+MODULE_DESCRIPTION("Maxim MAX8907 RTC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index e3e50d69baf8..cd0106293a49 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -343,7 +343,7 @@ static struct rtc_class_ops mxc_rtc_ops = {
 	.alarm_irq_enable	= mxc_rtc_alarm_irq_enable,
 };
 
-static int __init mxc_rtc_probe(struct platform_device *pdev)
+static int __devinit mxc_rtc_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	struct rtc_device *rtc;
@@ -367,14 +367,14 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
 	pdata->ioaddr = devm_ioremap(&pdev->dev, res->start,
 				     resource_size(res));
 
-	pdata->clk = clk_get(&pdev->dev, "rtc");
+	pdata->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(pdata->clk)) {
 		dev_err(&pdev->dev, "unable to get clock!\n");
 		ret = PTR_ERR(pdata->clk);
 		goto exit_free_pdata;
 	}
 
-	clk_enable(pdata->clk);
+	clk_prepare_enable(pdata->clk);
 	rate = clk_get_rate(pdata->clk);
 
 	if (rate == 32768)
@@ -426,22 +426,20 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
 exit_clr_drvdata:
 	platform_set_drvdata(pdev, NULL);
 exit_put_clk:
-	clk_disable(pdata->clk);
-	clk_put(pdata->clk);
+	clk_disable_unprepare(pdata->clk);
 
 exit_free_pdata:
 
 	return ret;
 }
 
-static int __exit mxc_rtc_remove(struct platform_device *pdev)
+static int __devexit mxc_rtc_remove(struct platform_device *pdev)
 {
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 
 	rtc_device_unregister(pdata->rtc);
 
-	clk_disable(pdata->clk);
-	clk_put(pdata->clk);
+	clk_disable_unprepare(pdata->clk);
 	platform_set_drvdata(pdev, NULL);
 
 	return 0;
@@ -482,21 +480,11 @@ static struct platform_driver mxc_rtc_driver = {
 #endif
 		   .owner	= THIS_MODULE,
 	},
-	.remove		= __exit_p(mxc_rtc_remove),
+	.probe = mxc_rtc_probe,
+	.remove = __devexit_p(mxc_rtc_remove),
 };
 
-static int __init mxc_rtc_init(void)
-{
-	return platform_driver_probe(&mxc_rtc_driver, mxc_rtc_probe);
-}
-
-static void __exit mxc_rtc_exit(void)
-{
-	platform_driver_unregister(&mxc_rtc_driver);
-}
-
-module_init(mxc_rtc_init);
-module_exit(mxc_rtc_exit);
+module_platform_driver(mxc_rtc_driver)
 
 MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
 MODULE_DESCRIPTION("RTC driver for Freescale MXC");
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index c2fe426a6ef2..98e3a2b681e6 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -78,8 +78,17 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
 	unsigned char buf[13] = { PCF8563_REG_ST1 };
 
 	struct i2c_msg msgs[] = {
-		{ client->addr, 0, 1, buf },	/* setup read ptr */
-		{ client->addr, I2C_M_RD, 13, buf },	/* read status + date */
+		{/* setup read ptr */
+			.addr = client->addr,
+			.len = 1,
+			.buf = buf
+		},
+		{/* read status + date */
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = 13,
+			.buf = buf
+		},
 	};
 
 	/* read registers */
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c
index 0a59fda5c09d..e96236ac2e78 100644
--- a/drivers/rtc/rtc-proc.c
+++ b/drivers/rtc/rtc-proc.c
@@ -18,6 +18,26 @@
 
 #include "rtc-core.h"
 
+#define NAME_SIZE	10
+
+#if defined(CONFIG_RTC_HCTOSYS_DEVICE)
+static bool is_rtc_hctosys(struct rtc_device *rtc)
+{
+	int size;
+	char name[NAME_SIZE];
+
+	size = scnprintf(name, NAME_SIZE, "rtc%d", rtc->id);
+	if (size > NAME_SIZE)
+		return false;
+
+	return !strncmp(name, CONFIG_RTC_HCTOSYS_DEVICE, NAME_SIZE);
+}
+#else
+static bool is_rtc_hctosys(struct rtc_device *rtc)
+{
+	return (rtc->id == 0);
+}
+#endif
 
 static int rtc_proc_show(struct seq_file *seq, void *offset)
 {
@@ -117,12 +137,12 @@ static const struct file_operations rtc_proc_fops = {
 
 void rtc_proc_add_device(struct rtc_device *rtc)
 {
-	if (rtc->id == 0)
+	if (is_rtc_hctosys(rtc))
 		proc_create_data("driver/rtc", 0, NULL, &rtc_proc_fops, rtc);
 }
 
 void rtc_proc_del_device(struct rtc_device *rtc)
 {
-	if (rtc->id == 0)
+	if (is_rtc_hctosys(rtc))
 		remove_proc_entry("driver/rtc", NULL);
 }
diff --git a/drivers/rtc/rtc-rc5t583.c b/drivers/rtc/rtc-rc5t583.c
new file mode 100644
index 000000000000..cdb140c29c56
--- /dev/null
+++ b/drivers/rtc/rtc-rc5t583.c
@@ -0,0 +1,331 @@
+/*
+ * rtc-rc5t583.c -- RICOH RC5T583 Real Time Clock
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ * Author: Venu Byravarasu <vbyravarasu@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/rc5t583.h>
+
+struct rc5t583_rtc {
+	struct rtc_device	*rtc;
+	/* To store the list of enabled interrupts, during system suspend */
+	u32 irqen;
+};
+
+/* Total number of RTC registers needed to set time*/
+#define NUM_TIME_REGS	(RC5T583_RTC_YEAR - RC5T583_RTC_SEC + 1)
+
+/* Total number of RTC registers needed to set Y-Alarm*/
+#define NUM_YAL_REGS	(RC5T583_RTC_AY_YEAR - RC5T583_RTC_AY_MIN + 1)
+
+/* Set Y-Alarm interrupt */
+#define SET_YAL BIT(5)
+
+/* Get Y-Alarm interrupt status*/
+#define GET_YAL_STATUS BIT(3)
+
+static int rc5t583_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
+{
+	struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+	u8 val;
+
+	/* Set Y-Alarm, based on 'enabled' */
+	val = enabled ? SET_YAL : 0;
+
+	return regmap_update_bits(rc5t583->regmap, RC5T583_RTC_CTL1, SET_YAL,
+		val);
+}
+
+/*
+ * Gets current rc5t583 RTC time and date parameters.
+ *
+ * The RTC's time/alarm representation is not what gmtime(3) requires
+ * Linux to use:
+ *
+ *  - Months are 1..12 vs Linux 0-11
+ *  - Years are 0..99 vs Linux 1900..N (we assume 21st century)
+ */
+static int rc5t583_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+	u8 rtc_data[NUM_TIME_REGS];
+	int ret;
+
+	ret = regmap_bulk_read(rc5t583->regmap, RC5T583_RTC_SEC, rtc_data,
+		NUM_TIME_REGS);
+	if (ret < 0) {
+		dev_err(dev, "RTC read time failed with err:%d\n", ret);
+		return ret;
+	}
+
+	tm->tm_sec = bcd2bin(rtc_data[0]);
+	tm->tm_min = bcd2bin(rtc_data[1]);
+	tm->tm_hour = bcd2bin(rtc_data[2]);
+	tm->tm_wday = bcd2bin(rtc_data[3]);
+	tm->tm_mday = bcd2bin(rtc_data[4]);
+	tm->tm_mon = bcd2bin(rtc_data[5]) - 1;
+	tm->tm_year = bcd2bin(rtc_data[6]) + 100;
+
+	return ret;
+}
+
+static int rc5t583_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+	unsigned char rtc_data[NUM_TIME_REGS];
+	int ret;
+
+	rtc_data[0] = bin2bcd(tm->tm_sec);
+	rtc_data[1] = bin2bcd(tm->tm_min);
+	rtc_data[2] = bin2bcd(tm->tm_hour);
+	rtc_data[3] = bin2bcd(tm->tm_wday);
+	rtc_data[4] = bin2bcd(tm->tm_mday);
+	rtc_data[5] = bin2bcd(tm->tm_mon + 1);
+	rtc_data[6] = bin2bcd(tm->tm_year - 100);
+
+	ret = regmap_bulk_write(rc5t583->regmap, RC5T583_RTC_SEC, rtc_data,
+		NUM_TIME_REGS);
+	if (ret < 0) {
+		dev_err(dev, "RTC set time failed with error %d\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int rc5t583_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+	unsigned char alarm_data[NUM_YAL_REGS];
+	u32 interrupt_enable;
+	int ret;
+
+	ret = regmap_bulk_read(rc5t583->regmap, RC5T583_RTC_AY_MIN, alarm_data,
+		NUM_YAL_REGS);
+	if (ret < 0) {
+		dev_err(dev, "rtc_read_alarm error %d\n", ret);
+		return ret;
+	}
+
+	alm->time.tm_min = bcd2bin(alarm_data[0]);
+	alm->time.tm_hour = bcd2bin(alarm_data[1]);
+	alm->time.tm_mday = bcd2bin(alarm_data[2]);
+	alm->time.tm_mon = bcd2bin(alarm_data[3]) - 1;
+	alm->time.tm_year = bcd2bin(alarm_data[4]) + 100;
+
+	ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL1, &interrupt_enable);
+	if (ret < 0)
+		return ret;
+
+	/* check if YALE is set */
+	if (interrupt_enable & SET_YAL)
+		alm->enabled = 1;
+
+	return ret;
+}
+
+static int rc5t583_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+	unsigned char alarm_data[NUM_YAL_REGS];
+	int ret;
+
+	ret = rc5t583_rtc_alarm_irq_enable(dev, 0);
+	if (ret)
+		return ret;
+
+	alarm_data[0] = bin2bcd(alm->time.tm_min);
+	alarm_data[1] = bin2bcd(alm->time.tm_hour);
+	alarm_data[2] = bin2bcd(alm->time.tm_mday);
+	alarm_data[3] = bin2bcd(alm->time.tm_mon + 1);
+	alarm_data[4] = bin2bcd(alm->time.tm_year - 100);
+
+	ret = regmap_bulk_write(rc5t583->regmap, RC5T583_RTC_AY_MIN, alarm_data,
+		NUM_YAL_REGS);
+	if (ret) {
+		dev_err(dev, "rtc_set_alarm error %d\n", ret);
+		return ret;
+	}
+
+	if (alm->enabled)
+		ret = rc5t583_rtc_alarm_irq_enable(dev, 1);
+
+	return ret;
+}
+
+static irqreturn_t rc5t583_rtc_interrupt(int irq, void *rtc)
+{
+	struct device *dev = rtc;
+	struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+	struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev);
+	unsigned long events = 0;
+	int ret;
+	u32 rtc_reg;
+
+	ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL2, &rtc_reg);
+	if (ret < 0)
+		return IRQ_NONE;
+
+	if (rtc_reg & GET_YAL_STATUS) {
+		events = RTC_IRQF | RTC_AF;
+		/* clear pending Y-alarm interrupt bit */
+		rtc_reg &= ~GET_YAL_STATUS;
+	}
+
+	ret = regmap_write(rc5t583->regmap, RC5T583_RTC_CTL2, rtc_reg);
+	if (ret)
+		return IRQ_NONE;
+
+	/* Notify RTC core on event */
+	rtc_update_irq(rc5t583_rtc->rtc, 1, events);
+
+	return IRQ_HANDLED;
+}
+
+static const struct rtc_class_ops rc5t583_rtc_ops = {
+	.read_time	= rc5t583_rtc_read_time,
+	.set_time	= rc5t583_rtc_set_time,
+	.read_alarm	= rc5t583_rtc_read_alarm,
+	.set_alarm	= rc5t583_rtc_set_alarm,
+	.alarm_irq_enable = rc5t583_rtc_alarm_irq_enable,
+};
+
+static int __devinit rc5t583_rtc_probe(struct platform_device *pdev)
+{
+	struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent);
+	struct rc5t583_rtc *ricoh_rtc;
+	struct rc5t583_platform_data *pmic_plat_data;
+	int ret;
+	int irq;
+
+	ricoh_rtc = devm_kzalloc(&pdev->dev, sizeof(struct rc5t583_rtc),
+			GFP_KERNEL);
+	if (!ricoh_rtc)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, ricoh_rtc);
+
+	/* Clear pending interrupts */
+	ret = regmap_write(rc5t583->regmap, RC5T583_RTC_CTL2, 0);
+	if (ret < 0)
+		return ret;
+
+	/* clear RTC Adjust register */
+	ret = regmap_write(rc5t583->regmap, RC5T583_RTC_ADJ, 0);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "unable to program rtc_adjust reg\n");
+		return -EBUSY;
+	}
+
+	pmic_plat_data = dev_get_platdata(rc5t583->dev);
+	irq = pmic_plat_data->irq_base;
+	if (irq <= 0) {
+		dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n",
+			irq);
+		return ret;
+	}
+
+	irq += RC5T583_IRQ_YALE;
+	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+		rc5t583_rtc_interrupt, IRQF_TRIGGER_LOW,
+		"rtc-rc5t583", &pdev->dev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "IRQ is not free.\n");
+		return ret;
+	}
+	device_init_wakeup(&pdev->dev, 1);
+
+	ricoh_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+		&rc5t583_rtc_ops, THIS_MODULE);
+	if (IS_ERR(ricoh_rtc->rtc)) {
+		ret = PTR_ERR(ricoh_rtc->rtc);
+		dev_err(&pdev->dev, "RTC device register: err %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * Disable rc5t583 RTC interrupts.
+ * Sets status flag to free.
+ */
+static int __devexit rc5t583_rtc_remove(struct platform_device *pdev)
+{
+	struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(&pdev->dev);
+
+	rc5t583_rtc_alarm_irq_enable(&rc5t583_rtc->rtc->dev, 0);
+
+	rtc_device_unregister(rc5t583_rtc->rtc);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+
+static int rc5t583_rtc_suspend(struct device *dev)
+{
+	struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+	struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev);
+	int ret;
+
+	/* Store current list of enabled interrupts*/
+	ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL1,
+		&rc5t583_rtc->irqen);
+	return ret;
+}
+
+static int rc5t583_rtc_resume(struct device *dev)
+{
+	struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+	struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev);
+
+	/* Restore list of enabled interrupts before suspend */
+	return regmap_write(rc5t583->regmap, RC5T583_RTC_CTL1,
+		rc5t583_rtc->irqen);
+}
+
+static const struct dev_pm_ops rc5t583_rtc_pm_ops = {
+	.suspend	= rc5t583_rtc_suspend,
+	.resume		= rc5t583_rtc_resume,
+};
+
+#define DEV_PM_OPS     (&rc5t583_rtc_pm_ops)
+#else
+#define DEV_PM_OPS     NULL
+#endif
+
+static struct platform_driver rc5t583_rtc_driver = {
+	.probe		= rc5t583_rtc_probe,
+	.remove		= __devexit_p(rc5t583_rtc_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= "rtc-rc5t583",
+		.pm	= DEV_PM_OPS,
+	},
+};
+
+module_platform_driver(rc5t583_rtc_driver);
+MODULE_ALIAS("platform:rtc-rc5t583");
+MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index fb4842c3544e..76f565ae384d 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -104,7 +104,12 @@ static int rs5c_get_regs(struct rs5c372 *rs5c)
 {
 	struct i2c_client	*client = rs5c->client;
 	struct i2c_msg		msgs[] = {
-		{ client->addr, I2C_M_RD, sizeof rs5c->buf, rs5c->buf },
+		{
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = sizeof(rs5c->buf),
+			.buf = rs5c->buf
+		},
 	};
 
 	/* This implements the third reading method from the datasheet, using
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
index c9562ceedef3..8a092325188d 100644
--- a/drivers/rtc/rtc-s35390a.c
+++ b/drivers/rtc/rtc-s35390a.c
@@ -19,6 +19,8 @@
 #define S35390A_CMD_STATUS1	0
 #define S35390A_CMD_STATUS2	1
 #define S35390A_CMD_TIME1	2
+#define S35390A_CMD_TIME2	3
+#define S35390A_CMD_INT2_REG1	5
 
 #define S35390A_BYTE_YEAR	0
 #define S35390A_BYTE_MONTH	1
@@ -28,12 +30,23 @@
 #define S35390A_BYTE_MINS	5
 #define S35390A_BYTE_SECS	6
 
+#define S35390A_ALRM_BYTE_WDAY	0
+#define S35390A_ALRM_BYTE_HOURS	1
+#define S35390A_ALRM_BYTE_MINS	2
+
 #define S35390A_FLAG_POC	0x01
 #define S35390A_FLAG_BLD	0x02
 #define S35390A_FLAG_24H	0x40
 #define S35390A_FLAG_RESET	0x80
 #define S35390A_FLAG_TEST	0x01
 
+#define S35390A_INT2_MODE_MASK		0xF0
+
+#define S35390A_INT2_MODE_NOINTR	0x00
+#define S35390A_INT2_MODE_FREQ		0x10
+#define S35390A_INT2_MODE_ALARM		0x40
+#define S35390A_INT2_MODE_PMIN_EDG	0x20
+
 static const struct i2c_device_id s35390a_id[] = {
 	{ "s35390a", 0 },
 	{ }
@@ -50,7 +63,11 @@ static int s35390a_set_reg(struct s35390a *s35390a, int reg, char *buf, int len)
 {
 	struct i2c_client *client = s35390a->client[reg];
 	struct i2c_msg msg[] = {
-		{ client->addr, 0, len, buf },
+		{
+			.addr = client->addr,
+			.len = len,
+			.buf = buf
+		},
 	};
 
 	if ((i2c_transfer(client->adapter, msg, 1)) != 1)
@@ -63,7 +80,12 @@ static int s35390a_get_reg(struct s35390a *s35390a, int reg, char *buf, int len)
 {
 	struct i2c_client *client = s35390a->client[reg];
 	struct i2c_msg msg[] = {
-		{ client->addr, I2C_M_RD, len, buf },
+		{
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = len,
+			.buf = buf
+		},
 	};
 
 	if ((i2c_transfer(client->adapter, msg, 1)) != 1)
@@ -184,6 +206,104 @@ static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm)
 	return rtc_valid_tm(tm);
 }
 
+static int s35390a_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alm)
+{
+	struct s35390a *s35390a = i2c_get_clientdata(client);
+	char buf[3], sts = 0;
+	int err, i;
+
+	dev_dbg(&client->dev, "%s: alm is secs=%d, mins=%d, hours=%d mday=%d, "\
+		"mon=%d, year=%d, wday=%d\n", __func__, alm->time.tm_sec,
+		alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday,
+		alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday);
+
+	/* disable interrupt */
+	err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
+	if (err < 0)
+		return err;
+
+	/* clear pending interrupt, if any */
+	err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, &sts, sizeof(sts));
+	if (err < 0)
+		return err;
+
+	if (alm->enabled)
+		sts = S35390A_INT2_MODE_ALARM;
+	else
+		sts = S35390A_INT2_MODE_NOINTR;
+
+	/* This chip expects the bits of each byte to be in reverse order */
+	sts = bitrev8(sts);
+
+	/* set interupt mode*/
+	err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
+	if (err < 0)
+		return err;
+
+	if (alm->time.tm_wday != -1)
+		buf[S35390A_ALRM_BYTE_WDAY] = bin2bcd(alm->time.tm_wday) | 0x80;
+
+	buf[S35390A_ALRM_BYTE_HOURS] = s35390a_hr2reg(s35390a,
+			alm->time.tm_hour) | 0x80;
+	buf[S35390A_ALRM_BYTE_MINS] = bin2bcd(alm->time.tm_min) | 0x80;
+
+	if (alm->time.tm_hour >= 12)
+		buf[S35390A_ALRM_BYTE_HOURS] |= 0x40;
+
+	for (i = 0; i < 3; ++i)
+		buf[i] = bitrev8(buf[i]);
+
+	err = s35390a_set_reg(s35390a, S35390A_CMD_INT2_REG1, buf,
+								sizeof(buf));
+
+	return err;
+}
+
+static int s35390a_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alm)
+{
+	struct s35390a *s35390a = i2c_get_clientdata(client);
+	char buf[3], sts;
+	int i, err;
+
+	err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
+	if (err < 0)
+		return err;
+
+	if (bitrev8(sts) != S35390A_INT2_MODE_ALARM)
+		return -EINVAL;
+
+	err = s35390a_get_reg(s35390a, S35390A_CMD_INT2_REG1, buf, sizeof(buf));
+	if (err < 0)
+		return err;
+
+	/* This chip returns the bits of each byte in reverse order */
+	for (i = 0; i < 3; ++i) {
+		buf[i] = bitrev8(buf[i]);
+		buf[i] &= ~0x80;
+	}
+
+	alm->time.tm_wday = bcd2bin(buf[S35390A_ALRM_BYTE_WDAY]);
+	alm->time.tm_hour = s35390a_reg2hr(s35390a,
+						buf[S35390A_ALRM_BYTE_HOURS]);
+	alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS]);
+
+	dev_dbg(&client->dev, "%s: alm is mins=%d, hours=%d, wday=%d\n",
+			__func__, alm->time.tm_min, alm->time.tm_hour,
+			alm->time.tm_wday);
+
+	return 0;
+}
+
+static int s35390a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	return s35390a_read_alarm(to_i2c_client(dev), alm);
+}
+
+static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	return s35390a_set_alarm(to_i2c_client(dev), alm);
+}
+
 static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
 	return s35390a_get_datetime(to_i2c_client(dev), tm);
@@ -197,6 +317,9 @@ static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm)
 static const struct rtc_class_ops s35390a_rtc_ops = {
 	.read_time	= s35390a_rtc_read_time,
 	.set_time	= s35390a_rtc_set_time,
+	.set_alarm	= s35390a_rtc_set_alarm,
+	.read_alarm	= s35390a_rtc_read_alarm,
+
 };
 
 static struct i2c_driver s35390a_driver;
@@ -261,6 +384,8 @@ static int s35390a_probe(struct i2c_client *client,
 	if (s35390a_get_datetime(client, &tm) < 0)
 		dev_warn(&client->dev, "clock needs to be set\n");
 
+	device_set_wakeup_capable(&client->dev, 1);
+
 	s35390a->rtc = rtc_device_register(s35390a_driver.driver.name,
 				&client->dev, &s35390a_rtc_ops, THIS_MODULE);
 
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index bfbd92c8d1c9..77823d21d314 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -476,13 +476,13 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
 	s3c_rtc_tickno = platform_get_irq(pdev, 1);
 	if (s3c_rtc_tickno < 0) {
 		dev_err(&pdev->dev, "no irq for rtc tick\n");
-		return -ENOENT;
+		return s3c_rtc_tickno;
 	}
 
 	s3c_rtc_alarmno = platform_get_irq(pdev, 0);
 	if (s3c_rtc_alarmno < 0) {
 		dev_err(&pdev->dev, "no irq for alarm\n");
-		return -ENOENT;
+		return s3c_rtc_alarmno;
 	}
 
 	pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d\n",
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c
new file mode 100644
index 000000000000..3c0da333f465
--- /dev/null
+++ b/drivers/rtc/rtc-snvs.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+/* These register offsets are relative to LP (Low Power) range */
+#define SNVS_LPCR		0x04
+#define SNVS_LPSR		0x18
+#define SNVS_LPSRTCMR		0x1c
+#define SNVS_LPSRTCLR		0x20
+#define SNVS_LPTAR		0x24
+#define SNVS_LPPGDR		0x30
+
+#define SNVS_LPCR_SRTC_ENV	(1 << 0)
+#define SNVS_LPCR_LPTA_EN	(1 << 1)
+#define SNVS_LPCR_LPWUI_EN	(1 << 3)
+#define SNVS_LPSR_LPTA		(1 << 0)
+
+#define SNVS_LPPGDR_INIT	0x41736166
+#define CNTR_TO_SECS_SH		15
+
+struct snvs_rtc_data {
+	struct rtc_device *rtc;
+	void __iomem *ioaddr;
+	int irq;
+	spinlock_t lock;
+};
+
+static u32 rtc_read_lp_counter(void __iomem *ioaddr)
+{
+	u64 read1, read2;
+
+	do {
+		read1 = readl(ioaddr + SNVS_LPSRTCMR);
+		read1 <<= 32;
+		read1 |= readl(ioaddr + SNVS_LPSRTCLR);
+
+		read2 = readl(ioaddr + SNVS_LPSRTCMR);
+		read2 <<= 32;
+		read2 |= readl(ioaddr + SNVS_LPSRTCLR);
+	} while (read1 != read2);
+
+	/* Convert 47-bit counter to 32-bit raw second count */
+	return (u32) (read1 >> CNTR_TO_SECS_SH);
+}
+
+static void rtc_write_sync_lp(void __iomem *ioaddr)
+{
+	u32 count1, count2, count3;
+	int i;
+
+	/* Wait for 3 CKIL cycles */
+	for (i = 0; i < 3; i++) {
+		do {
+			count1 = readl(ioaddr + SNVS_LPSRTCLR);
+			count2 = readl(ioaddr + SNVS_LPSRTCLR);
+		} while (count1 != count2);
+
+		/* Now wait until counter value changes */
+		do {
+			do {
+				count2 = readl(ioaddr + SNVS_LPSRTCLR);
+				count3 = readl(ioaddr + SNVS_LPSRTCLR);
+			} while (count2 != count3);
+		} while (count3 == count1);
+	}
+}
+
+static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable)
+{
+	unsigned long flags;
+	int timeout = 1000;
+	u32 lpcr;
+
+	spin_lock_irqsave(&data->lock, flags);
+
+	lpcr = readl(data->ioaddr + SNVS_LPCR);
+	if (enable)
+		lpcr |= SNVS_LPCR_SRTC_ENV;
+	else
+		lpcr &= ~SNVS_LPCR_SRTC_ENV;
+	writel(lpcr, data->ioaddr + SNVS_LPCR);
+
+	spin_unlock_irqrestore(&data->lock, flags);
+
+	while (--timeout) {
+		lpcr = readl(data->ioaddr + SNVS_LPCR);
+
+		if (enable) {
+			if (lpcr & SNVS_LPCR_SRTC_ENV)
+				break;
+		} else {
+			if (!(lpcr & SNVS_LPCR_SRTC_ENV))
+				break;
+		}
+	}
+
+	if (!timeout)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct snvs_rtc_data *data = dev_get_drvdata(dev);
+	unsigned long time = rtc_read_lp_counter(data->ioaddr);
+
+	rtc_time_to_tm(time, tm);
+
+	return 0;
+}
+
+static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct snvs_rtc_data *data = dev_get_drvdata(dev);
+	unsigned long time;
+
+	rtc_tm_to_time(tm, &time);
+
+	/* Disable RTC first */
+	snvs_rtc_enable(data, false);
+
+	/* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */
+	writel(time << CNTR_TO_SECS_SH, data->ioaddr + SNVS_LPSRTCLR);
+	writel(time >> (32 - CNTR_TO_SECS_SH), data->ioaddr + SNVS_LPSRTCMR);
+
+	/* Enable RTC again */
+	snvs_rtc_enable(data, true);
+
+	return 0;
+}
+
+static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct snvs_rtc_data *data = dev_get_drvdata(dev);
+	u32 lptar, lpsr;
+
+	lptar = readl(data->ioaddr + SNVS_LPTAR);
+	rtc_time_to_tm(lptar, &alrm->time);
+
+	lpsr = readl(data->ioaddr + SNVS_LPSR);
+	alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0;
+
+	return 0;
+}
+
+static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
+{
+	struct snvs_rtc_data *data = dev_get_drvdata(dev);
+	u32 lpcr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&data->lock, flags);
+
+	lpcr = readl(data->ioaddr + SNVS_LPCR);
+	if (enable)
+		lpcr |= (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN);
+	else
+		lpcr &= ~(SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN);
+	writel(lpcr, data->ioaddr + SNVS_LPCR);
+
+	spin_unlock_irqrestore(&data->lock, flags);
+
+	rtc_write_sync_lp(data->ioaddr);
+
+	return 0;
+}
+
+static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct snvs_rtc_data *data = dev_get_drvdata(dev);
+	struct rtc_time *alrm_tm = &alrm->time;
+	unsigned long time;
+	unsigned long flags;
+	u32 lpcr;
+
+	rtc_tm_to_time(alrm_tm, &time);
+
+	spin_lock_irqsave(&data->lock, flags);
+
+	/* Have to clear LPTA_EN before programming new alarm time in LPTAR */
+	lpcr = readl(data->ioaddr + SNVS_LPCR);
+	lpcr &= ~SNVS_LPCR_LPTA_EN;
+	writel(lpcr, data->ioaddr + SNVS_LPCR);
+
+	spin_unlock_irqrestore(&data->lock, flags);
+
+	writel(time, data->ioaddr + SNVS_LPTAR);
+
+	/* Clear alarm interrupt status bit */
+	writel(SNVS_LPSR_LPTA, data->ioaddr + SNVS_LPSR);
+
+	return snvs_rtc_alarm_irq_enable(dev, alrm->enabled);
+}
+
+static const struct rtc_class_ops snvs_rtc_ops = {
+	.read_time = snvs_rtc_read_time,
+	.set_time = snvs_rtc_set_time,
+	.read_alarm = snvs_rtc_read_alarm,
+	.set_alarm = snvs_rtc_set_alarm,
+	.alarm_irq_enable = snvs_rtc_alarm_irq_enable,
+};
+
+static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id)
+{
+	struct device *dev = dev_id;
+	struct snvs_rtc_data *data = dev_get_drvdata(dev);
+	u32 lpsr;
+	u32 events = 0;
+
+	lpsr = readl(data->ioaddr + SNVS_LPSR);
+
+	if (lpsr & SNVS_LPSR_LPTA) {
+		events |= (RTC_AF | RTC_IRQF);
+
+		/* RTC alarm should be one-shot */
+		snvs_rtc_alarm_irq_enable(dev, 0);
+
+		rtc_update_irq(data->rtc, 1, events);
+	}
+
+	/* clear interrupt status */
+	writel(lpsr, data->ioaddr + SNVS_LPSR);
+
+	return events ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static int __devinit snvs_rtc_probe(struct platform_device *pdev)
+{
+	struct snvs_rtc_data *data;
+	struct resource *res;
+	int ret;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	data->ioaddr = devm_request_and_ioremap(&pdev->dev, res);
+	if (!data->ioaddr)
+		return -EADDRNOTAVAIL;
+
+	data->irq = platform_get_irq(pdev, 0);
+	if (data->irq < 0)
+		return data->irq;
+
+	platform_set_drvdata(pdev, data);
+
+	spin_lock_init(&data->lock);
+
+	/* Initialize glitch detect */
+	writel(SNVS_LPPGDR_INIT, data->ioaddr + SNVS_LPPGDR);
+
+	/* Clear interrupt status */
+	writel(0xffffffff, data->ioaddr + SNVS_LPSR);
+
+	/* Enable RTC */
+	snvs_rtc_enable(data, true);
+
+	device_init_wakeup(&pdev->dev, true);
+
+	ret = devm_request_irq(&pdev->dev, data->irq, snvs_rtc_irq_handler,
+			       IRQF_SHARED, "rtc alarm", &pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to request irq %d: %d\n",
+			data->irq, ret);
+		return ret;
+	}
+
+	data->rtc = rtc_device_register(pdev->name, &pdev->dev,
+					&snvs_rtc_ops, THIS_MODULE);
+	if (IS_ERR(data->rtc)) {
+		ret = PTR_ERR(data->rtc);
+		dev_err(&pdev->dev, "failed to register rtc: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int __devexit snvs_rtc_remove(struct platform_device *pdev)
+{
+	struct snvs_rtc_data *data = platform_get_drvdata(pdev);
+
+	rtc_device_unregister(data->rtc);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int snvs_rtc_suspend(struct device *dev)
+{
+	struct snvs_rtc_data *data = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		enable_irq_wake(data->irq);
+
+	return 0;
+}
+
+static int snvs_rtc_resume(struct device *dev)
+{
+	struct snvs_rtc_data *data = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		disable_irq_wake(data->irq);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(snvs_rtc_pm_ops, snvs_rtc_suspend, snvs_rtc_resume);
+
+static const struct of_device_id __devinitconst snvs_dt_ids[] = {
+	{ .compatible = "fsl,sec-v4.0-mon-rtc-lp", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, snvs_dt_ids);
+
+static struct platform_driver snvs_rtc_driver = {
+	.driver = {
+		.name	= "snvs_rtc",
+		.owner	= THIS_MODULE,
+		.pm	= &snvs_rtc_pm_ops,
+		.of_match_table = snvs_dt_ids,
+	},
+	.probe		= snvs_rtc_probe,
+	.remove		= __devexit_p(snvs_rtc_remove),
+};
+module_platform_driver(snvs_rtc_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Freescale SNVS RTC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c
index e2785479113c..bb507d23f6ce 100644
--- a/drivers/rtc/rtc-spear.c
+++ b/drivers/rtc/rtc-spear.c
@@ -235,7 +235,7 @@ static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm)
 static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
 	struct spear_rtc_config *config = dev_get_drvdata(dev);
-	unsigned int time, date, err = 0;
+	unsigned int time, date;
 
 	if (tm2bcd(tm) < 0)
 		return -EINVAL;
@@ -247,11 +247,8 @@ static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm)
 		(tm->tm_year << YEAR_SHIFT);
 	writel(time, config->ioaddr + TIME_REG);
 	writel(date, config->ioaddr + DATE_REG);
-	err = is_write_complete(config);
-	if (err < 0)
-		return err;
 
-	return 0;
+	return is_write_complete(config);
 }
 
 /*
@@ -295,7 +292,8 @@ static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
 static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 {
 	struct spear_rtc_config *config = dev_get_drvdata(dev);
-	unsigned int time, date, err = 0;
+	unsigned int time, date;
+	int err;
 
 	if (tm2bcd(&alm->time) < 0)
 		return -EINVAL;
@@ -357,7 +355,7 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	struct spear_rtc_config *config;
-	unsigned int status = 0;
+	int status = 0;
 	int irq;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index 380083ca572f..b70e2bb63645 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -102,6 +102,12 @@ rtc_sysfs_set_max_user_freq(struct device *dev, struct device_attribute *attr,
 	return n;
 }
 
+/**
+ * rtc_sysfs_show_hctosys - indicate if the given RTC set the system time
+ *
+ * Returns 1 if the system clock was set by this RTC at the last
+ * boot or resume event.
+ */
 static ssize_t
 rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr,
 		char *buf)
diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c
new file mode 100644
index 000000000000..7a82337e4dee
--- /dev/null
+++ b/drivers/rtc/rtc-tps65910.c
@@ -0,0 +1,349 @@
+/*
+ * rtc-tps65910.c -- TPS65910 Real Time Clock interface
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ * Author: Venu Byravarasu <vbyravarasu@nvidia.com>
+ *
+ * Based on original TI driver rtc-twl.c
+ *   Copyright (C) 2007 MontaVista Software, Inc
+ *   Author: Alexandre Rusev <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/tps65910.h>
+
+struct tps65910_rtc {
+	struct rtc_device	*rtc;
+	/* To store the list of enabled interrupts */
+	u32 irqstat;
+};
+
+/* Total number of RTC registers needed to set time*/
+#define NUM_TIME_REGS	(TPS65910_YEARS - TPS65910_SECONDS + 1)
+
+static int tps65910_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
+{
+	struct tps65910 *tps = dev_get_drvdata(dev->parent);
+	u8 val = 0;
+
+	if (enabled)
+		val = TPS65910_RTC_INTERRUPTS_IT_ALARM;
+
+	return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, val);
+}
+
+/*
+ * Gets current tps65910 RTC time and date parameters.
+ *
+ * The RTC's time/alarm representation is not what gmtime(3) requires
+ * Linux to use:
+ *
+ *  - Months are 1..12 vs Linux 0-11
+ *  - Years are 0..99 vs Linux 1900..N (we assume 21st century)
+ */
+static int tps65910_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	unsigned char rtc_data[NUM_TIME_REGS];
+	struct tps65910 *tps = dev_get_drvdata(dev->parent);
+	int ret;
+
+	/* Copy RTC counting registers to static registers or latches */
+	ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL,
+		TPS65910_RTC_CTRL_GET_TIME, TPS65910_RTC_CTRL_GET_TIME);
+	if (ret < 0) {
+		dev_err(dev, "RTC CTRL reg update failed with err:%d\n", ret);
+		return ret;
+	}
+
+	ret = regmap_bulk_read(tps->regmap, TPS65910_SECONDS, rtc_data,
+		NUM_TIME_REGS);
+	if (ret < 0) {
+		dev_err(dev, "reading from RTC failed with err:%d\n", ret);
+		return ret;
+	}
+
+	tm->tm_sec = bcd2bin(rtc_data[0]);
+	tm->tm_min = bcd2bin(rtc_data[1]);
+	tm->tm_hour = bcd2bin(rtc_data[2]);
+	tm->tm_mday = bcd2bin(rtc_data[3]);
+	tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
+	tm->tm_year = bcd2bin(rtc_data[5]) + 100;
+
+	return ret;
+}
+
+static int tps65910_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	unsigned char rtc_data[NUM_TIME_REGS];
+	struct tps65910 *tps = dev_get_drvdata(dev->parent);
+	int ret;
+
+	rtc_data[0] = bin2bcd(tm->tm_sec);
+	rtc_data[1] = bin2bcd(tm->tm_min);
+	rtc_data[2] = bin2bcd(tm->tm_hour);
+	rtc_data[3] = bin2bcd(tm->tm_mday);
+	rtc_data[4] = bin2bcd(tm->tm_mon + 1);
+	rtc_data[5] = bin2bcd(tm->tm_year - 100);
+
+	/* Stop RTC while updating the RTC time registers */
+	ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL,
+		TPS65910_RTC_CTRL_STOP_RTC, 0);
+	if (ret < 0) {
+		dev_err(dev, "RTC stop failed with err:%d\n", ret);
+		return ret;
+	}
+
+	/* update all the time registers in one shot */
+	ret = regmap_bulk_write(tps->regmap, TPS65910_SECONDS, rtc_data,
+		NUM_TIME_REGS);
+	if (ret < 0) {
+		dev_err(dev, "rtc_set_time error %d\n", ret);
+		return ret;
+	}
+
+	/* Start back RTC */
+	ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL,
+		TPS65910_RTC_CTRL_STOP_RTC, 1);
+	if (ret < 0)
+		dev_err(dev, "RTC start failed with err:%d\n", ret);
+
+	return ret;
+}
+
+/*
+ * Gets current tps65910 RTC alarm time.
+ */
+static int tps65910_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	unsigned char alarm_data[NUM_TIME_REGS];
+	u32 int_val;
+	struct tps65910 *tps = dev_get_drvdata(dev->parent);
+	int ret;
+
+	ret = regmap_bulk_read(tps->regmap, TPS65910_SECONDS, alarm_data,
+		NUM_TIME_REGS);
+	if (ret < 0) {
+		dev_err(dev, "rtc_read_alarm error %d\n", ret);
+		return ret;
+	}
+
+	alm->time.tm_sec = bcd2bin(alarm_data[0]);
+	alm->time.tm_min = bcd2bin(alarm_data[1]);
+	alm->time.tm_hour = bcd2bin(alarm_data[2]);
+	alm->time.tm_mday = bcd2bin(alarm_data[3]);
+	alm->time.tm_mon = bcd2bin(alarm_data[4]) - 1;
+	alm->time.tm_year = bcd2bin(alarm_data[5]) + 100;
+
+	ret = regmap_read(tps->regmap, TPS65910_RTC_INTERRUPTS, &int_val);
+	if (ret < 0)
+		return ret;
+
+	if (int_val & TPS65910_RTC_INTERRUPTS_IT_ALARM)
+		alm->enabled = 1;
+
+	return ret;
+}
+
+static int tps65910_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	unsigned char alarm_data[NUM_TIME_REGS];
+	struct tps65910 *tps = dev_get_drvdata(dev->parent);
+	int ret;
+
+	ret = tps65910_rtc_alarm_irq_enable(dev, 0);
+	if (ret)
+		return ret;
+
+	alarm_data[0] = bin2bcd(alm->time.tm_sec);
+	alarm_data[1] = bin2bcd(alm->time.tm_min);
+	alarm_data[2] = bin2bcd(alm->time.tm_hour);
+	alarm_data[3] = bin2bcd(alm->time.tm_mday);
+	alarm_data[4] = bin2bcd(alm->time.tm_mon + 1);
+	alarm_data[5] = bin2bcd(alm->time.tm_year - 100);
+
+	/* update all the alarm registers in one shot */
+	ret = regmap_bulk_write(tps->regmap, TPS65910_ALARM_SECONDS,
+		alarm_data, NUM_TIME_REGS);
+	if (ret) {
+		dev_err(dev, "rtc_set_alarm error %d\n", ret);
+		return ret;
+	}
+
+	if (alm->enabled)
+		ret = tps65910_rtc_alarm_irq_enable(dev, 1);
+
+	return ret;
+}
+
+static irqreturn_t tps65910_rtc_interrupt(int irq, void *rtc)
+{
+	struct device *dev = rtc;
+	unsigned long events = 0;
+	struct tps65910 *tps = dev_get_drvdata(dev->parent);
+	struct tps65910_rtc *tps_rtc = dev_get_drvdata(dev);
+	int ret;
+	u32 rtc_reg;
+
+	ret = regmap_read(tps->regmap, TPS65910_RTC_STATUS, &rtc_reg);
+	if (ret)
+		return IRQ_NONE;
+
+	if (rtc_reg & TPS65910_RTC_STATUS_ALARM)
+		events = RTC_IRQF | RTC_AF;
+
+	ret = regmap_write(tps->regmap, TPS65910_RTC_STATUS, rtc_reg);
+	if (ret)
+		return IRQ_NONE;
+
+	/* Notify RTC core on event */
+	rtc_update_irq(tps_rtc->rtc, 1, events);
+
+	return IRQ_HANDLED;
+}
+
+static const struct rtc_class_ops tps65910_rtc_ops = {
+	.read_time	= tps65910_rtc_read_time,
+	.set_time	= tps65910_rtc_set_time,
+	.read_alarm	= tps65910_rtc_read_alarm,
+	.set_alarm	= tps65910_rtc_set_alarm,
+	.alarm_irq_enable = tps65910_rtc_alarm_irq_enable,
+};
+
+static int __devinit tps65910_rtc_probe(struct platform_device *pdev)
+{
+	struct tps65910 *tps65910 = NULL;
+	struct tps65910_rtc *tps_rtc = NULL;
+	int ret;
+	int irq;
+	u32 rtc_reg;
+
+	tps65910 = dev_get_drvdata(pdev->dev.parent);
+
+	tps_rtc = devm_kzalloc(&pdev->dev, sizeof(struct tps65910_rtc),
+			GFP_KERNEL);
+	if (!tps_rtc)
+		return -ENOMEM;
+
+	/* Clear pending interrupts */
+	ret = regmap_read(tps65910->regmap, TPS65910_RTC_STATUS, &rtc_reg);
+	if (ret < 0)
+		return ret;
+
+	ret = regmap_write(tps65910->regmap, TPS65910_RTC_STATUS, rtc_reg);
+	if (ret < 0)
+		return ret;
+
+	dev_dbg(&pdev->dev, "Enabling rtc-tps65910.\n");
+	rtc_reg = TPS65910_RTC_CTRL_STOP_RTC;
+	ret = regmap_write(tps65910->regmap, TPS65910_RTC_CTRL, rtc_reg);
+	if (ret < 0)
+		return ret;
+
+	irq  = platform_get_irq(pdev, 0);
+	if (irq <= 0) {
+		dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n",
+			irq);
+		return ret;
+	}
+
+	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+		tps65910_rtc_interrupt, IRQF_TRIGGER_LOW,
+		"rtc-tps65910", &pdev->dev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "IRQ is not free.\n");
+		return ret;
+	}
+	device_init_wakeup(&pdev->dev, 1);
+
+	tps_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+		&tps65910_rtc_ops, THIS_MODULE);
+	if (IS_ERR(tps_rtc->rtc)) {
+		ret = PTR_ERR(tps_rtc->rtc);
+		dev_err(&pdev->dev, "RTC device register: err %d\n", ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, tps_rtc);
+
+	return 0;
+}
+
+/*
+ * Disable tps65910 RTC interrupts.
+ * Sets status flag to free.
+ */
+static int __devexit tps65910_rtc_remove(struct platform_device *pdev)
+{
+	/* leave rtc running, but disable irqs */
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+
+	tps65910_rtc_alarm_irq_enable(&rtc->dev, 0);
+
+	rtc_device_unregister(rtc);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+
+static int tps65910_rtc_suspend(struct device *dev)
+{
+	struct tps65910 *tps = dev_get_drvdata(dev->parent);
+	u8 alarm = TPS65910_RTC_INTERRUPTS_IT_ALARM;
+	int ret;
+
+	/* Store current list of enabled interrupts*/
+	ret = regmap_read(tps->regmap, TPS65910_RTC_INTERRUPTS,
+		&tps->rtc->irqstat);
+	if (ret < 0)
+		return ret;
+
+	/* Enable RTC ALARM interrupt only */
+	return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, alarm);
+}
+
+static int tps65910_rtc_resume(struct device *dev)
+{
+	struct tps65910 *tps = dev_get_drvdata(dev->parent);
+
+	/* Restore list of enabled interrupts before suspend */
+	return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS,
+		tps->rtc->irqstat);
+}
+
+static const struct dev_pm_ops tps65910_rtc_pm_ops = {
+	.suspend	= tps65910_rtc_suspend,
+	.resume		= tps65910_rtc_resume,
+};
+
+#define DEV_PM_OPS     (&tps65910_rtc_pm_ops)
+#else
+#define DEV_PM_OPS     NULL
+#endif
+
+static struct platform_driver tps65910_rtc_driver = {
+	.probe		= tps65910_rtc_probe,
+	.remove		= __devexit_p(tps65910_rtc_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= "tps65910-rtc",
+		.pm	= DEV_PM_OPS,
+	},
+};
+
+module_platform_driver(tps65910_rtc_driver);
+MODULE_ALIAS("platform:rtc-tps65910");
+MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c
index 403b3d41d101..f36e59c6bc01 100644
--- a/drivers/rtc/rtc-x1205.c
+++ b/drivers/rtc/rtc-x1205.c
@@ -97,8 +97,17 @@ static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm,
 	int i;
 
 	struct i2c_msg msgs[] = {
-		{ client->addr, 0, 2, dt_addr },	/* setup read ptr */
-		{ client->addr, I2C_M_RD, 8, buf },	/* read date */
+		{/* setup read ptr */
+			.addr = client->addr,
+			.len = 2,
+			.buf = dt_addr
+		},
+		{/* read date */
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = 8,
+			.buf = buf
+		},
 	};
 
 	/* read date registers */
@@ -142,8 +151,17 @@ static int x1205_get_status(struct i2c_client *client, unsigned char *sr)
 	static unsigned char sr_addr[2] = { 0, X1205_REG_SR };
 
 	struct i2c_msg msgs[] = {
-		{ client->addr, 0, 2, sr_addr },	/* setup read ptr */
-		{ client->addr, I2C_M_RD, 1, sr },	/* read status */
+		{     /* setup read ptr */
+			.addr = client->addr,
+			.len = 2,
+			.buf = sr_addr
+		},
+		{    /* read status */
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = sr
+		},
 	};
 
 	/* read status register */
@@ -279,8 +297,17 @@ static int x1205_get_dtrim(struct i2c_client *client, int *trim)
 	static unsigned char dtr_addr[2] = { 0, X1205_REG_DTR };
 
 	struct i2c_msg msgs[] = {
-		{ client->addr, 0, 2, dtr_addr },	/* setup read ptr */
-		{ client->addr, I2C_M_RD, 1, &dtr }, 	/* read dtr */
+		{	/* setup read ptr */
+			.addr = client->addr,
+			.len = 2,
+			.buf = dtr_addr
+		},
+		{      /* read dtr */
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = &dtr
+		},
 	};
 
 	/* read dtr register */
@@ -311,8 +338,17 @@ static int x1205_get_atrim(struct i2c_client *client, int *trim)
 	static unsigned char atr_addr[2] = { 0, X1205_REG_ATR };
 
 	struct i2c_msg msgs[] = {
-		{ client->addr, 0, 2, atr_addr },	/* setup read ptr */
-		{ client->addr, I2C_M_RD, 1, &atr }, 	/* read atr */
+		{/* setup read ptr */
+			.addr = client->addr,
+			.len = 2,
+			.buf = atr_addr
+		},
+		{/* read atr */
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = &atr
+		},
 	};
 
 	/* read atr register */
@@ -381,8 +417,17 @@ static int x1205_validate_client(struct i2c_client *client)
 		unsigned char addr[2] = { 0, probe_zero_pattern[i] };
 
 		struct i2c_msg msgs[2] = {
-			{ client->addr, 0, 2, addr },
-			{ client->addr, I2C_M_RD, 1, &buf },
+			{
+				.addr = client->addr,
+				.len = 2,
+				.buf = addr
+			},
+			{
+				.addr = client->addr,
+				.flags = I2C_M_RD,
+				.len = 1,
+				.buf = &buf
+			},
 		};
 
 		if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) {
@@ -409,8 +454,17 @@ static int x1205_validate_client(struct i2c_client *client)
 		unsigned char addr[2] = { 0, probe_limits_pattern[i].reg };
 
 		struct i2c_msg msgs[2] = {
-			{ client->addr, 0, 2, addr },
-			{ client->addr, I2C_M_RD, 1, &reg },
+			{
+				.addr = client->addr,
+				.len = 2,
+				.buf = addr
+			},
+			{
+				.addr = client->addr,
+				.flags = I2C_M_RD,
+				.len = 1,
+				.buf = &reg
+			},
 		};
 
 		if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) {
@@ -444,8 +498,18 @@ static int x1205_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	static unsigned char int_addr[2] = { 0, X1205_REG_INT };
 	struct i2c_client *client = to_i2c_client(dev);
 	struct i2c_msg msgs[] = {
-		{ client->addr, 0, 2, int_addr },        /* setup read ptr */
-		{ client->addr, I2C_M_RD, 1, &intreg },  /* read INT register */
+		{ /* setup read ptr */
+			.addr = client->addr,
+			.len = 2,
+			.buf = int_addr
+		},
+		{/* read INT register */
+
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = &intreg
+		},
 	};
 
 	/* read interrupt register and status register */