Browse Source

Merge tag 'rtc-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux

Pull RTC updates from Alexandre Belloni:
 "Subsystem wide cleanups:
   - Use IS_ENABLED() instead of checking for built-in or module
   - remove useless DRV_VERSION
   - remove CLK_IS_ROOT
   - remove UIE signaling

  Drivers:
   - ds1302: rewritten to be a proper SPI device driver
   - m41t80: huge cleanup, alarm, wakelarm ans oscialltor failure
     detection support
   - rv3029: switch to regmap to handle rv3049, alarm support, fixes
   - zynqmp: enable switching to battery power, fixes
   - small fixes for at91sam9, da9053, ds1307, ds1685, ds3232, r2025,
     sa1100, snvs, stmp3xxx, tps6586x"

* tag 'rtc-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (40 commits)
  rtc: tps6586x: rename so module can be autoloaded
  rtc: rv3029: hide unused i2c device table
  rtc: rs5c372: r2025: fix check for 'oscillator halted' condition
  rtc: rv3029: add alarm IRQ
  rtc: rv3029: fix set_time function
  rtc: rv3029: fix alarm support
  rtc: rv3029: Remove some checks and warnings
  rtc: rv3029: Add support of RV3049
  rtc: rv3029: convert to use regmap
  rtc: rv3029: remove 'i2c' in functions names
  rtc: stmp3xxx: print message on error
  rtc: Use IS_ENABLED() instead of checking for built-in or module
  rtc: ds3232: fix call trace when rtc->ops_lock is used as NULL
  rtc: snvs: return error in case enable_irq_wake fails
  rtc: zynqmp: Update seconds time programming logic
  rtc: sa1100: DT spelling s/interrupt-name/interrupt-names/
  rtc: mc13xxx: remove UIE signaling
  rtc: mxc: remove UIE signaling
  rtc: ds1307: Remove CLK_IS_ROOT
  rtc: hym8563: Remove CLK_IS_ROOT
  ...
Linus Torvalds 9 years ago
parent
commit
63d222b9d2
43 changed files with 1019 additions and 735 deletions
  1. 46 0
      Documentation/devicetree/bindings/rtc/maxim-ds1302.txt
  2. 1 1
      Documentation/devicetree/bindings/rtc/sa1100-rtc.txt
  3. 28 24
      drivers/rtc/Kconfig
  4. 1 1
      drivers/rtc/rtc-at91sam9.c
  5. 1 1
      drivers/rtc/rtc-cmos.c
  6. 8 5
      drivers/rtc/rtc-da9052.c
  7. 0 3
      drivers/rtc/rtc-ds1216.c
  8. 0 3
      drivers/rtc/rtc-ds1286.c
  9. 156 192
      drivers/rtc/rtc-ds1302.c
  10. 14 9
      drivers/rtc/rtc-ds1307.c
  11. 0 2
      drivers/rtc/rtc-ds1343.c
  12. 0 3
      drivers/rtc/rtc-ds1511.c
  13. 0 3
      drivers/rtc/rtc-ds1553.c
  14. 0 5
      drivers/rtc/rtc-ds1672.c
  15. 1 3
      drivers/rtc/rtc-ds1685.c
  16. 0 3
      drivers/rtc/rtc-ds1742.c
  17. 6 3
      drivers/rtc/rtc-ds3232.c
  18. 0 3
      drivers/rtc/rtc-ep93xx.c
  19. 0 1
      drivers/rtc/rtc-gemini.c
  20. 1 1
      drivers/rtc/rtc-hym8563.c
  21. 0 5
      drivers/rtc/rtc-isl12022.c
  22. 0 6
      drivers/rtc/rtc-isl1208.c
  23. 293 154
      drivers/rtc/rtc-m41t80.c
  24. 0 3
      drivers/rtc/rtc-m48t35.c
  25. 0 4
      drivers/rtc/rtc-m48t86.c
  26. 0 5
      drivers/rtc/rtc-max6900.c
  27. 0 19
      drivers/rtc/rtc-mc13xxx.c
  28. 1 1
      drivers/rtc/rtc-mrst.c
  29. 0 3
      drivers/rtc/rtc-mxc.c
  30. 0 4
      drivers/rtc/rtc-pcf2123.c
  31. 1 6
      drivers/rtc/rtc-pcf8563.c
  32. 0 2
      drivers/rtc/rtc-rs5c313.c
  33. 0 4
      drivers/rtc/rtc-rs5c348.c
  34. 7 11
      drivers/rtc/rtc-rs5c372.c
  35. 385 211
      drivers/rtc/rtc-rv3029c2.c
  36. 0 5
      drivers/rtc/rtc-rx8581.c
  37. 0 2
      drivers/rtc/rtc-sh.c
  38. 1 1
      drivers/rtc/rtc-snvs.c
  39. 0 3
      drivers/rtc/rtc-stk17ta8.c
  40. 6 1
      drivers/rtc/rtc-stmp3xxx.c
  41. 1 1
      drivers/rtc/rtc-tps6586x.c
  42. 0 5
      drivers/rtc/rtc-x1205.c
  43. 61 13
      drivers/rtc/rtc-zynqmp.c

+ 46 - 0
Documentation/devicetree/bindings/rtc/maxim-ds1302.txt

@@ -0,0 +1,46 @@
+* Maxim/Dallas Semiconductor DS-1302 RTC
+
+Simple device which could be used to store date/time between reboots.
+
+The device uses the standard MicroWire half-duplex transfer timing.
+Master output is set on low clock and sensed by the RTC on the rising
+edge. Master input is set by the RTC on the trailing edge and is sensed
+by the master on low clock.
+
+Required properties:
+
+- compatible : Should be "maxim,ds1302"
+
+Required SPI properties:
+
+- reg : Should be address of the device chip select within
+  the controller.
+
+- spi-max-frequency : DS-1302 has 500 kHz if powered at 2.2V,
+  and 2MHz if powered at 5V.
+
+- spi-3wire : The device has a shared signal IN/OUT line.
+
+- spi-lsb-first : DS-1302 requires least significant bit first
+  transfers.
+
+- spi-cs-high: DS-1302 has active high chip select line. This is
+  required unless inverted in hardware.
+
+Example:
+
+spi@901c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "icpdas,lp8841-spi-rtc";
+	reg = <0x901c 0x1>;
+
+	rtc@0 {
+		compatible = "maxim,ds1302";
+		reg = <0>;
+		spi-max-frequency = <500000>;
+		spi-3wire;
+		spi-lsb-first;
+		spi-cs-high;
+	};
+};

+ 1 - 1
Documentation/devicetree/bindings/rtc/sa1100-rtc.txt

@@ -13,5 +13,5 @@ Example:
 		compatible = "mrvl,mmp-rtc";
 		compatible = "mrvl,mmp-rtc";
 		reg = <0xd4010000 0x1000>;
 		reg = <0xd4010000 0x1000>;
 		interrupts = <5>, <6>;
 		interrupts = <5>, <6>;
-		interrupt-name = "rtc 1Hz", "rtc alarm";
+		interrupt-names = "rtc 1Hz", "rtc alarm";
 	};
 	};

+ 28 - 24
drivers/rtc/Kconfig

@@ -573,24 +573,6 @@ config RTC_DRV_EM3027
 	  This driver can also be built as a module. If so, the module
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-em3027.
 	  will be called rtc-em3027.
 
 
-config RTC_DRV_RV3029C2
-	tristate "Micro Crystal RV3029"
-	help
-	  If you say yes here you get support for the Micro Crystal
-	  RV3029 RTC chips.
-
-	  This driver can also be built as a module. If so, the module
-	  will be called rtc-rv3029c2.
-
-config RTC_DRV_RV3029_HWMON
-	bool "HWMON support for RV3029"
-	depends on RTC_DRV_RV3029C2 && HWMON
-	depends on !(RTC_DRV_RV3029C2=y && HWMON=m)
-	default y
-	help
-	  Say Y here if you want to expose temperature sensor data on
-	  rtc-rv3029.
-
 config RTC_DRV_RV8803
 config RTC_DRV_RV8803
 	tristate "Micro Crystal RV8803"
 	tristate "Micro Crystal RV8803"
 	help
 	help
@@ -634,6 +616,15 @@ config RTC_DRV_M41T94
 	  This driver can also be built as a module. If so, the module
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-m41t94.
 	  will be called rtc-m41t94.
 
 
+config RTC_DRV_DS1302
+	tristate "Dallas/Maxim DS1302"
+	depends on SPI
+	help
+	  If you say yes here you get support for the Dallas DS1302 RTC chips.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-ds1302.
+
 config RTC_DRV_DS1305
 config RTC_DRV_DS1305
 	tristate "Dallas/Maxim DS1305/DS1306"
 	tristate "Dallas/Maxim DS1305/DS1306"
 	help
 	help
@@ -777,6 +768,25 @@ config RTC_DRV_PCF2127
 	  This driver can also be built as a module. If so, the module
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-pcf2127.
 	  will be called rtc-pcf2127.
 
 
+config RTC_DRV_RV3029C2
+	tristate "Micro Crystal RV3029/3049"
+	depends on RTC_I2C_AND_SPI
+	help
+	  If you say yes here you get support for the Micro Crystal
+	  RV3029 and RV3049 RTC chips.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-rv3029c2.
+
+config RTC_DRV_RV3029_HWMON
+	bool "HWMON support for RV3029/3049"
+	depends on RTC_DRV_RV3029C2 && HWMON
+	depends on !(RTC_DRV_RV3029C2=y && HWMON=m)
+	default y
+	help
+	  Say Y here if you want to expose temperature sensor data on
+	  rtc-rv3029.
+
 comment "Platform RTC drivers"
 comment "Platform RTC drivers"
 
 
 # this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h>
 # this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h>
@@ -834,12 +844,6 @@ config RTC_DRV_DS1286
 	help
 	help
 	  If you say yes here you get support for the Dallas DS1286 RTC chips.
 	  If you say yes here you get support for the Dallas DS1286 RTC chips.
 
 
-config RTC_DRV_DS1302
-	tristate "Dallas DS1302"
-	depends on SH_SECUREEDGE5410
-	help
-	  If you say yes here you get support for the Dallas DS1302 RTC chips.
-
 config RTC_DRV_DS1511
 config RTC_DRV_DS1511
 	tristate "Dallas DS1511"
 	tristate "Dallas DS1511"
 	depends on HAS_IOMEM
 	depends on HAS_IOMEM

+ 1 - 1
drivers/rtc/rtc-at91sam9.c

@@ -268,7 +268,7 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
 static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
 {
 {
 	struct sam9_rtc *rtc = dev_get_drvdata(dev);
 	struct sam9_rtc *rtc = dev_get_drvdata(dev);
-	u32 mr = mr = rtt_readl(rtc, MR);
+	u32 mr = rtt_readl(rtc, MR);
 
 
 	seq_printf(seq, "update_IRQ\t: %s\n",
 	seq_printf(seq, "update_IRQ\t: %s\n",
 			(mr & AT91_RTT_RTTINCIEN) ? "yes" : "no");
 			(mr & AT91_RTT_RTTINCIEN) ? "yes" : "no");

+ 1 - 1
drivers/rtc/rtc-cmos.c

@@ -401,7 +401,7 @@ static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled)
 	return 0;
 	return 0;
 }
 }
 
 
-#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
+#if IS_ENABLED(CONFIG_RTC_INTF_PROC)
 
 
 static int cmos_procfs(struct device *dev, struct seq_file *seq)
 static int cmos_procfs(struct device *dev, struct seq_file *seq)
 {
 {

+ 8 - 5
drivers/rtc/rtc-da9052.c

@@ -302,6 +302,13 @@ static int da9052_rtc_probe(struct platform_device *pdev)
 	if (ret != 0)
 	if (ret != 0)
 		rtc_err(rtc, "Failed to disable TICKS: %d\n", ret);
 		rtc_err(rtc, "Failed to disable TICKS: %d\n", ret);
 
 
+	device_init_wakeup(&pdev->dev, true);
+	rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
+				       &da9052_rtc_ops, THIS_MODULE);
+
+	if (IS_ERR(rtc->rtc))
+		return PTR_ERR(rtc->rtc);
+
 	ret = da9052_request_irq(rtc->da9052, DA9052_IRQ_ALARM, "ALM",
 	ret = da9052_request_irq(rtc->da9052, DA9052_IRQ_ALARM, "ALM",
 				da9052_rtc_irq, rtc);
 				da9052_rtc_irq, rtc);
 	if (ret != 0) {
 	if (ret != 0) {
@@ -309,11 +316,7 @@ static int da9052_rtc_probe(struct platform_device *pdev)
 		return ret;
 		return ret;
 	}
 	}
 
 
-	device_init_wakeup(&pdev->dev, true);
-
-	rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
-				       &da9052_rtc_ops, THIS_MODULE);
-	return PTR_ERR_OR_ZERO(rtc->rtc);
+	return 0;
 }
 }
 
 
 static struct platform_driver da9052_rtc_driver = {
 static struct platform_driver da9052_rtc_driver = {

+ 0 - 3
drivers/rtc/rtc-ds1216.c

@@ -11,8 +11,6 @@
 #include <linux/bcd.h>
 #include <linux/bcd.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 
 
-#define DRV_VERSION "0.2"
-
 struct ds1216_regs {
 struct ds1216_regs {
 	u8 tsec;
 	u8 tsec;
 	u8 sec;
 	u8 sec;
@@ -176,5 +174,4 @@ module_platform_driver_probe(ds1216_rtc_platform_driver, ds1216_rtc_probe);
 MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
 MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
 MODULE_DESCRIPTION("DS1216 RTC driver");
 MODULE_DESCRIPTION("DS1216 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
 MODULE_ALIAS("platform:rtc-ds1216");
 MODULE_ALIAS("platform:rtc-ds1216");

+ 0 - 3
drivers/rtc/rtc-ds1286.c

@@ -20,8 +20,6 @@
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 
 
-#define DRV_VERSION		"1.0"
-
 struct ds1286_priv {
 struct ds1286_priv {
 	struct rtc_device *rtc;
 	struct rtc_device *rtc;
 	u32 __iomem *rtcregs;
 	u32 __iomem *rtcregs;
@@ -363,5 +361,4 @@ module_platform_driver(ds1286_platform_driver);
 MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
 MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
 MODULE_DESCRIPTION("DS1286 RTC driver");
 MODULE_DESCRIPTION("DS1286 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
 MODULE_ALIAS("platform:rtc-ds1286");
 MODULE_ALIAS("platform:rtc-ds1286");

+ 156 - 192
drivers/rtc/rtc-ds1302.c

@@ -9,16 +9,16 @@
  * this archive for more details.
  * this archive for more details.
  */
  */
 
 
+#include <linux/bcd.h>
 #include <linux/init.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
-#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/of.h>
 #include <linux/rtc.h>
 #include <linux/rtc.h>
-#include <linux/io.h>
-#include <linux/bcd.h>
+#include <linux/spi/spi.h>
 
 
 #define DRV_NAME	"rtc-ds1302"
 #define DRV_NAME	"rtc-ds1302"
-#define DRV_VERSION	"0.1.1"
 
 
 #define	RTC_CMD_READ	0x81		/* Read command */
 #define	RTC_CMD_READ	0x81		/* Read command */
 #define	RTC_CMD_WRITE	0x80		/* Write command */
 #define	RTC_CMD_WRITE	0x80		/* Write command */
@@ -28,6 +28,8 @@
 
 
 #define RTC_ADDR_RAM0	0x20		/* Address of RAM0 */
 #define RTC_ADDR_RAM0	0x20		/* Address of RAM0 */
 #define RTC_ADDR_TCR	0x08		/* Address of trickle charge register */
 #define RTC_ADDR_TCR	0x08		/* Address of trickle charge register */
+#define RTC_CLCK_BURST	0x1F		/* Address of clock burst */
+#define	RTC_CLCK_LEN	0x08		/* Size of clock burst */
 #define	RTC_ADDR_CTRL	0x07		/* Address of control register */
 #define	RTC_ADDR_CTRL	0x07		/* Address of control register */
 #define	RTC_ADDR_YEAR	0x06		/* Address of year register */
 #define	RTC_ADDR_YEAR	0x06		/* Address of year register */
 #define	RTC_ADDR_DAY	0x05		/* Address of day of week register */
 #define	RTC_ADDR_DAY	0x05		/* Address of day of week register */
@@ -37,219 +39,181 @@
 #define	RTC_ADDR_MIN	0x01		/* Address of minute register */
 #define	RTC_ADDR_MIN	0x01		/* Address of minute register */
 #define	RTC_ADDR_SEC	0x00		/* Address of second register */
 #define	RTC_ADDR_SEC	0x00		/* Address of second register */
 
 
-#ifdef CONFIG_SH_SECUREEDGE5410
-#include <asm/rtc.h>
-#include <mach/secureedge5410.h>
-
-#define	RTC_RESET	0x1000
-#define	RTC_IODATA	0x0800
-#define	RTC_SCLK	0x0400
-
-#define set_dp(x)	SECUREEDGE_WRITE_IOPORT(x, 0x1c00)
-#define get_dp()	SECUREEDGE_READ_IOPORT()
-#define ds1302_set_tx()
-#define ds1302_set_rx()
-
-static inline int ds1302_hw_init(void)
+static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *time)
 {
 {
-	return 0;
+	struct spi_device	*spi = dev_get_drvdata(dev);
+	u8		buf[1 + RTC_CLCK_LEN];
+	u8		*bp = buf;
+	int		status;
+
+	/* Enable writing */
+	bp = buf;
+	*bp++ = RTC_ADDR_CTRL << 1 | RTC_CMD_WRITE;
+	*bp++ = RTC_CMD_WRITE_ENABLE;
+
+	status = spi_write_then_read(spi, buf, 2,
+			NULL, 0);
+	if (status)
+		return status;
+
+	/* Write registers starting at the first time/date address. */
+	bp = buf;
+	*bp++ = RTC_CLCK_BURST << 1 | RTC_CMD_WRITE;
+
+	*bp++ = bin2bcd(time->tm_sec);
+	*bp++ = bin2bcd(time->tm_min);
+	*bp++ = bin2bcd(time->tm_hour);
+	*bp++ = bin2bcd(time->tm_mday);
+	*bp++ = bin2bcd(time->tm_mon + 1);
+	*bp++ = time->tm_wday + 1;
+	*bp++ = bin2bcd(time->tm_year % 100);
+	*bp++ = RTC_CMD_WRITE_DISABLE;
+
+	/* use write-then-read since dma from stack is nonportable */
+	return spi_write_then_read(spi, buf, sizeof(buf),
+			NULL, 0);
 }
 }
 
 
-static inline void ds1302_reset(void)
+static int ds1302_rtc_get_time(struct device *dev, struct rtc_time *time)
 {
 {
-	set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
+	struct spi_device	*spi = dev_get_drvdata(dev);
+	u8		addr = RTC_CLCK_BURST << 1 | RTC_CMD_READ;
+	u8		buf[RTC_CLCK_LEN - 1];
+	int		status;
+
+	/* Use write-then-read to get all the date/time registers
+	 * since dma from stack is nonportable
+	 */
+	status = spi_write_then_read(spi, &addr, sizeof(addr),
+			buf, sizeof(buf));
+	if (status < 0)
+		return status;
+
+	/* Decode the registers */
+	time->tm_sec = bcd2bin(buf[RTC_ADDR_SEC]);
+	time->tm_min = bcd2bin(buf[RTC_ADDR_MIN]);
+	time->tm_hour = bcd2bin(buf[RTC_ADDR_HOUR]);
+	time->tm_wday = buf[RTC_ADDR_DAY] - 1;
+	time->tm_mday = bcd2bin(buf[RTC_ADDR_DATE]);
+	time->tm_mon = bcd2bin(buf[RTC_ADDR_MON]) - 1;
+	time->tm_year = bcd2bin(buf[RTC_ADDR_YEAR]) + 100;
+
+	/* Time may not be set */
+	return rtc_valid_tm(time);
 }
 }
 
 
-static inline void ds1302_clock(void)
-{
-	set_dp(get_dp() | RTC_SCLK);	/* clock high */
-	set_dp(get_dp() & ~RTC_SCLK);	/* clock low */
-}
-
-static inline void ds1302_start(void)
-{
-	set_dp(get_dp() | RTC_RESET);
-}
-
-static inline void ds1302_stop(void)
-{
-	set_dp(get_dp() & ~RTC_RESET);
-}
-
-static inline void ds1302_txbit(int bit)
-{
-	set_dp((get_dp() & ~RTC_IODATA) | (bit ? RTC_IODATA : 0));
-}
-
-static inline int ds1302_rxbit(void)
-{
-	return !!(get_dp() & RTC_IODATA);
-}
-
-#else
-#error "Add support for your platform"
-#endif
+static struct rtc_class_ops ds1302_rtc_ops = {
+	.read_time	= ds1302_rtc_get_time,
+	.set_time	= ds1302_rtc_set_time,
+};
 
 
-static void ds1302_sendbits(unsigned int val)
+static int ds1302_probe(struct spi_device *spi)
 {
 {
-	int i;
-
-	ds1302_set_tx();
-
-	for (i = 8; (i); i--, val >>= 1) {
-		ds1302_txbit(val & 0x1);
-		ds1302_clock();
+	struct rtc_device	*rtc;
+	u8		addr;
+	u8		buf[4];
+	u8		*bp = buf;
+	int		status;
+
+	/* Sanity check board setup data.  This may be hooked up
+	 * in 3wire mode, but we don't care.  Note that unless
+	 * there's an inverter in place, this needs SPI_CS_HIGH!
+	 */
+	if (spi->bits_per_word && (spi->bits_per_word != 8)) {
+		dev_err(&spi->dev, "bad word length\n");
+		return -EINVAL;
+	} else if (spi->max_speed_hz > 2000000) {
+		dev_err(&spi->dev, "speed is too high\n");
+		return -EINVAL;
+	} else if (spi->mode & SPI_CPHA) {
+		dev_err(&spi->dev, "bad mode\n");
+		return -EINVAL;
 	}
 	}
-}
-
-static unsigned int ds1302_recvbits(void)
-{
-	unsigned int val;
-	int i;
-
-	ds1302_set_rx();
 
 
-	for (i = 0, val = 0; (i < 8); i++) {
-		val |= (ds1302_rxbit() << i);
-		ds1302_clock();
+	addr = RTC_ADDR_CTRL << 1 | RTC_CMD_READ;
+	status = spi_write_then_read(spi, &addr, sizeof(addr), buf, 1);
+	if (status < 0) {
+		dev_err(&spi->dev, "control register read error %d\n",
+				status);
+		return status;
 	}
 	}
 
 
-	return val;
-}
-
-static unsigned int ds1302_readbyte(unsigned int addr)
-{
-	unsigned int val;
-
-	ds1302_reset();
-
-	ds1302_start();
-	ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ);
-	val = ds1302_recvbits();
-	ds1302_stop();
-
-	return val;
-}
-
-static void ds1302_writebyte(unsigned int addr, unsigned int val)
-{
-	ds1302_reset();
-
-	ds1302_start();
-	ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE);
-	ds1302_sendbits(val);
-	ds1302_stop();
-}
-
-static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
-	tm->tm_sec	= bcd2bin(ds1302_readbyte(RTC_ADDR_SEC));
-	tm->tm_min	= bcd2bin(ds1302_readbyte(RTC_ADDR_MIN));
-	tm->tm_hour	= bcd2bin(ds1302_readbyte(RTC_ADDR_HOUR));
-	tm->tm_wday	= bcd2bin(ds1302_readbyte(RTC_ADDR_DAY));
-	tm->tm_mday	= bcd2bin(ds1302_readbyte(RTC_ADDR_DATE));
-	tm->tm_mon	= bcd2bin(ds1302_readbyte(RTC_ADDR_MON)) - 1;
-	tm->tm_year	= bcd2bin(ds1302_readbyte(RTC_ADDR_YEAR));
-
-	if (tm->tm_year < 70)
-		tm->tm_year += 100;
-
-	dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
-		"mday=%d, mon=%d, year=%d, wday=%d\n",
-		__func__,
-		tm->tm_sec, tm->tm_min, tm->tm_hour,
-		tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
-
-	return rtc_valid_tm(tm);
-}
-
-static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
-	ds1302_writebyte(RTC_ADDR_CTRL, RTC_CMD_WRITE_ENABLE);
-	/* Stop RTC */
-	ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
-
-	ds1302_writebyte(RTC_ADDR_SEC, bin2bcd(tm->tm_sec));
-	ds1302_writebyte(RTC_ADDR_MIN, bin2bcd(tm->tm_min));
-	ds1302_writebyte(RTC_ADDR_HOUR, bin2bcd(tm->tm_hour));
-	ds1302_writebyte(RTC_ADDR_DAY, bin2bcd(tm->tm_wday));
-	ds1302_writebyte(RTC_ADDR_DATE, bin2bcd(tm->tm_mday));
-	ds1302_writebyte(RTC_ADDR_MON, bin2bcd(tm->tm_mon + 1));
-	ds1302_writebyte(RTC_ADDR_YEAR, bin2bcd(tm->tm_year % 100));
+	if ((buf[0] & ~RTC_CMD_WRITE_DISABLE) != 0) {
+		status = spi_write_then_read(spi, &addr, sizeof(addr), buf, 1);
+		if (status < 0) {
+			dev_err(&spi->dev, "control register read error %d\n",
+					status);
+			return status;
+		}
+
+		if ((buf[0] & ~RTC_CMD_WRITE_DISABLE) != 0) {
+			dev_err(&spi->dev, "junk in control register\n");
+			return -ENODEV;
+		}
+	}
+	if (buf[0] == 0) {
+		bp = buf;
+		*bp++ = RTC_ADDR_CTRL << 1 | RTC_CMD_WRITE;
+		*bp++ = RTC_CMD_WRITE_DISABLE;
+
+		status = spi_write_then_read(spi, buf, 2, NULL, 0);
+		if (status < 0) {
+			dev_err(&spi->dev, "control register write error %d\n",
+					status);
+			return status;
+		}
+
+		addr = RTC_ADDR_CTRL << 1 | RTC_CMD_READ;
+		status = spi_write_then_read(spi, &addr, sizeof(addr), buf, 1);
+		if (status < 0) {
+			dev_err(&spi->dev,
+					"error %d reading control register\n",
+					status);
+			return status;
+		}
+
+		if (buf[0] != RTC_CMD_WRITE_DISABLE) {
+			dev_err(&spi->dev, "failed to detect chip\n");
+			return -ENODEV;
+		}
+	}
 
 
-	/* Start RTC */
-	ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
+	spi_set_drvdata(spi, spi);
 
 
-	ds1302_writebyte(RTC_ADDR_CTRL, RTC_CMD_WRITE_DISABLE);
+	rtc = devm_rtc_device_register(&spi->dev, "ds1302",
+			&ds1302_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc)) {
+		status = PTR_ERR(rtc);
+		dev_err(&spi->dev, "error %d registering rtc\n", status);
+		return status;
+	}
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int ds1302_rtc_ioctl(struct device *dev, unsigned int cmd,
-			    unsigned long arg)
+static int ds1302_remove(struct spi_device *spi)
 {
 {
-	switch (cmd) {
-#ifdef RTC_SET_CHARGE
-	case RTC_SET_CHARGE:
-	{
-		int tcs_val;
-
-		if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int)))
-			return -EFAULT;
-
-		ds1302_writebyte(RTC_ADDR_TCR, (0xa0 | tcs_val * 0xf));
-		return 0;
-	}
-#endif
-	}
-
-	return -ENOIOCTLCMD;
+	spi_set_drvdata(spi, NULL);
+	return 0;
 }
 }
 
 
-static struct rtc_class_ops ds1302_rtc_ops = {
-	.read_time	= ds1302_rtc_read_time,
-	.set_time	= ds1302_rtc_set_time,
-	.ioctl		= ds1302_rtc_ioctl,
+#ifdef CONFIG_OF
+static const struct of_device_id ds1302_dt_ids[] = {
+	{ .compatible = "maxim,ds1302", },
+	{ /* sentinel */ }
 };
 };
+MODULE_DEVICE_TABLE(of, ds1302_dt_ids);
+#endif
 
 
-static int __init ds1302_rtc_probe(struct platform_device *pdev)
-{
-	struct rtc_device *rtc;
-
-	if (ds1302_hw_init()) {
-		dev_err(&pdev->dev, "Failed to init communication channel");
-		return -EINVAL;
-	}
-
-	/* Reset */
-	ds1302_reset();
-
-	/* Write a magic value to the DS1302 RAM, and see if it sticks. */
-	ds1302_writebyte(RTC_ADDR_RAM0, 0x42);
-	if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) {
-		dev_err(&pdev->dev, "Failed to probe");
-		return -ENODEV;
-	}
-
-	rtc = devm_rtc_device_register(&pdev->dev, "ds1302",
-					   &ds1302_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc))
-		return PTR_ERR(rtc);
-
-	platform_set_drvdata(pdev, rtc);
-
-	return 0;
-}
-
-static struct platform_driver ds1302_platform_driver = {
-	.driver		= {
-		.name	= DRV_NAME,
-	},
+static struct spi_driver ds1302_driver = {
+	.driver.name	= "rtc-ds1302",
+	.driver.of_match_table = of_match_ptr(ds1302_dt_ids),
+	.probe		= ds1302_probe,
+	.remove		= ds1302_remove,
 };
 };
 
 
-module_platform_driver_probe(ds1302_platform_driver, ds1302_rtc_probe);
+module_spi_driver(ds1302_driver);
 
 
 MODULE_DESCRIPTION("Dallas DS1302 RTC driver");
 MODULE_DESCRIPTION("Dallas DS1302 RTC driver");
-MODULE_VERSION(DRV_VERSION);
 MODULE_AUTHOR("Paul Mundt, David McCullough");
 MODULE_AUTHOR("Paul Mundt, David McCullough");
 MODULE_LICENSE("GPL v2");
 MODULE_LICENSE("GPL v2");

+ 14 - 9
drivers/rtc/rtc-ds1307.c

@@ -275,9 +275,13 @@ static s32 ds1307_native_smbus_write_block_data(const struct i2c_client *client,
 {
 {
 	u8 suboffset = 0;
 	u8 suboffset = 0;
 
 
-	if (length <= I2C_SMBUS_BLOCK_MAX)
-		return i2c_smbus_write_i2c_block_data(client,
+	if (length <= I2C_SMBUS_BLOCK_MAX) {
+		s32 retval = i2c_smbus_write_i2c_block_data(client,
 					command, length, values);
 					command, length, values);
+		if (retval < 0)
+			return retval;
+		return length;
+	}
 
 
 	while (suboffset < length) {
 	while (suboffset < length) {
 		s32 retval = i2c_smbus_write_i2c_block_data(client,
 		s32 retval = i2c_smbus_write_i2c_block_data(client,
@@ -538,12 +542,8 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 	buf[5] = 0;
 	buf[5] = 0;
 	buf[6] = 0;
 	buf[6] = 0;
 
 
-	/* optionally enable ALARM1 */
+	/* disable alarms */
 	buf[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE);
 	buf[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE);
-	if (t->enabled) {
-		dev_dbg(dev, "alarm IRQ armed\n");
-		buf[7] |= DS1337_BIT_A1IE;	/* only ALARM1 is used */
-	}
 	buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
 	buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
 
 
 	ret = ds1307->write_block_data(client,
 	ret = ds1307->write_block_data(client,
@@ -553,6 +553,13 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 		return ret;
 		return ret;
 	}
 	}
 
 
+	/* optionally enable ALARM1 */
+	if (t->enabled) {
+		dev_dbg(dev, "alarm IRQ armed\n");
+		buf[7] |= DS1337_BIT_A1IE;	/* only ALARM1 is used */
+		i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, buf[7]);
+	}
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1144,12 +1151,10 @@ static struct clk_init_data ds3231_clks_init[] = {
 	[DS3231_CLK_SQW] = {
 	[DS3231_CLK_SQW] = {
 		.name = "ds3231_clk_sqw",
 		.name = "ds3231_clk_sqw",
 		.ops = &ds3231_clk_sqw_ops,
 		.ops = &ds3231_clk_sqw_ops,
-		.flags = CLK_IS_ROOT,
 	},
 	},
 	[DS3231_CLK_32KHZ] = {
 	[DS3231_CLK_32KHZ] = {
 		.name = "ds3231_clk_32khz",
 		.name = "ds3231_clk_32khz",
 		.ops = &ds3231_clk_32khz_ops,
 		.ops = &ds3231_clk_32khz_ops,
-		.flags = CLK_IS_ROOT,
 	},
 	},
 };
 };
 
 

+ 0 - 2
drivers/rtc/rtc-ds1343.c

@@ -24,7 +24,6 @@
 #include <linux/pm_wakeirq.h>
 #include <linux/pm_wakeirq.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 
 
-#define DS1343_DRV_VERSION	"01.00"
 #define DALLAS_MAXIM_DS1343	0
 #define DALLAS_MAXIM_DS1343	0
 #define DALLAS_MAXIM_DS1344	1
 #define DALLAS_MAXIM_DS1344	1
 
 
@@ -747,4 +746,3 @@ MODULE_DESCRIPTION("DS1343 RTC SPI Driver");
 MODULE_AUTHOR("Raghavendra Chandra Ganiga <ravi23ganiga@gmail.com>,"
 MODULE_AUTHOR("Raghavendra Chandra Ganiga <ravi23ganiga@gmail.com>,"
 		"Ankur Srivastava <sankurece@gmail.com>");
 		"Ankur Srivastava <sankurece@gmail.com>");
 MODULE_LICENSE("GPL v2");
 MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DS1343_DRV_VERSION);

+ 0 - 3
drivers/rtc/rtc-ds1511.c

@@ -25,8 +25,6 @@
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/module.h>
 
 
-#define DRV_VERSION "0.6"
-
 enum ds1511reg {
 enum ds1511reg {
 	DS1511_SEC = 0x0,
 	DS1511_SEC = 0x0,
 	DS1511_MIN = 0x1,
 	DS1511_MIN = 0x1,
@@ -537,4 +535,3 @@ module_platform_driver(ds1511_rtc_driver);
 MODULE_AUTHOR("Andrew Sharp <andy.sharp@lsi.com>");
 MODULE_AUTHOR("Andrew Sharp <andy.sharp@lsi.com>");
 MODULE_DESCRIPTION("Dallas DS1511 RTC driver");
 MODULE_DESCRIPTION("Dallas DS1511 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);

+ 0 - 3
drivers/rtc/rtc-ds1553.c

@@ -20,8 +20,6 @@
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/module.h>
 
 
-#define DRV_VERSION "0.3"
-
 #define RTC_REG_SIZE		0x2000
 #define RTC_REG_SIZE		0x2000
 #define RTC_OFFSET		0x1ff0
 #define RTC_OFFSET		0x1ff0
 
 
@@ -359,4 +357,3 @@ module_platform_driver(ds1553_rtc_driver);
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_DESCRIPTION("Dallas DS1553 RTC driver");
 MODULE_DESCRIPTION("Dallas DS1553 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);

+ 0 - 5
drivers/rtc/rtc-ds1672.c

@@ -13,8 +13,6 @@
 #include <linux/rtc.h>
 #include <linux/rtc.h>
 #include <linux/module.h>
 #include <linux/module.h>
 
 
-#define DRV_VERSION "0.4"
-
 /* Registers */
 /* Registers */
 
 
 #define DS1672_REG_CNT_BASE	0
 #define DS1672_REG_CNT_BASE	0
@@ -165,8 +163,6 @@ static int ds1672_probe(struct i2c_client *client,
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
 		return -ENODEV;
 		return -ENODEV;
 
 
-	dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
-
 	rtc = devm_rtc_device_register(&client->dev, ds1672_driver.driver.name,
 	rtc = devm_rtc_device_register(&client->dev, ds1672_driver.driver.name,
 				  &ds1672_rtc_ops, THIS_MODULE);
 				  &ds1672_rtc_ops, THIS_MODULE);
 
 
@@ -213,4 +209,3 @@ module_i2c_driver(ds1672_driver);
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver");
 MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);

+ 1 - 3
drivers/rtc/rtc-ds1685.c

@@ -32,8 +32,6 @@
 #include <linux/proc_fs.h>
 #include <linux/proc_fs.h>
 #endif
 #endif
 
 
-#define DRV_VERSION	"0.42.0"
-
 
 
 /* ----------------------------------------------------------------------- */
 /* ----------------------------------------------------------------------- */
 /* Standard read/write functions if platform does not provide overrides */
 /* Standard read/write functions if platform does not provide overrides */
@@ -2213,6 +2211,7 @@ ds1685_rtc_poweroff(struct platform_device *pdev)
 			   (ctrl4a | RTC_CTRL_4A_PAB));
 			   (ctrl4a | RTC_CTRL_4A_PAB));
 
 
 		/* Spin ... we do not switch back to bank0. */
 		/* Spin ... we do not switch back to bank0. */
+		while(1);
 		unreachable();
 		unreachable();
 	}
 	}
 }
 }
@@ -2224,5 +2223,4 @@ MODULE_AUTHOR("Joshua Kinard <kumba@gentoo.org>");
 MODULE_AUTHOR("Matthias Fuchs <matthias.fuchs@esd-electronics.com>");
 MODULE_AUTHOR("Matthias Fuchs <matthias.fuchs@esd-electronics.com>");
 MODULE_DESCRIPTION("Dallas/Maxim DS1685/DS1687-series RTC driver");
 MODULE_DESCRIPTION("Dallas/Maxim DS1685/DS1687-series RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
 MODULE_ALIAS("platform:rtc-ds1685");
 MODULE_ALIAS("platform:rtc-ds1685");

+ 0 - 3
drivers/rtc/rtc-ds1742.c

@@ -24,8 +24,6 @@
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/module.h>
 
 
-#define DRV_VERSION "0.4"
-
 #define RTC_SIZE		8
 #define RTC_SIZE		8
 
 
 #define RTC_CONTROL		0
 #define RTC_CONTROL		0
@@ -239,5 +237,4 @@ module_platform_driver(ds1742_rtc_driver);
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_DESCRIPTION("Dallas DS1742 RTC driver");
 MODULE_DESCRIPTION("Dallas DS1742 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
 MODULE_ALIAS("platform:rtc-ds1742");
 MODULE_ALIAS("platform:rtc-ds1742");

+ 6 - 3
drivers/rtc/rtc-ds3232.c

@@ -369,6 +369,11 @@ static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
+	ds3232->rtc = devm_rtc_device_register(dev, name, &ds3232_rtc_ops,
+						THIS_MODULE);
+	if (IS_ERR(ds3232->rtc))
+		return PTR_ERR(ds3232->rtc);
+
 	if (ds3232->irq > 0) {
 	if (ds3232->irq > 0) {
 		ret = devm_request_threaded_irq(dev, ds3232->irq, NULL,
 		ret = devm_request_threaded_irq(dev, ds3232->irq, NULL,
 						ds3232_irq,
 						ds3232_irq,
@@ -380,10 +385,8 @@ static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
 		} else
 		} else
 			device_init_wakeup(dev, 1);
 			device_init_wakeup(dev, 1);
 	}
 	}
-	ds3232->rtc = devm_rtc_device_register(dev, name, &ds3232_rtc_ops,
-						THIS_MODULE);
 
 
-	return PTR_ERR_OR_ZERO(ds3232->rtc);
+	return 0;
 }
 }
 
 
 #ifdef CONFIG_PM_SLEEP
 #ifdef CONFIG_PM_SLEEP

+ 0 - 3
drivers/rtc/rtc-ep93xx.c

@@ -28,8 +28,6 @@
 #define  EP93XX_RTC_SWCOMP_INT_MASK	 0x0000ffff
 #define  EP93XX_RTC_SWCOMP_INT_MASK	 0x0000ffff
 #define  EP93XX_RTC_SWCOMP_INT_SHIFT	 0
 #define  EP93XX_RTC_SWCOMP_INT_SHIFT	 0
 
 
-#define DRV_VERSION "0.3"
-
 /*
 /*
  * struct device dev.platform_data is used to store our private data
  * struct device dev.platform_data is used to store our private data
  * because struct rtc_device does not have a variable to hold it.
  * because struct rtc_device does not have a variable to hold it.
@@ -184,5 +182,4 @@ module_platform_driver(ep93xx_rtc_driver);
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_DESCRIPTION("EP93XX RTC driver");
 MODULE_DESCRIPTION("EP93XX RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
 MODULE_ALIAS("platform:ep93xx-rtc");
 MODULE_ALIAS("platform:ep93xx-rtc");

+ 0 - 1
drivers/rtc/rtc-gemini.c

@@ -28,7 +28,6 @@
 #include <linux/module.h>
 #include <linux/module.h>
 
 
 #define DRV_NAME        "rtc-gemini"
 #define DRV_NAME        "rtc-gemini"
-#define DRV_VERSION     "0.2"
 
 
 MODULE_AUTHOR("Hans Ulli Kroll <ulli.kroll@googlemail.com>");
 MODULE_AUTHOR("Hans Ulli Kroll <ulli.kroll@googlemail.com>");
 MODULE_DESCRIPTION("RTC driver for Gemini SoC");
 MODULE_DESCRIPTION("RTC driver for Gemini SoC");

+ 1 - 1
drivers/rtc/rtc-hym8563.c

@@ -413,7 +413,7 @@ static struct clk *hym8563_clkout_register_clk(struct hym8563 *hym8563)
 
 
 	init.name = "hym8563-clkout";
 	init.name = "hym8563-clkout";
 	init.ops = &hym8563_clkout_ops;
 	init.ops = &hym8563_clkout_ops;
-	init.flags = CLK_IS_ROOT;
+	init.flags = 0;
 	init.parent_names = NULL;
 	init.parent_names = NULL;
 	init.num_parents = 0;
 	init.num_parents = 0;
 	hym8563->clkout_hw.init = &init;
 	hym8563->clkout_hw.init = &init;

+ 0 - 5
drivers/rtc/rtc-isl12022.c

@@ -20,8 +20,6 @@
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
 
 
-#define DRV_VERSION "0.1"
-
 /* ISL register offsets */
 /* ISL register offsets */
 #define ISL12022_REG_SC		0x00
 #define ISL12022_REG_SC		0x00
 #define ISL12022_REG_MN		0x01
 #define ISL12022_REG_MN		0x01
@@ -258,8 +256,6 @@ static int isl12022_probe(struct i2c_client *client,
 	if (!isl12022)
 	if (!isl12022)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	dev_dbg(&client->dev, "chip found, driver version " DRV_VERSION "\n");
-
 	i2c_set_clientdata(client, isl12022);
 	i2c_set_clientdata(client, isl12022);
 
 
 	isl12022->rtc = devm_rtc_device_register(&client->dev,
 	isl12022->rtc = devm_rtc_device_register(&client->dev,
@@ -299,4 +295,3 @@ module_i2c_driver(isl12022_driver);
 MODULE_AUTHOR("roman.fietze@telemotive.de");
 MODULE_AUTHOR("roman.fietze@telemotive.de");
 MODULE_DESCRIPTION("ISL 12022 RTC driver");
 MODULE_DESCRIPTION("ISL 12022 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);

+ 0 - 6
drivers/rtc/rtc-isl1208.c

@@ -15,8 +15,6 @@
 #include <linux/bcd.h>
 #include <linux/bcd.h>
 #include <linux/rtc.h>
 #include <linux/rtc.h>
 
 
-#define DRV_VERSION "0.3"
-
 /* Register map */
 /* Register map */
 /* rtc section */
 /* rtc section */
 #define ISL1208_REG_SC  0x00
 #define ISL1208_REG_SC  0x00
@@ -632,9 +630,6 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	if (isl1208_i2c_validate_client(client) < 0)
 	if (isl1208_i2c_validate_client(client) < 0)
 		return -ENODEV;
 		return -ENODEV;
 
 
-	dev_info(&client->dev,
-		 "chip found, driver version " DRV_VERSION "\n");
-
 	if (client->irq > 0) {
 	if (client->irq > 0) {
 		rc = devm_request_threaded_irq(&client->dev, client->irq, NULL,
 		rc = devm_request_threaded_irq(&client->dev, client->irq, NULL,
 					       isl1208_rtc_interrupt,
 					       isl1208_rtc_interrupt,
@@ -706,4 +701,3 @@ module_i2c_driver(isl1208_driver);
 MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>");
 MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>");
 MODULE_DESCRIPTION("Intersil ISL1208 RTC driver");
 MODULE_DESCRIPTION("Intersil ISL1208 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);

+ 293 - 154
drivers/rtc/rtc-m41t80.c

@@ -32,41 +32,42 @@
 #include <linux/watchdog.h>
 #include <linux/watchdog.h>
 #endif
 #endif
 
 
-#define M41T80_REG_SSEC	0
-#define M41T80_REG_SEC	1
-#define M41T80_REG_MIN	2
-#define M41T80_REG_HOUR	3
-#define M41T80_REG_WDAY	4
-#define M41T80_REG_DAY	5
-#define M41T80_REG_MON	6
-#define M41T80_REG_YEAR	7
-#define M41T80_REG_ALARM_MON	0xa
-#define M41T80_REG_ALARM_DAY	0xb
-#define M41T80_REG_ALARM_HOUR	0xc
-#define M41T80_REG_ALARM_MIN	0xd
-#define M41T80_REG_ALARM_SEC	0xe
-#define M41T80_REG_FLAGS	0xf
-#define M41T80_REG_SQW	0x13
+#define M41T80_REG_SSEC		0x00
+#define M41T80_REG_SEC		0x01
+#define M41T80_REG_MIN		0x02
+#define M41T80_REG_HOUR		0x03
+#define M41T80_REG_WDAY		0x04
+#define M41T80_REG_DAY		0x05
+#define M41T80_REG_MON		0x06
+#define M41T80_REG_YEAR		0x07
+#define M41T80_REG_ALARM_MON	0x0a
+#define M41T80_REG_ALARM_DAY	0x0b
+#define M41T80_REG_ALARM_HOUR	0x0c
+#define M41T80_REG_ALARM_MIN	0x0d
+#define M41T80_REG_ALARM_SEC	0x0e
+#define M41T80_REG_FLAGS	0x0f
+#define M41T80_REG_SQW		0x13
 
 
 #define M41T80_DATETIME_REG_SIZE	(M41T80_REG_YEAR + 1)
 #define M41T80_DATETIME_REG_SIZE	(M41T80_REG_YEAR + 1)
 #define M41T80_ALARM_REG_SIZE	\
 #define M41T80_ALARM_REG_SIZE	\
 	(M41T80_REG_ALARM_SEC + 1 - M41T80_REG_ALARM_MON)
 	(M41T80_REG_ALARM_SEC + 1 - M41T80_REG_ALARM_MON)
 
 
-#define M41T80_SEC_ST		(1 << 7)	/* ST: Stop Bit */
-#define M41T80_ALMON_AFE	(1 << 7)	/* AFE: AF Enable Bit */
-#define M41T80_ALMON_SQWE	(1 << 6)	/* SQWE: SQW Enable Bit */
-#define M41T80_ALHOUR_HT	(1 << 6)	/* HT: Halt Update Bit */
-#define M41T80_FLAGS_AF		(1 << 6)	/* AF: Alarm Flag Bit */
-#define M41T80_FLAGS_BATT_LOW	(1 << 4)	/* BL: Battery Low Bit */
-#define M41T80_WATCHDOG_RB2	(1 << 7)	/* RB: Watchdog resolution */
-#define M41T80_WATCHDOG_RB1	(1 << 1)	/* RB: Watchdog resolution */
-#define M41T80_WATCHDOG_RB0	(1 << 0)	/* RB: Watchdog resolution */
-
-#define M41T80_FEATURE_HT	(1 << 0)	/* Halt feature */
-#define M41T80_FEATURE_BL	(1 << 1)	/* Battery low indicator */
-#define M41T80_FEATURE_SQ	(1 << 2)	/* Squarewave feature */
-#define M41T80_FEATURE_WD	(1 << 3)	/* Extra watchdog resolution */
-#define M41T80_FEATURE_SQ_ALT	(1 << 4)	/* RSx bits are in reg 4 */
+#define M41T80_SEC_ST		BIT(7)	/* ST: Stop Bit */
+#define M41T80_ALMON_AFE	BIT(7)	/* AFE: AF Enable Bit */
+#define M41T80_ALMON_SQWE	BIT(6)	/* SQWE: SQW Enable Bit */
+#define M41T80_ALHOUR_HT	BIT(6)	/* HT: Halt Update Bit */
+#define M41T80_FLAGS_OF		BIT(2)	/* OF: Oscillator Failure Bit */
+#define M41T80_FLAGS_AF		BIT(6)	/* AF: Alarm Flag Bit */
+#define M41T80_FLAGS_BATT_LOW	BIT(4)	/* BL: Battery Low Bit */
+#define M41T80_WATCHDOG_RB2	BIT(7)	/* RB: Watchdog resolution */
+#define M41T80_WATCHDOG_RB1	BIT(1)	/* RB: Watchdog resolution */
+#define M41T80_WATCHDOG_RB0	BIT(0)	/* RB: Watchdog resolution */
+
+#define M41T80_FEATURE_HT	BIT(0)	/* Halt feature */
+#define M41T80_FEATURE_BL	BIT(1)	/* Battery low indicator */
+#define M41T80_FEATURE_SQ	BIT(2)	/* Squarewave feature */
+#define M41T80_FEATURE_WD	BIT(3)	/* Extra watchdog resolution */
+#define M41T80_FEATURE_SQ_ALT	BIT(4)	/* RSx bits are in reg 4 */
 
 
 static DEFINE_MUTEX(m41t80_rtc_mutex);
 static DEFINE_MUTEX(m41t80_rtc_mutex);
 static const struct i2c_device_id m41t80_id[] = {
 static const struct i2c_device_id m41t80_id[] = {
@@ -90,27 +91,65 @@ struct m41t80_data {
 	struct rtc_device *rtc;
 	struct rtc_device *rtc;
 };
 };
 
 
+static irqreturn_t m41t80_handle_irq(int irq, void *dev_id)
+{
+	struct i2c_client *client = dev_id;
+	struct m41t80_data *m41t80 = i2c_get_clientdata(client);
+	struct mutex *lock = &m41t80->rtc->ops_lock;
+	unsigned long events = 0;
+	int flags, flags_afe;
+
+	mutex_lock(lock);
+
+	flags_afe = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
+	if (flags_afe < 0) {
+		mutex_unlock(lock);
+		return IRQ_NONE;
+	}
+
+	flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
+	if (flags <= 0) {
+		mutex_unlock(lock);
+		return IRQ_NONE;
+	}
+
+	if (flags & M41T80_FLAGS_AF) {
+		flags &= ~M41T80_FLAGS_AF;
+		flags_afe &= ~M41T80_ALMON_AFE;
+		events |= RTC_AF;
+	}
+
+	if (events) {
+		rtc_update_irq(m41t80->rtc, 1, events);
+		i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS, flags);
+		i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
+					  flags_afe);
+	}
+
+	mutex_unlock(lock);
+
+	return IRQ_HANDLED;
+}
+
 static int m41t80_get_datetime(struct i2c_client *client,
 static int m41t80_get_datetime(struct i2c_client *client,
 			       struct rtc_time *tm)
 			       struct rtc_time *tm)
 {
 {
-	u8 buf[M41T80_DATETIME_REG_SIZE], dt_addr[1] = { M41T80_REG_SEC };
-	struct i2c_msg msgs[] = {
-		{
-			.addr	= client->addr,
-			.flags	= 0,
-			.len	= 1,
-			.buf	= dt_addr,
-		},
-		{
-			.addr	= client->addr,
-			.flags	= I2C_M_RD,
-			.len	= M41T80_DATETIME_REG_SIZE - M41T80_REG_SEC,
-			.buf	= buf + M41T80_REG_SEC,
-		},
-	};
+	unsigned char buf[8];
+	int err, flags;
+
+	flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
+	if (flags < 0)
+		return flags;
 
 
-	if (i2c_transfer(client->adapter, msgs, 2) < 0) {
-		dev_err(&client->dev, "read error\n");
+	if (flags & M41T80_FLAGS_OF) {
+		dev_err(&client->dev, "Oscillator failure, data is invalid.\n");
+		return -EINVAL;
+	}
+
+	err = i2c_smbus_read_i2c_block_data(client, M41T80_REG_SSEC,
+					    sizeof(buf), buf);
+	if (err < 0) {
+		dev_err(&client->dev, "Unable to read date\n");
 		return -EIO;
 		return -EIO;
 	}
 	}
 
 
@@ -129,70 +168,42 @@ static int m41t80_get_datetime(struct i2c_client *client,
 /* Sets the given date and time to the real time clock. */
 /* Sets the given date and time to the real time clock. */
 static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm)
 static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm)
 {
 {
-	u8 wbuf[1 + M41T80_DATETIME_REG_SIZE];
-	u8 *buf = &wbuf[1];
-	u8 dt_addr[1] = { M41T80_REG_SEC };
-	struct i2c_msg msgs_in[] = {
-		{
-			.addr	= client->addr,
-			.flags	= 0,
-			.len	= 1,
-			.buf	= dt_addr,
-		},
-		{
-			.addr	= client->addr,
-			.flags	= I2C_M_RD,
-			.len	= M41T80_DATETIME_REG_SIZE - M41T80_REG_SEC,
-			.buf	= buf + M41T80_REG_SEC,
-		},
-	};
-	struct i2c_msg msgs[] = {
-		{
-			.addr	= client->addr,
-			.flags	= 0,
-			.len	= 1 + M41T80_DATETIME_REG_SIZE,
-			.buf	= wbuf,
-		 },
-	};
+	unsigned char buf[8];
+	int err, flags;
 
 
-	/* Read current reg values into buf[1..7] */
-	if (i2c_transfer(client->adapter, msgs_in, 2) < 0) {
-		dev_err(&client->dev, "read error\n");
-		return -EIO;
-	}
+	if (tm->tm_year < 100 || tm->tm_year > 199)
+		return -EINVAL;
 
 
-	wbuf[0] = 0; /* offset into rtc's regs */
-	/* Merge time-data and register flags into buf[0..7] */
 	buf[M41T80_REG_SSEC] = 0;
 	buf[M41T80_REG_SSEC] = 0;
-	buf[M41T80_REG_SEC] =
-		bin2bcd(tm->tm_sec) | (buf[M41T80_REG_SEC] & ~0x7f);
-	buf[M41T80_REG_MIN] =
-		bin2bcd(tm->tm_min) | (buf[M41T80_REG_MIN] & ~0x7f);
-	buf[M41T80_REG_HOUR] =
-		bin2bcd(tm->tm_hour) | (buf[M41T80_REG_HOUR] & ~0x3f);
-	buf[M41T80_REG_WDAY] =
-		(tm->tm_wday & 0x07) | (buf[M41T80_REG_WDAY] & ~0x07);
-	buf[M41T80_REG_DAY] =
-		bin2bcd(tm->tm_mday) | (buf[M41T80_REG_DAY] & ~0x3f);
-	buf[M41T80_REG_MON] =
-		bin2bcd(tm->tm_mon + 1) | (buf[M41T80_REG_MON] & ~0x1f);
-
-	/* assume 20YY not 19YY */
-	if (tm->tm_year < 100 || tm->tm_year > 199) {
-		dev_err(&client->dev, "Year must be between 2000 and 2099. It's %d.\n",
-			tm->tm_year + 1900);
-		return -EINVAL;
+	buf[M41T80_REG_SEC] = bin2bcd(tm->tm_sec);
+	buf[M41T80_REG_MIN] = bin2bcd(tm->tm_min);
+	buf[M41T80_REG_HOUR] = bin2bcd(tm->tm_hour);
+	buf[M41T80_REG_DAY] = bin2bcd(tm->tm_mday);
+	buf[M41T80_REG_MON] = bin2bcd(tm->tm_mon + 1);
+	buf[M41T80_REG_YEAR] = bin2bcd(tm->tm_year - 100);
+	buf[M41T80_REG_WDAY] = tm->tm_wday;
+
+	err = i2c_smbus_write_i2c_block_data(client, M41T80_REG_SSEC,
+					     sizeof(buf), buf);
+	if (err < 0) {
+		dev_err(&client->dev, "Unable to write to date registers\n");
+		return err;
 	}
 	}
-	buf[M41T80_REG_YEAR] = bin2bcd(tm->tm_year % 100);
 
 
-	if (i2c_transfer(client->adapter, msgs, 1) != 1) {
-		dev_err(&client->dev, "write error\n");
+	/* Clear the OF bit of Flags Register */
+	flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
+	if (flags < 0)
+		return flags;
+
+	if (i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS,
+				      flags & ~M41T80_FLAGS_OF)) {
+		dev_err(&client->dev, "Unable to write flags register\n");
 		return -EIO;
 		return -EIO;
 	}
 	}
-	return 0;
+
+	return err;
 }
 }
 
 
-#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
 static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq)
 static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq)
 {
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct i2c_client *client = to_i2c_client(dev);
@@ -206,9 +217,6 @@ static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq)
 	}
 	}
 	return 0;
 	return 0;
 }
 }
-#else
-#define m41t80_rtc_proc NULL
-#endif
 
 
 static int m41t80_rtc_read_time(struct device *dev, struct rtc_time *tm)
 static int m41t80_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
 {
@@ -220,19 +228,117 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	return m41t80_set_datetime(to_i2c_client(dev), tm);
 	return m41t80_set_datetime(to_i2c_client(dev), tm);
 }
 }
 
 
-/*
- * XXX - m41t80 alarm functionality is reported broken.
- * until it is fixed, don't register alarm functions.
- */
+static int m41t80_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	int flags, retval;
+
+	flags = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
+	if (flags < 0)
+		return flags;
+
+	if (enabled)
+		flags |= M41T80_ALMON_AFE;
+	else
+		flags &= ~M41T80_ALMON_AFE;
+
+	retval = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, flags);
+	if (retval < 0) {
+		dev_info(dev, "Unable to enable alarm IRQ %d\n", retval);
+		return retval;
+	}
+	return 0;
+}
+
+static int m41t80_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	u8 alarmvals[5];
+	int ret, err;
+
+	alarmvals[0] = bin2bcd(alrm->time.tm_mon + 1);
+	alarmvals[1] = bin2bcd(alrm->time.tm_mday);
+	alarmvals[2] = bin2bcd(alrm->time.tm_hour);
+	alarmvals[3] = bin2bcd(alrm->time.tm_min);
+	alarmvals[4] = bin2bcd(alrm->time.tm_sec);
+
+	/* Clear AF and AFE flags */
+	ret = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
+	if (ret < 0)
+		return ret;
+	err = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
+					ret & ~(M41T80_ALMON_AFE));
+	if (err < 0) {
+		dev_err(dev, "Unable to clear AFE bit\n");
+		return err;
+	}
+
+	ret = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
+	if (ret < 0)
+		return ret;
+
+	err = i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS,
+					ret & ~(M41T80_FLAGS_AF));
+	if (err < 0) {
+		dev_err(dev, "Unable to clear AF bit\n");
+		return err;
+	}
+
+	/* Write the alarm */
+	err = i2c_smbus_write_i2c_block_data(client, M41T80_REG_ALARM_MON,
+					     5, alarmvals);
+	if (err)
+		return err;
+
+	/* Enable the alarm interrupt */
+	if (alrm->enabled) {
+		alarmvals[0] |= M41T80_ALMON_AFE;
+		err = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
+						alarmvals[0]);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static int m41t80_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	u8 alarmvals[5];
+	int flags, ret;
+
+	ret = i2c_smbus_read_i2c_block_data(client, M41T80_REG_ALARM_MON,
+					    5, alarmvals);
+	if (ret != 5)
+		return ret < 0 ? ret : -EIO;
+
+	flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
+	if (flags < 0)
+		return flags;
+
+	alrm->time.tm_sec  = bcd2bin(alarmvals[4] & 0x7f);
+	alrm->time.tm_min  = bcd2bin(alarmvals[3] & 0x7f);
+	alrm->time.tm_hour = bcd2bin(alarmvals[2] & 0x3f);
+	alrm->time.tm_wday = -1;
+	alrm->time.tm_mday = bcd2bin(alarmvals[1] & 0x3f);
+	alrm->time.tm_mon  = bcd2bin(alarmvals[0] & 0x3f);
+	alrm->time.tm_year = -1;
+
+	alrm->enabled = !!(alarmvals[0] & M41T80_ALMON_AFE);
+	alrm->pending = (flags & M41T80_FLAGS_AF) && alrm->enabled;
+
+	return 0;
+}
+
 static struct rtc_class_ops m41t80_rtc_ops = {
 static struct rtc_class_ops m41t80_rtc_ops = {
 	.read_time = m41t80_rtc_read_time,
 	.read_time = m41t80_rtc_read_time,
 	.set_time = m41t80_rtc_set_time,
 	.set_time = m41t80_rtc_set_time,
 	.proc = m41t80_rtc_proc,
 	.proc = m41t80_rtc_proc,
 };
 };
 
 
-#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
-static ssize_t m41t80_sysfs_show_flags(struct device *dev,
-				struct device_attribute *attr, char *buf)
+static ssize_t flags_show(struct device *dev,
+			  struct device_attribute *attr, char *buf)
 {
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct i2c_client *client = to_i2c_client(dev);
 	int val;
 	int val;
@@ -242,10 +348,10 @@ static ssize_t m41t80_sysfs_show_flags(struct device *dev,
 		return val;
 		return val;
 	return sprintf(buf, "%#x\n", val);
 	return sprintf(buf, "%#x\n", val);
 }
 }
-static DEVICE_ATTR(flags, S_IRUGO, m41t80_sysfs_show_flags, NULL);
+static DEVICE_ATTR_RO(flags);
 
 
-static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev,
-				struct device_attribute *attr, char *buf)
+static ssize_t sqwfreq_show(struct device *dev,
+			    struct device_attribute *attr, char *buf)
 {
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct i2c_client *client = to_i2c_client(dev);
 	struct m41t80_data *clientdata = i2c_get_clientdata(client);
 	struct m41t80_data *clientdata = i2c_get_clientdata(client);
@@ -272,14 +378,19 @@ static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev,
 	}
 	}
 	return sprintf(buf, "%d\n", val);
 	return sprintf(buf, "%d\n", val);
 }
 }
-static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
-				struct device_attribute *attr,
-				const char *buf, size_t count)
+
+static ssize_t sqwfreq_store(struct device *dev,
+			     struct device_attribute *attr,
+			     const char *buf, size_t count)
 {
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct i2c_client *client = to_i2c_client(dev);
 	struct m41t80_data *clientdata = i2c_get_clientdata(client);
 	struct m41t80_data *clientdata = i2c_get_clientdata(client);
 	int almon, sqw, reg_sqw, rc;
 	int almon, sqw, reg_sqw, rc;
-	int val = simple_strtoul(buf, NULL, 0);
+	unsigned long val;
+
+	rc = kstrtoul(buf, 0, &val);
+	if (rc < 0)
+		return rc;
 
 
 	if (!(clientdata->features & M41T80_FEATURE_SQ))
 	if (!(clientdata->features & M41T80_FEATURE_SQ))
 		return -EINVAL;
 		return -EINVAL;
@@ -308,7 +419,7 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
 	sqw = (sqw & 0x0f) | (val << 4);
 	sqw = (sqw & 0x0f) | (val << 4);
 
 
 	rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
 	rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
-				      almon & ~M41T80_ALMON_SQWE);
+				       almon & ~M41T80_ALMON_SQWE);
 	if (rc < 0)
 	if (rc < 0)
 		return rc;
 		return rc;
 
 
@@ -318,35 +429,24 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
 			return rc;
 			return rc;
 
 
 		rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
 		rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
-					     almon | M41T80_ALMON_SQWE);
-		if (rc <0)
+					       almon | M41T80_ALMON_SQWE);
+		if (rc < 0)
 			return rc;
 			return rc;
 	}
 	}
 	return count;
 	return count;
 }
 }
-static DEVICE_ATTR(sqwfreq, S_IRUGO | S_IWUSR,
-		   m41t80_sysfs_show_sqwfreq, m41t80_sysfs_set_sqwfreq);
+static DEVICE_ATTR_RW(sqwfreq);
 
 
 static struct attribute *attrs[] = {
 static struct attribute *attrs[] = {
 	&dev_attr_flags.attr,
 	&dev_attr_flags.attr,
 	&dev_attr_sqwfreq.attr,
 	&dev_attr_sqwfreq.attr,
 	NULL,
 	NULL,
 };
 };
+
 static struct attribute_group attr_group = {
 static struct attribute_group attr_group = {
 	.attrs = attrs,
 	.attrs = attrs,
 };
 };
 
 
-static int m41t80_sysfs_register(struct device *dev)
-{
-	return sysfs_create_group(&dev->kobj, &attr_group);
-}
-#else
-static int m41t80_sysfs_register(struct device *dev)
-{
-	return 0;
-}
-#endif
-
 #ifdef CONFIG_RTC_DRV_M41T80_WDT
 #ifdef CONFIG_RTC_DRV_M41T80_WDT
 /*
 /*
  *****************************************************************************
  *****************************************************************************
@@ -394,7 +494,7 @@ static void wdt_ping(void)
 		/*
 		/*
 		 * WDS = 1 (0x80), mulitplier = WD_TIMO, resolution = 1s (0x02)
 		 * WDS = 1 (0x80), mulitplier = WD_TIMO, resolution = 1s (0x02)
 		 */
 		 */
-		i2c_data[1] = wdt_margin<<2 | 0x82;
+		i2c_data[1] = wdt_margin << 2 | 0x82;
 
 
 	/*
 	/*
 	 * M41T65 has three bits for watchdog resolution.  Don't set bit 7, as
 	 * M41T65 has three bits for watchdog resolution.  Don't set bit 7, as
@@ -636,49 +736,76 @@ static struct notifier_block wdt_notifier = {
  *
  *
  *****************************************************************************
  *****************************************************************************
  */
  */
+
+static void m41t80_remove_sysfs_group(void *_dev)
+{
+	struct device *dev = _dev;
+
+	sysfs_remove_group(&dev->kobj, &attr_group);
+}
+
 static int m41t80_probe(struct i2c_client *client,
 static int m41t80_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 			const struct i2c_device_id *id)
 {
 {
+	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
 	int rc = 0;
 	int rc = 0;
 	struct rtc_device *rtc = NULL;
 	struct rtc_device *rtc = NULL;
 	struct rtc_time tm;
 	struct rtc_time tm;
-	struct m41t80_data *clientdata = NULL;
+	struct m41t80_data *m41t80_data = NULL;
 
 
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C
-				     | I2C_FUNC_SMBUS_BYTE_DATA))
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
+				     I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_err(&adapter->dev, "doesn't support I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK\n");
 		return -ENODEV;
 		return -ENODEV;
+	}
 
 
-	clientdata = devm_kzalloc(&client->dev, sizeof(*clientdata),
-				GFP_KERNEL);
-	if (!clientdata)
+	m41t80_data = devm_kzalloc(&client->dev, sizeof(*m41t80_data),
+				   GFP_KERNEL);
+	if (!m41t80_data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	clientdata->features = id->driver_data;
-	i2c_set_clientdata(client, clientdata);
+	m41t80_data->features = id->driver_data;
+	i2c_set_clientdata(client, m41t80_data);
+
+	if (client->irq > 0) {
+		rc = devm_request_threaded_irq(&client->dev, client->irq,
+					       NULL, m41t80_handle_irq,
+					       IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					       "m41t80", client);
+		if (rc) {
+			dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
+			client->irq = 0;
+		} else {
+			m41t80_rtc_ops.read_alarm = m41t80_read_alarm;
+			m41t80_rtc_ops.set_alarm = m41t80_set_alarm;
+			m41t80_rtc_ops.alarm_irq_enable = m41t80_alarm_irq_enable;
+			/* Enable the wakealarm */
+			device_init_wakeup(&client->dev, true);
+		}
+	}
 
 
 	rtc = devm_rtc_device_register(&client->dev, client->name,
 	rtc = devm_rtc_device_register(&client->dev, client->name,
-					&m41t80_rtc_ops, THIS_MODULE);
+				       &m41t80_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc))
 	if (IS_ERR(rtc))
 		return PTR_ERR(rtc);
 		return PTR_ERR(rtc);
 
 
-	clientdata->rtc = rtc;
+	m41t80_data->rtc = rtc;
 
 
 	/* Make sure HT (Halt Update) bit is cleared */
 	/* Make sure HT (Halt Update) bit is cleared */
 	rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR);
 	rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR);
 
 
 	if (rc >= 0 && rc & M41T80_ALHOUR_HT) {
 	if (rc >= 0 && rc & M41T80_ALHOUR_HT) {
-		if (clientdata->features & M41T80_FEATURE_HT) {
+		if (m41t80_data->features & M41T80_FEATURE_HT) {
 			m41t80_get_datetime(client, &tm);
 			m41t80_get_datetime(client, &tm);
 			dev_info(&client->dev, "HT bit was set!\n");
 			dev_info(&client->dev, "HT bit was set!\n");
 			dev_info(&client->dev,
 			dev_info(&client->dev,
-				 "Power Down at "
-				 "%04i-%02i-%02i %02i:%02i:%02i\n",
+				 "Power Down at %04i-%02i-%02i %02i:%02i:%02i\n",
 				 tm.tm_year + 1900,
 				 tm.tm_year + 1900,
 				 tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
 				 tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
 				 tm.tm_min, tm.tm_sec);
 				 tm.tm_min, tm.tm_sec);
 		}
 		}
 		rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_HOUR,
 		rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_HOUR,
-					      rc & ~M41T80_ALHOUR_HT);
+					       rc & ~M41T80_ALHOUR_HT);
 	}
 	}
 
 
 	if (rc < 0) {
 	if (rc < 0) {
@@ -691,18 +818,30 @@ static int m41t80_probe(struct i2c_client *client,
 
 
 	if (rc >= 0 && rc & M41T80_SEC_ST)
 	if (rc >= 0 && rc & M41T80_SEC_ST)
 		rc = i2c_smbus_write_byte_data(client, M41T80_REG_SEC,
 		rc = i2c_smbus_write_byte_data(client, M41T80_REG_SEC,
-					      rc & ~M41T80_SEC_ST);
+					       rc & ~M41T80_SEC_ST);
 	if (rc < 0) {
 	if (rc < 0) {
 		dev_err(&client->dev, "Can't clear ST bit\n");
 		dev_err(&client->dev, "Can't clear ST bit\n");
 		return rc;
 		return rc;
 	}
 	}
 
 
-	rc = m41t80_sysfs_register(&client->dev);
-	if (rc)
+	/* Export sysfs entries */
+	rc = sysfs_create_group(&(&client->dev)->kobj, &attr_group);
+	if (rc) {
+		dev_err(&client->dev, "Failed to create sysfs group: %d\n", rc);
+		return rc;
+	}
+
+	rc = devm_add_action(&client->dev, m41t80_remove_sysfs_group,
+			     &client->dev);
+	if (rc) {
+		m41t80_remove_sysfs_group(&client->dev);
+		dev_err(&client->dev,
+			"Failed to add sysfs cleanup action: %d\n", rc);
 		return rc;
 		return rc;
+	}
 
 
 #ifdef CONFIG_RTC_DRV_M41T80_WDT
 #ifdef CONFIG_RTC_DRV_M41T80_WDT
-	if (clientdata->features & M41T80_FEATURE_HT) {
+	if (m41t80_data->features & M41T80_FEATURE_HT) {
 		save_client = client;
 		save_client = client;
 		rc = misc_register(&wdt_dev);
 		rc = misc_register(&wdt_dev);
 		if (rc)
 		if (rc)

+ 0 - 3
drivers/rtc/rtc-m48t35.c

@@ -22,8 +22,6 @@
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/err.h>
 
 
-#define DRV_VERSION		"1.0"
-
 struct m48t35_rtc {
 struct m48t35_rtc {
 	u8	pad[0x7ff8];    /* starts at 0x7ff8 */
 	u8	pad[0x7ff8];    /* starts at 0x7ff8 */
 	u8	control;
 	u8	control;
@@ -190,5 +188,4 @@ module_platform_driver(m48t35_platform_driver);
 MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
 MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
 MODULE_DESCRIPTION("M48T35 RTC driver");
 MODULE_DESCRIPTION("M48T35 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
 MODULE_ALIAS("platform:rtc-m48t35");
 MODULE_ALIAS("platform:rtc-m48t35");

+ 0 - 4
drivers/rtc/rtc-m48t86.c

@@ -39,9 +39,6 @@
 #define M48T86_REG_B_SET	(1 << 7)
 #define M48T86_REG_B_SET	(1 << 7)
 #define M48T86_REG_D_VRT	(1 << 7)
 #define M48T86_REG_D_VRT	(1 << 7)
 
 
-#define DRV_VERSION "0.1"
-
-
 static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm)
 static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
 {
 	unsigned char reg;
 	unsigned char reg;
@@ -178,5 +175,4 @@ module_platform_driver(m48t86_rtc_platform_driver);
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_DESCRIPTION("M48T86 RTC driver");
 MODULE_DESCRIPTION("M48T86 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
 MODULE_ALIAS("platform:rtc-m48t86");
 MODULE_ALIAS("platform:rtc-m48t86");

+ 0 - 5
drivers/rtc/rtc-max6900.c

@@ -17,8 +17,6 @@
 #include <linux/rtc.h>
 #include <linux/rtc.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 
 
-#define DRV_VERSION "0.2"
-
 /*
 /*
  * register indices
  * register indices
  */
  */
@@ -218,8 +216,6 @@ max6900_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
 		return -ENODEV;
 		return -ENODEV;
 
 
-	dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
-
 	rtc = devm_rtc_device_register(&client->dev, max6900_driver.driver.name,
 	rtc = devm_rtc_device_register(&client->dev, max6900_driver.driver.name,
 					&max6900_rtc_ops, THIS_MODULE);
 					&max6900_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc))
 	if (IS_ERR(rtc))
@@ -249,4 +245,3 @@ module_i2c_driver(max6900_driver);
 MODULE_DESCRIPTION("Maxim MAX6900 RTC driver");
 MODULE_DESCRIPTION("Maxim MAX6900 RTC driver");
 MODULE_AUTHOR("Dale Farnsworth <dale@farnsworth.org>");
 MODULE_AUTHOR("Dale Farnsworth <dale@farnsworth.org>");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);

+ 0 - 19
drivers/rtc/rtc-mc13xxx.c

@@ -250,18 +250,6 @@ static irqreturn_t mc13xxx_rtc_alarm_handler(int irq, void *dev)
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
-static irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev)
-{
-	struct mc13xxx_rtc *priv = dev;
-	struct mc13xxx *mc13xxx = priv->mc13xxx;
-
-	rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF);
-
-	mc13xxx_irq_ack(mc13xxx, irq);
-
-	return IRQ_HANDLED;
-}
-
 static const struct rtc_class_ops mc13xxx_rtc_ops = {
 static const struct rtc_class_ops mc13xxx_rtc_ops = {
 	.read_time = mc13xxx_rtc_read_time,
 	.read_time = mc13xxx_rtc_read_time,
 	.set_mmss64 = mc13xxx_rtc_set_mmss,
 	.set_mmss64 = mc13xxx_rtc_set_mmss,
@@ -307,11 +295,6 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev)
 	if (ret)
 	if (ret)
 		goto err_irq_request;
 		goto err_irq_request;
 
 
-	ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_1HZ,
-			mc13xxx_rtc_update_handler, DRIVER_NAME, priv);
-	if (ret)
-		goto err_irq_request;
-
 	ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_TODA,
 	ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_TODA,
 			mc13xxx_rtc_alarm_handler, DRIVER_NAME, priv);
 			mc13xxx_rtc_alarm_handler, DRIVER_NAME, priv);
 	if (ret)
 	if (ret)
@@ -326,7 +309,6 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev)
 
 
 err_irq_request:
 err_irq_request:
 	mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_TODA, priv);
 	mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_TODA, priv);
-	mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_1HZ, priv);
 	mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv);
 	mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv);
 
 
 	mc13xxx_unlock(mc13xxx);
 	mc13xxx_unlock(mc13xxx);
@@ -341,7 +323,6 @@ static int mc13xxx_rtc_remove(struct platform_device *pdev)
 	mc13xxx_lock(priv->mc13xxx);
 	mc13xxx_lock(priv->mc13xxx);
 
 
 	mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_TODA, priv);
 	mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_TODA, priv);
-	mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_1HZ, priv);
 	mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_RTCRST, priv);
 	mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_RTCRST, priv);
 
 
 	mc13xxx_unlock(priv->mc13xxx);
 	mc13xxx_unlock(priv->mc13xxx);

+ 1 - 1
drivers/rtc/rtc-mrst.c

@@ -266,7 +266,7 @@ static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 }
 }
 
 
 
 
-#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
+#if IS_ENABLED(CONFIG_RTC_INTF_PROC)
 
 
 static int mrst_procfs(struct device *dev, struct seq_file *seq)
 static int mrst_procfs(struct device *dev, struct seq_file *seq)
 {
 {

+ 0 - 3
drivers/rtc/rtc-mxc.c

@@ -240,9 +240,6 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
 		mxc_rtc_irq_enable(&pdev->dev, RTC_ALM_BIT, 0);
 		mxc_rtc_irq_enable(&pdev->dev, RTC_ALM_BIT, 0);
 	}
 	}
 
 
-	if (status & RTC_1HZ_BIT)
-		events |= (RTC_UF | RTC_IRQF);
-
 	if (status & PIT_ALL_ON)
 	if (status & PIT_ALL_ON)
 		events |= (RTC_PF | RTC_IRQF);
 		events |= (RTC_PF | RTC_IRQF);
 
 

+ 0 - 4
drivers/rtc/rtc-pcf2123.c

@@ -46,8 +46,6 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/sysfs.h>
 #include <linux/sysfs.h>
 
 
-#define DRV_VERSION "0.6"
-
 /* REGISTERS */
 /* REGISTERS */
 #define PCF2123_REG_CTRL1	(0x00)	/* Control Register 1 */
 #define PCF2123_REG_CTRL1	(0x00)	/* Control Register 1 */
 #define PCF2123_REG_CTRL2	(0x01)	/* Control Register 2 */
 #define PCF2123_REG_CTRL2	(0x01)	/* Control Register 2 */
@@ -395,7 +393,6 @@ static int pcf2123_probe(struct spi_device *spi)
 		}
 		}
 	}
 	}
 
 
-	dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n");
 	dev_info(&spi->dev, "spiclk %u KHz.\n",
 	dev_info(&spi->dev, "spiclk %u KHz.\n",
 			(spi->max_speed_hz + 500) / 1000);
 			(spi->max_speed_hz + 500) / 1000);
 
 
@@ -474,4 +471,3 @@ module_spi_driver(pcf2123_driver);
 MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>");
 MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>");
 MODULE_DESCRIPTION("NXP PCF2123 RTC driver");
 MODULE_DESCRIPTION("NXP PCF2123 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);

+ 1 - 6
drivers/rtc/rtc-pcf8563.c

@@ -23,8 +23,6 @@
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/err.h>
 #include <linux/err.h>
 
 
-#define DRV_VERSION "0.4.4"
-
 #define PCF8563_REG_ST1		0x00 /* status */
 #define PCF8563_REG_ST1		0x00 /* status */
 #define PCF8563_REG_ST2		0x01
 #define PCF8563_REG_ST2		0x01
 #define PCF8563_BIT_AIE		(1 << 1)
 #define PCF8563_BIT_AIE		(1 << 1)
@@ -535,7 +533,7 @@ static struct clk *pcf8563_clkout_register_clk(struct pcf8563 *pcf8563)
 
 
 	init.name = "pcf8563-clkout";
 	init.name = "pcf8563-clkout";
 	init.ops = &pcf8563_clkout_ops;
 	init.ops = &pcf8563_clkout_ops;
-	init.flags = CLK_IS_ROOT;
+	init.flags = 0;
 	init.parent_names = NULL;
 	init.parent_names = NULL;
 	init.num_parents = 0;
 	init.num_parents = 0;
 	pcf8563->clkout_hw.init = &init;
 	pcf8563->clkout_hw.init = &init;
@@ -580,8 +578,6 @@ static int pcf8563_probe(struct i2c_client *client,
 	if (!pcf8563)
 	if (!pcf8563)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
-
 	i2c_set_clientdata(client, pcf8563);
 	i2c_set_clientdata(client, pcf8563);
 	pcf8563->client = client;
 	pcf8563->client = client;
 	device_set_wakeup_capable(&client->dev, 1);
 	device_set_wakeup_capable(&client->dev, 1);
@@ -662,4 +658,3 @@ module_i2c_driver(pcf8563_driver);
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver");
 MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);

+ 0 - 2
drivers/rtc/rtc-rs5c313.c

@@ -50,7 +50,6 @@
 #include <linux/io.h>
 #include <linux/io.h>
 
 
 #define DRV_NAME	"rs5c313"
 #define DRV_NAME	"rs5c313"
-#define DRV_VERSION	"1.13"
 
 
 #ifdef CONFIG_SH_LANDISK
 #ifdef CONFIG_SH_LANDISK
 /*****************************************************/
 /*****************************************************/
@@ -407,7 +406,6 @@ static void __exit rs5c313_rtc_exit(void)
 module_init(rs5c313_rtc_init);
 module_init(rs5c313_rtc_init);
 module_exit(rs5c313_rtc_exit);
 module_exit(rs5c313_rtc_exit);
 
 
-MODULE_VERSION(DRV_VERSION);
 MODULE_AUTHOR("kogiidena , Nobuhiro Iwamatsu <iwamatsu@nigauri.org>");
 MODULE_AUTHOR("kogiidena , Nobuhiro Iwamatsu <iwamatsu@nigauri.org>");
 MODULE_DESCRIPTION("Ricoh RS5C313 RTC device driver");
 MODULE_DESCRIPTION("Ricoh RS5C313 RTC device driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");

+ 0 - 4
drivers/rtc/rtc-rs5c348.c

@@ -25,8 +25,6 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
 #include <linux/module.h>
 #include <linux/module.h>
 
 
-#define DRV_VERSION "0.2"
-
 #define RS5C348_REG_SECS	0
 #define RS5C348_REG_SECS	0
 #define RS5C348_REG_MINS	1
 #define RS5C348_REG_MINS	1
 #define RS5C348_REG_HOURS	2
 #define RS5C348_REG_HOURS	2
@@ -171,7 +169,6 @@ static int rs5c348_probe(struct spi_device *spi)
 		goto kfree_exit;
 		goto kfree_exit;
 	}
 	}
 
 
-	dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n");
 	dev_info(&spi->dev, "spiclk %u KHz.\n",
 	dev_info(&spi->dev, "spiclk %u KHz.\n",
 		 (spi->max_speed_hz + 500) / 1000);
 		 (spi->max_speed_hz + 500) / 1000);
 
 
@@ -230,5 +227,4 @@ module_spi_driver(rs5c348_driver);
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver");
 MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
 MODULE_ALIAS("spi:rtc-rs5c348");
 MODULE_ALIAS("spi:rtc-rs5c348");

+ 7 - 11
drivers/rtc/rtc-rs5c372.c

@@ -16,9 +16,6 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/module.h>
 
 
-#define DRV_VERSION "0.6"
-
-
 /*
 /*
  * Ricoh has a family of I2C based RTCs, which differ only slightly from
  * Ricoh has a family of I2C based RTCs, which differ only slightly from
  * each other.  Differences center on pinout (e.g. how many interrupts,
  * each other.  Differences center on pinout (e.g. how many interrupts,
@@ -240,11 +237,11 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm)
 	return 0;
 	return 0;
 }
 }
 
 
-#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
+#if IS_ENABLED(CONFIG_RTC_INTF_PROC)
 #define	NEED_TRIM
 #define	NEED_TRIM
 #endif
 #endif
 
 
-#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
+#if IS_ENABLED(CONFIG_RTC_INTF_SYSFS)
 #define	NEED_TRIM
 #define	NEED_TRIM
 #endif
 #endif
 
 
@@ -412,7 +409,7 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 	return 0;
 	return 0;
 }
 }
 
 
-#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
+#if IS_ENABLED(CONFIG_RTC_INTF_PROC)
 
 
 static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq)
 static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq)
 {
 {
@@ -441,7 +438,7 @@ static const struct rtc_class_ops rs5c372_rtc_ops = {
 	.alarm_irq_enable = rs5c_rtc_alarm_irq_enable,
 	.alarm_irq_enable = rs5c_rtc_alarm_irq_enable,
 };
 };
 
 
-#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
+#if IS_ENABLED(CONFIG_RTC_INTF_SYSFS)
 
 
 static ssize_t rs5c372_sysfs_show_trim(struct device *dev,
 static ssize_t rs5c372_sysfs_show_trim(struct device *dev,
 				struct device_attribute *attr, char *buf)
 				struct device_attribute *attr, char *buf)
@@ -509,9 +506,9 @@ static int rs5c_oscillator_setup(struct rs5c372 *rs5c372)
 	int addr, i, ret = 0;
 	int addr, i, ret = 0;
 
 
 	if (rs5c372->type == rtc_r2025sd) {
 	if (rs5c372->type == rtc_r2025sd) {
-		if (!(rs5c372->regs[RS5C_REG_CTRL2] & R2025_CTRL2_XST))
+		if (rs5c372->regs[RS5C_REG_CTRL2] & R2025_CTRL2_XST)
 			return ret;
 			return ret;
-		rs5c372->regs[RS5C_REG_CTRL2] &= ~R2025_CTRL2_XST;
+		rs5c372->regs[RS5C_REG_CTRL2] |= R2025_CTRL2_XST;
 	} else {
 	} else {
 		if (!(rs5c372->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_XSTP))
 		if (!(rs5c372->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_XSTP))
 			return ret;
 			return ret;
@@ -640,7 +637,7 @@ static int rs5c372_probe(struct i2c_client *client,
 	if (rs5c372_get_datetime(client, &tm) < 0)
 	if (rs5c372_get_datetime(client, &tm) < 0)
 		dev_warn(&client->dev, "clock needs to be set\n");
 		dev_warn(&client->dev, "clock needs to be set\n");
 
 
-	dev_info(&client->dev, "%s found, %s, driver version " DRV_VERSION "\n",
+	dev_info(&client->dev, "%s found, %s\n",
 			({ char *s; switch (rs5c372->type) {
 			({ char *s; switch (rs5c372->type) {
 			case rtc_r2025sd:	s = "r2025sd"; break;
 			case rtc_r2025sd:	s = "r2025sd"; break;
 			case rtc_r2221tl:	s = "r2221tl"; break;
 			case rtc_r2221tl:	s = "r2221tl"; break;
@@ -696,4 +693,3 @@ MODULE_AUTHOR(
 		"Paul Mundt <lethal@linux-sh.org>");
 		"Paul Mundt <lethal@linux-sh.org>");
 MODULE_DESCRIPTION("Ricoh RS5C372 RTC driver");
 MODULE_DESCRIPTION("Ricoh RS5C372 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);

+ 385 - 211
drivers/rtc/rtc-rv3029c2.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Micro Crystal RV-3029 rtc class driver
+ * Micro Crystal RV-3029 / RV-3049 rtc class driver
  *
  *
  * Author: Gregory Hermant <gregory.hermant@calao-systems.com>
  * Author: Gregory Hermant <gregory.hermant@calao-systems.com>
  *         Michael Buesch <m@bues.ch>
  *         Michael Buesch <m@bues.ch>
@@ -14,13 +14,14 @@
 
 
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/spi/spi.h>
 #include <linux/bcd.h>
 #include <linux/bcd.h>
 #include <linux/rtc.h>
 #include <linux/rtc.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/hwmon-sysfs.h>
-
+#include <linux/regmap.h>
 
 
 /* Register map */
 /* Register map */
 /* control section */
 /* control section */
@@ -75,6 +76,7 @@
 #define RV3029_A_DW			0x14
 #define RV3029_A_DW			0x14
 #define RV3029_A_MO			0x15
 #define RV3029_A_MO			0x15
 #define RV3029_A_YR			0x16
 #define RV3029_A_YR			0x16
+#define RV3029_A_AE_X			BIT(7)
 #define RV3029_ALARM_SECTION_LEN	0x07
 #define RV3029_ALARM_SECTION_LEN	0x07
 
 
 /* timer section */
 /* timer section */
@@ -116,85 +118,84 @@
 #define RV3029_USR2_RAM_PAGE		0x3C
 #define RV3029_USR2_RAM_PAGE		0x3C
 #define RV3029_USR2_SECTION_LEN		0x04
 #define RV3029_USR2_SECTION_LEN		0x04
 
 
-static int
-rv3029_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
-		     unsigned len)
+struct rv3029_data {
+	struct device		*dev;
+	struct rtc_device	*rtc;
+	struct regmap		*regmap;
+	int irq;
+};
+
+static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf,
+			    unsigned int len)
 {
 {
-	int ret;
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 
 
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
-		(reg + len > RV3029_USR1_RAM_PAGE + 8))
+	    (reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	ret = i2c_smbus_read_i2c_block_data(client, reg, len, buf);
-	if (ret < 0)
-		return ret;
-	if (ret < len)
-		return -EIO;
-	return 0;
+	return regmap_bulk_read(rv3029->regmap, reg, buf, len);
 }
 }
 
 
-static int
-rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
-		      unsigned len)
+static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
+			     unsigned int len)
 {
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
-		(reg + len > RV3029_USR1_RAM_PAGE + 8))
+	    (reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	return i2c_smbus_write_i2c_block_data(client, reg, len, buf);
+	return regmap_bulk_write(rv3029->regmap, reg, buf, len);
 }
 }
 
 
-static int
-rv3029_i2c_update_bits(struct i2c_client *client, u8 reg, u8 mask, u8 set)
+static int rv3029_update_bits(struct device *dev, u8 reg, u8 mask, u8 set)
 {
 {
 	u8 buf;
 	u8 buf;
 	int ret;
 	int ret;
 
 
-	ret = rv3029_i2c_read_regs(client, reg, &buf, 1);
+	ret = rv3029_read_regs(dev, reg, &buf, 1);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 	buf &= ~mask;
 	buf &= ~mask;
 	buf |= set & mask;
 	buf |= set & mask;
-	ret = rv3029_i2c_write_regs(client, reg, &buf, 1);
+	ret = rv3029_write_regs(dev, reg, &buf, 1);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int
-rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf)
+static int rv3029_get_sr(struct device *dev, u8 *buf)
 {
 {
-	int ret = rv3029_i2c_read_regs(client, RV3029_STATUS, buf, 1);
+	int ret = rv3029_read_regs(dev, RV3029_STATUS, buf, 1);
 
 
 	if (ret < 0)
 	if (ret < 0)
 		return -EIO;
 		return -EIO;
-	dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
+	dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
 	return 0;
 	return 0;
 }
 }
 
 
-static int
-rv3029_i2c_set_sr(struct i2c_client *client, u8 val)
+static int rv3029_set_sr(struct device *dev, u8 val)
 {
 {
 	u8 buf[1];
 	u8 buf[1];
 	int sr;
 	int sr;
 
 
 	buf[0] = val;
 	buf[0] = val;
-	sr = rv3029_i2c_write_regs(client, RV3029_STATUS, buf, 1);
-	dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
+	sr = rv3029_write_regs(dev, RV3029_STATUS, buf, 1);
+	dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
 	if (sr < 0)
 	if (sr < 0)
 		return -EIO;
 		return -EIO;
 	return 0;
 	return 0;
 }
 }
 
 
-static int rv3029_eeprom_busywait(struct i2c_client *client)
+static int rv3029_eeprom_busywait(struct device *dev)
 {
 {
 	int i, ret;
 	int i, ret;
 	u8 sr;
 	u8 sr;
 
 
 	for (i = 100; i > 0; i--) {
 	for (i = 100; i > 0; i--) {
-		ret = rv3029_i2c_get_sr(client, &sr);
+		ret = rv3029_get_sr(dev, &sr);
 		if (ret < 0)
 		if (ret < 0)
 			break;
 			break;
 		if (!(sr & RV3029_STATUS_EEBUSY))
 		if (!(sr & RV3029_STATUS_EEBUSY))
@@ -202,28 +203,28 @@ static int rv3029_eeprom_busywait(struct i2c_client *client)
 		usleep_range(1000, 10000);
 		usleep_range(1000, 10000);
 	}
 	}
 	if (i <= 0) {
 	if (i <= 0) {
-		dev_err(&client->dev, "EEPROM busy wait timeout.\n");
+		dev_err(dev, "EEPROM busy wait timeout.\n");
 		return -ETIMEDOUT;
 		return -ETIMEDOUT;
 	}
 	}
 
 
 	return ret;
 	return ret;
 }
 }
 
 
-static int rv3029_eeprom_exit(struct i2c_client *client)
+static int rv3029_eeprom_exit(struct device *dev)
 {
 {
 	/* Re-enable eeprom refresh */
 	/* Re-enable eeprom refresh */
-	return rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL,
-				      RV3029_ONOFF_CTRL_EERE,
-				      RV3029_ONOFF_CTRL_EERE);
+	return rv3029_update_bits(dev, RV3029_ONOFF_CTRL,
+				  RV3029_ONOFF_CTRL_EERE,
+				  RV3029_ONOFF_CTRL_EERE);
 }
 }
 
 
-static int rv3029_eeprom_enter(struct i2c_client *client)
+static int rv3029_eeprom_enter(struct device *dev)
 {
 {
 	int ret;
 	int ret;
 	u8 sr;
 	u8 sr;
 
 
 	/* Check whether we are in the allowed voltage range. */
 	/* Check whether we are in the allowed voltage range. */
-	ret = rv3029_i2c_get_sr(client, &sr);
+	ret = rv3029_get_sr(dev, &sr);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
 	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@@ -232,129 +233,168 @@ static int rv3029_eeprom_enter(struct i2c_client *client)
 		 */
 		 */
 		sr &= ~RV3029_STATUS_VLOW1;
 		sr &= ~RV3029_STATUS_VLOW1;
 		sr &= ~RV3029_STATUS_VLOW2;
 		sr &= ~RV3029_STATUS_VLOW2;
-		ret = rv3029_i2c_set_sr(client, sr);
+		ret = rv3029_set_sr(dev, sr);
 		if (ret < 0)
 		if (ret < 0)
 			return ret;
 			return ret;
 		usleep_range(1000, 10000);
 		usleep_range(1000, 10000);
-		ret = rv3029_i2c_get_sr(client, &sr);
+		ret = rv3029_get_sr(dev, &sr);
 		if (ret < 0)
 		if (ret < 0)
 			return ret;
 			return ret;
 		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
 		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
-			dev_err(&client->dev,
+			dev_err(dev,
 				"Supply voltage is too low to safely access the EEPROM.\n");
 				"Supply voltage is too low to safely access the EEPROM.\n");
 			return -ENODEV;
 			return -ENODEV;
 		}
 		}
 	}
 	}
 
 
 	/* Disable eeprom refresh. */
 	/* Disable eeprom refresh. */
-	ret = rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL,
-				     RV3029_ONOFF_CTRL_EERE, 0);
+	ret = rv3029_update_bits(dev, RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE,
+				 0);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
 	/* Wait for any previous eeprom accesses to finish. */
 	/* Wait for any previous eeprom accesses to finish. */
-	ret = rv3029_eeprom_busywait(client);
+	ret = rv3029_eeprom_busywait(dev);
 	if (ret < 0)
 	if (ret < 0)
-		rv3029_eeprom_exit(client);
+		rv3029_eeprom_exit(dev);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
-static int rv3029_eeprom_read(struct i2c_client *client, u8 reg,
+static int rv3029_eeprom_read(struct device *dev, u8 reg,
 			      u8 buf[], size_t len)
 			      u8 buf[], size_t len)
 {
 {
 	int ret, err;
 	int ret, err;
 
 
-	err = rv3029_eeprom_enter(client);
+	err = rv3029_eeprom_enter(dev);
 	if (err < 0)
 	if (err < 0)
 		return err;
 		return err;
 
 
-	ret = rv3029_i2c_read_regs(client, reg, buf, len);
+	ret = rv3029_read_regs(dev, reg, buf, len);
 
 
-	err = rv3029_eeprom_exit(client);
+	err = rv3029_eeprom_exit(dev);
 	if (err < 0)
 	if (err < 0)
 		return err;
 		return err;
 
 
 	return ret;
 	return ret;
 }
 }
 
 
-static int rv3029_eeprom_write(struct i2c_client *client, u8 reg,
+static int rv3029_eeprom_write(struct device *dev, u8 reg,
 			       u8 const buf[], size_t len)
 			       u8 const buf[], size_t len)
 {
 {
 	int ret, err;
 	int ret, err;
 	size_t i;
 	size_t i;
 	u8 tmp;
 	u8 tmp;
 
 
-	err = rv3029_eeprom_enter(client);
+	err = rv3029_eeprom_enter(dev);
 	if (err < 0)
 	if (err < 0)
 		return err;
 		return err;
 
 
 	for (i = 0; i < len; i++, reg++) {
 	for (i = 0; i < len; i++, reg++) {
-		ret = rv3029_i2c_read_regs(client, reg, &tmp, 1);
+		ret = rv3029_read_regs(dev, reg, &tmp, 1);
 		if (ret < 0)
 		if (ret < 0)
 			break;
 			break;
 		if (tmp != buf[i]) {
 		if (tmp != buf[i]) {
-			ret = rv3029_i2c_write_regs(client, reg, &buf[i], 1);
+			ret = rv3029_write_regs(dev, reg, &buf[i], 1);
 			if (ret < 0)
 			if (ret < 0)
 				break;
 				break;
 		}
 		}
-		ret = rv3029_eeprom_busywait(client);
+		ret = rv3029_eeprom_busywait(dev);
 		if (ret < 0)
 		if (ret < 0)
 			break;
 			break;
 	}
 	}
 
 
-	err = rv3029_eeprom_exit(client);
+	err = rv3029_eeprom_exit(dev);
 	if (err < 0)
 	if (err < 0)
 		return err;
 		return err;
 
 
 	return ret;
 	return ret;
 }
 }
 
 
-static int rv3029_eeprom_update_bits(struct i2c_client *client,
+static int rv3029_eeprom_update_bits(struct device *dev,
 				     u8 reg, u8 mask, u8 set)
 				     u8 reg, u8 mask, u8 set)
 {
 {
 	u8 buf;
 	u8 buf;
 	int ret;
 	int ret;
 
 
-	ret = rv3029_eeprom_read(client, reg, &buf, 1);
+	ret = rv3029_eeprom_read(dev, reg, &buf, 1);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 	buf &= ~mask;
 	buf &= ~mask;
 	buf |= set & mask;
 	buf |= set & mask;
-	ret = rv3029_eeprom_write(client, reg, &buf, 1);
+	ret = rv3029_eeprom_write(dev, reg, &buf, 1);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int
-rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
+static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
+{
+	struct device *dev = dev_id;
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+	struct mutex *lock = &rv3029->rtc->ops_lock;
+	unsigned long events = 0;
+	u8 flags, controls;
+	int ret;
+
+	mutex_lock(lock);
+
+	ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	if (ret) {
+		dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
+		mutex_unlock(lock);
+		return IRQ_NONE;
+	}
+
+	ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+	if (ret) {
+		dev_warn(dev, "Read IRQ Flags Register error %d\n", ret);
+		mutex_unlock(lock);
+		return IRQ_NONE;
+	}
+
+	if (flags & RV3029_IRQ_FLAGS_AF) {
+		flags &= ~RV3029_IRQ_FLAGS_AF;
+		controls &= ~RV3029_IRQ_CTRL_AIE;
+		events |= RTC_AF;
+	}
+
+	if (events) {
+		rtc_update_irq(rv3029->rtc, 1, events);
+		rv3029_write_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+		rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	}
+	mutex_unlock(lock);
+
+	return IRQ_HANDLED;
+}
+
+static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 {
 {
 	u8 buf[1];
 	u8 buf[1];
 	int ret;
 	int ret;
 	u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
 	u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
 
 
-	ret = rv3029_i2c_get_sr(client, buf);
+	ret = rv3029_get_sr(dev, buf);
 	if (ret < 0) {
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 		return -EIO;
 	}
 	}
 
 
-	ret = rv3029_i2c_read_regs(client, RV3029_W_SEC, regs,
-				   RV3029_WATCH_SECTION_LEN);
+	ret = rv3029_read_regs(dev, RV3029_W_SEC, regs,
+			       RV3029_WATCH_SECTION_LEN);
 	if (ret < 0) {
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading RTC section failed\n",
-			__func__);
+		dev_err(dev, "%s: reading RTC section failed\n", __func__);
 		return ret;
 		return ret;
 	}
 	}
 
 
-	tm->tm_sec = bcd2bin(regs[RV3029_W_SEC-RV3029_W_SEC]);
-	tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES-RV3029_W_SEC]);
+	tm->tm_sec = bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]);
+	tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]);
 
 
 	/* HR field has a more complex interpretation */
 	/* HR field has a more complex interpretation */
 	{
 	{
-		const u8 _hr = regs[RV3029_W_HOURS-RV3029_W_SEC];
+		const u8 _hr = regs[RV3029_W_HOURS - RV3029_W_SEC];
 
 
 		if (_hr & RV3029_REG_HR_12_24) {
 		if (_hr & RV3029_REG_HR_12_24) {
 			/* 12h format */
 			/* 12h format */
@@ -365,77 +405,86 @@ rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
 			tm->tm_hour = bcd2bin(_hr & 0x3f);
 			tm->tm_hour = bcd2bin(_hr & 0x3f);
 	}
 	}
 
 
-	tm->tm_mday = bcd2bin(regs[RV3029_W_DATE-RV3029_W_SEC]);
-	tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS-RV3029_W_SEC]) - 1;
-	tm->tm_year = bcd2bin(regs[RV3029_W_YEARS-RV3029_W_SEC]) + 100;
-	tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS-RV3029_W_SEC]) - 1;
+	tm->tm_mday = bcd2bin(regs[RV3029_W_DATE - RV3029_W_SEC]);
+	tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS - RV3029_W_SEC]) - 1;
+	tm->tm_year = bcd2bin(regs[RV3029_W_YEARS - RV3029_W_SEC]) + 100;
+	tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS - RV3029_W_SEC]) - 1;
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int rv3029_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
-	return rv3029_i2c_read_time(to_i2c_client(dev), tm);
-}
-
-static int
-rv3029_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
+static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 {
 	struct rtc_time *const tm = &alarm->time;
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
 	int ret;
-	u8 regs[8];
+	u8 regs[8], controls, flags;
 
 
-	ret = rv3029_i2c_get_sr(client, regs);
+	ret = rv3029_get_sr(dev, regs);
 	if (ret < 0) {
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 		return -EIO;
 	}
 	}
 
 
-	ret = rv3029_i2c_read_regs(client, RV3029_A_SC, regs,
-				   RV3029_ALARM_SECTION_LEN);
+	ret = rv3029_read_regs(dev, RV3029_A_SC, regs,
+			       RV3029_ALARM_SECTION_LEN);
 
 
 	if (ret < 0) {
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading alarm section failed\n",
-			__func__);
+		dev_err(dev, "%s: reading alarm section failed\n", __func__);
 		return ret;
 		return ret;
 	}
 	}
 
 
-	tm->tm_sec = bcd2bin(regs[RV3029_A_SC-RV3029_A_SC] & 0x7f);
-	tm->tm_min = bcd2bin(regs[RV3029_A_MN-RV3029_A_SC] & 0x7f);
-	tm->tm_hour = bcd2bin(regs[RV3029_A_HR-RV3029_A_SC] & 0x3f);
-	tm->tm_mday = bcd2bin(regs[RV3029_A_DT-RV3029_A_SC] & 0x3f);
-	tm->tm_mon = bcd2bin(regs[RV3029_A_MO-RV3029_A_SC] & 0x1f) - 1;
-	tm->tm_year = bcd2bin(regs[RV3029_A_YR-RV3029_A_SC] & 0x7f) + 100;
-	tm->tm_wday = bcd2bin(regs[RV3029_A_DW-RV3029_A_SC] & 0x07) - 1;
+	ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	if (ret) {
+		dev_err(dev, "Read IRQ Control Register error %d\n", ret);
+		return ret;
+	}
+	ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+	if (ret < 0) {
+		dev_err(dev, "Read IRQ Flags Register error %d\n", ret);
+		return ret;
+	}
 
 
-	return 0;
-}
+	tm->tm_sec = bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f);
+	tm->tm_min = bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f);
+	tm->tm_hour = bcd2bin(regs[RV3029_A_HR - RV3029_A_SC] & 0x3f);
+	tm->tm_mday = bcd2bin(regs[RV3029_A_DT - RV3029_A_SC] & 0x3f);
+	tm->tm_mon = bcd2bin(regs[RV3029_A_MO - RV3029_A_SC] & 0x1f) - 1;
+	tm->tm_year = bcd2bin(regs[RV3029_A_YR - RV3029_A_SC] & 0x7f) + 100;
+	tm->tm_wday = bcd2bin(regs[RV3029_A_DW - RV3029_A_SC] & 0x07) - 1;
 
 
-static int
-rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
-	return rv3029_i2c_read_alarm(to_i2c_client(dev), alarm);
+	alarm->enabled = !!(controls & RV3029_IRQ_CTRL_AIE);
+	alarm->pending = (flags & RV3029_IRQ_FLAGS_AF) && alarm->enabled;
+
+	return 0;
 }
 }
 
 
-static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client,
-					int enable)
+static int rv3029_alarm_irq_enable(struct device *dev, unsigned int enable)
 {
 {
 	int ret;
 	int ret;
+	u8 controls;
+
+	ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	if (ret < 0) {
+		dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
+		return ret;
+	}
 
 
 	/* enable/disable AIE irq */
 	/* enable/disable AIE irq */
-	ret = rv3029_i2c_update_bits(client, RV3029_IRQ_CTRL,
-				     RV3029_IRQ_CTRL_AIE,
-				     (enable ? RV3029_IRQ_CTRL_AIE : 0));
+	if (enable)
+		controls |= RV3029_IRQ_CTRL_AIE;
+	else
+		controls &= ~RV3029_IRQ_CTRL_AIE;
+
+	ret = rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
 	if (ret < 0) {
 	if (ret < 0) {
-		dev_err(&client->dev, "can't update INT reg\n");
+		dev_err(dev, "can't update INT reg\n");
 		return ret;
 		return ret;
 	}
 	}
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
-				    struct rtc_wkalrm *alarm)
+static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 {
 	struct rtc_time *const tm = &alarm->time;
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
 	int ret;
@@ -449,57 +498,48 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
 	if (tm->tm_year < 100)
 	if (tm->tm_year < 100)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	ret = rv3029_i2c_get_sr(client, regs);
+	ret = rv3029_get_sr(dev, regs);
 	if (ret < 0) {
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 		return -EIO;
 	}
 	}
-	regs[RV3029_A_SC-RV3029_A_SC] = bin2bcd(tm->tm_sec & 0x7f);
-	regs[RV3029_A_MN-RV3029_A_SC] = bin2bcd(tm->tm_min & 0x7f);
-	regs[RV3029_A_HR-RV3029_A_SC] = bin2bcd(tm->tm_hour & 0x3f);
-	regs[RV3029_A_DT-RV3029_A_SC] = bin2bcd(tm->tm_mday & 0x3f);
-	regs[RV3029_A_MO-RV3029_A_SC] = bin2bcd((tm->tm_mon & 0x1f) - 1);
-	regs[RV3029_A_DW-RV3029_A_SC] = bin2bcd((tm->tm_wday & 7) - 1);
-	regs[RV3029_A_YR-RV3029_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100);
 
 
-	ret = rv3029_i2c_write_regs(client, RV3029_A_SC, regs,
-				    RV3029_ALARM_SECTION_LEN);
+	/* Activate all the alarms with AE_x bit */
+	regs[RV3029_A_SC - RV3029_A_SC] = bin2bcd(tm->tm_sec) | RV3029_A_AE_X;
+	regs[RV3029_A_MN - RV3029_A_SC] = bin2bcd(tm->tm_min) | RV3029_A_AE_X;
+	regs[RV3029_A_HR - RV3029_A_SC] = (bin2bcd(tm->tm_hour) & 0x3f)
+		| RV3029_A_AE_X;
+	regs[RV3029_A_DT - RV3029_A_SC] = (bin2bcd(tm->tm_mday) & 0x3f)
+		| RV3029_A_AE_X;
+	regs[RV3029_A_MO - RV3029_A_SC] = (bin2bcd(tm->tm_mon + 1) & 0x1f)
+		| RV3029_A_AE_X;
+	regs[RV3029_A_DW - RV3029_A_SC] = (bin2bcd(tm->tm_wday + 1) & 0x7)
+		| RV3029_A_AE_X;
+	regs[RV3029_A_YR - RV3029_A_SC] = (bin2bcd(tm->tm_year - 100))
+		| RV3029_A_AE_X;
+
+	/* Write the alarm */
+	ret = rv3029_write_regs(dev, RV3029_A_SC, regs,
+				RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
 	if (alarm->enabled) {
 	if (alarm->enabled) {
-		/* clear AF flag */
-		ret = rv3029_i2c_update_bits(client, RV3029_IRQ_FLAGS,
-					     RV3029_IRQ_FLAGS_AF, 0);
-		if (ret < 0) {
-			dev_err(&client->dev, "can't clear alarm flag\n");
-			return ret;
-		}
 		/* enable AIE irq */
 		/* enable AIE irq */
-		ret = rv3029_rtc_i2c_alarm_set_irq(client, 1);
+		ret = rv3029_alarm_irq_enable(dev, 1);
 		if (ret)
 		if (ret)
 			return ret;
 			return ret;
-
-		dev_dbg(&client->dev, "alarm IRQ armed\n");
 	} else {
 	} else {
 		/* disable AIE irq */
 		/* disable AIE irq */
-		ret = rv3029_rtc_i2c_alarm_set_irq(client, 0);
+		ret = rv3029_alarm_irq_enable(dev, 0);
 		if (ret)
 		if (ret)
 			return ret;
 			return ret;
-
-		dev_dbg(&client->dev, "alarm IRQ disabled\n");
 	}
 	}
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
-	return rv3029_rtc_i2c_set_alarm(to_i2c_client(dev), alarm);
-}
-
-static int
-rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
+static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 {
 {
 	u8 regs[8];
 	u8 regs[8];
 	int ret;
 	int ret;
@@ -512,39 +552,34 @@ rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
 	if (tm->tm_year < 100)
 	if (tm->tm_year < 100)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	regs[RV3029_W_SEC-RV3029_W_SEC] = bin2bcd(tm->tm_sec);
-	regs[RV3029_W_MINUTES-RV3029_W_SEC] = bin2bcd(tm->tm_min);
-	regs[RV3029_W_HOURS-RV3029_W_SEC] = bin2bcd(tm->tm_hour);
-	regs[RV3029_W_DATE-RV3029_W_SEC] = bin2bcd(tm->tm_mday);
-	regs[RV3029_W_MONTHS-RV3029_W_SEC] = bin2bcd(tm->tm_mon+1);
-	regs[RV3029_W_DAYS-RV3029_W_SEC] = bin2bcd((tm->tm_wday & 7)+1);
-	regs[RV3029_W_YEARS-RV3029_W_SEC] = bin2bcd(tm->tm_year - 100);
+	regs[RV3029_W_SEC - RV3029_W_SEC] = bin2bcd(tm->tm_sec);
+	regs[RV3029_W_MINUTES - RV3029_W_SEC] = bin2bcd(tm->tm_min);
+	regs[RV3029_W_HOURS - RV3029_W_SEC] = bin2bcd(tm->tm_hour);
+	regs[RV3029_W_DATE - RV3029_W_SEC] = bin2bcd(tm->tm_mday);
+	regs[RV3029_W_MONTHS - RV3029_W_SEC] = bin2bcd(tm->tm_mon + 1);
+	regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7;
+	regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 100);
 
 
-	ret = rv3029_i2c_write_regs(client, RV3029_W_SEC, regs,
-				    RV3029_WATCH_SECTION_LEN);
+	ret = rv3029_write_regs(dev, RV3029_W_SEC, regs,
+				RV3029_WATCH_SECTION_LEN);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
-	ret = rv3029_i2c_get_sr(client, regs);
+	ret = rv3029_get_sr(dev, regs);
 	if (ret < 0) {
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return ret;
 		return ret;
 	}
 	}
 	/* clear PON bit */
 	/* clear PON bit */
-	ret = rv3029_i2c_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
+	ret = rv3029_set_sr(dev, (regs[0] & ~RV3029_STATUS_PON));
 	if (ret < 0) {
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return ret;
 		return ret;
 	}
 	}
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
-	return rv3029_i2c_set_time(to_i2c_client(dev), tm);
-}
-
 static const struct rv3029_trickle_tab_elem {
 static const struct rv3029_trickle_tab_elem {
 	u32 r;		/* resistance in ohms */
 	u32 r;		/* resistance in ohms */
 	u8 conf;	/* trickle config bits */
 	u8 conf;	/* trickle config bits */
@@ -602,9 +637,9 @@ static const struct rv3029_trickle_tab_elem {
 	},
 	},
 };
 };
 
 
-static void rv3029_trickle_config(struct i2c_client *client)
+static void rv3029_trickle_config(struct device *dev)
 {
 {
-	struct device_node *of_node = client->dev.of_node;
+	struct device_node *of_node = dev->of_node;
 	const struct rv3029_trickle_tab_elem *elem;
 	const struct rv3029_trickle_tab_elem *elem;
 	int i, err;
 	int i, err;
 	u32 ohms;
 	u32 ohms;
@@ -626,27 +661,25 @@ static void rv3029_trickle_config(struct i2c_client *client)
 				break;
 				break;
 		}
 		}
 		trickle_set_bits = elem->conf;
 		trickle_set_bits = elem->conf;
-		dev_info(&client->dev,
+		dev_info(dev,
 			 "Trickle charger enabled at %d ohms resistance.\n",
 			 "Trickle charger enabled at %d ohms resistance.\n",
 			 elem->r);
 			 elem->r);
 	}
 	}
-	err = rv3029_eeprom_update_bits(client, RV3029_CONTROL_E2P_EECTRL,
+	err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_TRICKLE_MASK,
 					RV3029_TRICKLE_MASK,
 					trickle_set_bits);
 					trickle_set_bits);
-	if (err < 0) {
-		dev_err(&client->dev,
-			"Failed to update trickle charger config\n");
-	}
+	if (err < 0)
+		dev_err(dev, "Failed to update trickle charger config\n");
 }
 }
 
 
 #ifdef CONFIG_RTC_DRV_RV3029_HWMON
 #ifdef CONFIG_RTC_DRV_RV3029_HWMON
 
 
-static int rv3029_read_temp(struct i2c_client *client, int *temp_mC)
+static int rv3029_read_temp(struct device *dev, int *temp_mC)
 {
 {
 	int ret;
 	int ret;
 	u8 temp;
 	u8 temp;
 
 
-	ret = rv3029_i2c_read_regs(client, RV3029_TEMP_PAGE, &temp, 1);
+	ret = rv3029_read_regs(dev, RV3029_TEMP_PAGE, &temp, 1);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
@@ -659,10 +692,9 @@ static ssize_t rv3029_hwmon_show_temp(struct device *dev,
 				      struct device_attribute *attr,
 				      struct device_attribute *attr,
 				      char *buf)
 				      char *buf)
 {
 {
-	struct i2c_client *client = dev_get_drvdata(dev);
 	int ret, temp_mC;
 	int ret, temp_mC;
 
 
-	ret = rv3029_read_temp(client, &temp_mC);
+	ret = rv3029_read_temp(dev, &temp_mC);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
@@ -674,7 +706,6 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
 						const char *buf,
 						const char *buf,
 						size_t count)
 						size_t count)
 {
 {
-	struct i2c_client *client = dev_get_drvdata(dev);
 	unsigned long interval_ms;
 	unsigned long interval_ms;
 	int ret;
 	int ret;
 	u8 th_set_bits = 0;
 	u8 th_set_bits = 0;
@@ -688,7 +719,7 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
 		if (interval_ms >= 16000)
 		if (interval_ms >= 16000)
 			th_set_bits |= RV3029_EECTRL_THP;
 			th_set_bits |= RV3029_EECTRL_THP;
 	}
 	}
-	ret = rv3029_eeprom_update_bits(client, RV3029_CONTROL_E2P_EECTRL,
+	ret = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_EECTRL_THE | RV3029_EECTRL_THP,
 					RV3029_EECTRL_THE | RV3029_EECTRL_THP,
 					th_set_bits);
 					th_set_bits);
 	if (ret < 0)
 	if (ret < 0)
@@ -701,11 +732,10 @@ static ssize_t rv3029_hwmon_show_update_interval(struct device *dev,
 						 struct device_attribute *attr,
 						 struct device_attribute *attr,
 						 char *buf)
 						 char *buf)
 {
 {
-	struct i2c_client *client = dev_get_drvdata(dev);
 	int ret, interval_ms;
 	int ret, interval_ms;
 	u8 eectrl;
 	u8 eectrl;
 
 
-	ret = rv3029_eeprom_read(client, RV3029_CONTROL_E2P_EECTRL,
+	ret = rv3029_eeprom_read(dev, RV3029_CONTROL_E2P_EECTRL,
 				 &eectrl, 1);
 				 &eectrl, 1);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
@@ -735,82 +765,226 @@ static struct attribute *rv3029_hwmon_attrs[] = {
 };
 };
 ATTRIBUTE_GROUPS(rv3029_hwmon);
 ATTRIBUTE_GROUPS(rv3029_hwmon);
 
 
-static void rv3029_hwmon_register(struct i2c_client *client)
+static void rv3029_hwmon_register(struct device *dev, const char *name)
 {
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 	struct device *hwmon_dev;
 	struct device *hwmon_dev;
 
 
-	hwmon_dev = devm_hwmon_device_register_with_groups(
-		&client->dev, client->name, client, rv3029_hwmon_groups);
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, name, rv3029,
+							   rv3029_hwmon_groups);
 	if (IS_ERR(hwmon_dev)) {
 	if (IS_ERR(hwmon_dev)) {
-		dev_warn(&client->dev,
-			"unable to register hwmon device %ld\n",
-			PTR_ERR(hwmon_dev));
+		dev_warn(dev, "unable to register hwmon device %ld\n",
+			 PTR_ERR(hwmon_dev));
 	}
 	}
 }
 }
 
 
 #else /* CONFIG_RTC_DRV_RV3029_HWMON */
 #else /* CONFIG_RTC_DRV_RV3029_HWMON */
 
 
-static void rv3029_hwmon_register(struct i2c_client *client)
+static void rv3029_hwmon_register(struct device *dev, const char *name)
 {
 {
 }
 }
 
 
 #endif /* CONFIG_RTC_DRV_RV3029_HWMON */
 #endif /* CONFIG_RTC_DRV_RV3029_HWMON */
 
 
-static const struct rtc_class_ops rv3029_rtc_ops = {
-	.read_time	= rv3029_rtc_read_time,
-	.set_time	= rv3029_rtc_set_time,
-	.read_alarm	= rv3029_rtc_read_alarm,
-	.set_alarm	= rv3029_rtc_set_alarm,
+static struct rtc_class_ops rv3029_rtc_ops = {
+	.read_time	= rv3029_read_time,
+	.set_time	= rv3029_set_time,
 };
 };
 
 
-static struct i2c_device_id rv3029_id[] = {
-	{ "rv3029", 0 },
-	{ "rv3029c2", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, rv3029_id);
-
-static int rv3029_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
+			const char *name)
 {
 {
-	struct rtc_device *rtc;
+	struct rv3029_data *rv3029;
 	int rc = 0;
 	int rc = 0;
 	u8 buf[1];
 	u8 buf[1];
 
 
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL))
-		return -ENODEV;
+	rv3029 = devm_kzalloc(dev, sizeof(*rv3029), GFP_KERNEL);
+	if (!rv3029)
+		return -ENOMEM;
 
 
-	rc = rv3029_i2c_get_sr(client, buf);
+	rv3029->regmap = regmap;
+	rv3029->irq = irq;
+	rv3029->dev = dev;
+	dev_set_drvdata(dev, rv3029);
+
+	rc = rv3029_get_sr(dev, buf);
 	if (rc < 0) {
 	if (rc < 0) {
-		dev_err(&client->dev, "reading status failed\n");
+		dev_err(dev, "reading status failed\n");
 		return rc;
 		return rc;
 	}
 	}
 
 
-	rv3029_trickle_config(client);
-	rv3029_hwmon_register(client);
-
-	rtc = devm_rtc_device_register(&client->dev, client->name,
-				       &rv3029_rtc_ops, THIS_MODULE);
+	rv3029_trickle_config(dev);
+	rv3029_hwmon_register(dev, name);
 
 
-	if (IS_ERR(rtc))
-		return PTR_ERR(rtc);
+	rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
+					       THIS_MODULE);
+	if (IS_ERR(rv3029->rtc)) {
+		dev_err(dev, "unable to register the class device\n");
+		return PTR_ERR(rv3029->rtc);
+	}
 
 
-	i2c_set_clientdata(client, rtc);
+	if (rv3029->irq > 0) {
+		rc = devm_request_threaded_irq(dev, rv3029->irq,
+					       NULL, rv3029_handle_irq,
+					       IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					       "rv3029", dev);
+		if (rc) {
+			dev_warn(dev, "unable to request IRQ, alarms disabled\n");
+			rv3029->irq = 0;
+		} else {
+			rv3029_rtc_ops.read_alarm = rv3029_read_alarm;
+			rv3029_rtc_ops.set_alarm = rv3029_set_alarm;
+			rv3029_rtc_ops.alarm_irq_enable = rv3029_alarm_irq_enable;
+		}
+	}
 
 
 	return 0;
 	return 0;
 }
 }
 
 
+#if IS_ENABLED(CONFIG_I2C)
+
+static int rv3029_i2c_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
+{
+	struct regmap *regmap;
+	static const struct regmap_config config = {
+		.reg_bits = 8,
+		.val_bits = 8,
+	};
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
+				     I2C_FUNC_SMBUS_BYTE)) {
+		dev_err(&client->dev, "Adapter does not support SMBUS_I2C_BLOCK or SMBUS_I2C_BYTE\n");
+		return -ENODEV;
+	}
+
+	regmap = devm_regmap_init_i2c(client, &config);
+	if (IS_ERR(regmap)) {
+		dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
+			__func__, PTR_ERR(regmap));
+		return PTR_ERR(regmap);
+	}
+
+	return rv3029_probe(&client->dev, regmap, client->irq, client->name);
+}
+
+static struct i2c_device_id rv3029_id[] = {
+	{ "rv3029", 0 },
+	{ "rv3029c2", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, rv3029_id);
+
 static struct i2c_driver rv3029_driver = {
 static struct i2c_driver rv3029_driver = {
 	.driver = {
 	.driver = {
 		.name = "rtc-rv3029c2",
 		.name = "rtc-rv3029c2",
 	},
 	},
-	.probe		= rv3029_probe,
+	.probe		= rv3029_i2c_probe,
 	.id_table	= rv3029_id,
 	.id_table	= rv3029_id,
 };
 };
 
 
-module_i2c_driver(rv3029_driver);
+static int rv3029_register_driver(void)
+{
+	return i2c_add_driver(&rv3029_driver);
+}
+
+static void rv3029_unregister_driver(void)
+{
+	i2c_del_driver(&rv3029_driver);
+}
+
+#else
+
+static int rv3029_register_driver(void)
+{
+	return 0;
+}
+
+static void rv3029_unregister_driver(void)
+{
+}
+
+#endif
+
+#if IS_ENABLED(CONFIG_SPI_MASTER)
+
+static int rv3049_probe(struct spi_device *spi)
+{
+	static const struct regmap_config config = {
+		.reg_bits = 8,
+		.val_bits = 8,
+	};
+	struct regmap *regmap;
+
+	regmap = devm_regmap_init_spi(spi, &config);
+	if (IS_ERR(regmap)) {
+		dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
+			__func__, PTR_ERR(regmap));
+		return PTR_ERR(regmap);
+	}
+
+	return rv3029_probe(&spi->dev, regmap, spi->irq, "rv3049");
+}
+
+static struct spi_driver rv3049_driver = {
+	.driver = {
+		.name    = "rv3049",
+	},
+	.probe   = rv3049_probe,
+};
+
+static int rv3049_register_driver(void)
+{
+	return spi_register_driver(&rv3049_driver);
+}
+
+static void rv3049_unregister_driver(void)
+{
+	spi_unregister_driver(&rv3049_driver);
+}
+
+#else
+
+static int rv3049_register_driver(void)
+{
+	return 0;
+}
+
+static void rv3049_unregister_driver(void)
+{
+}
+
+#endif
+
+static int __init rv30x9_init(void)
+{
+	int ret;
+
+	ret = rv3029_register_driver();
+	if (ret) {
+		pr_err("Failed to register rv3029 driver: %d\n", ret);
+		return ret;
+	}
+
+	ret = rv3049_register_driver();
+	if (ret) {
+		pr_err("Failed to register rv3049 driver: %d\n", ret);
+		rv3029_unregister_driver();
+	}
+
+	return ret;
+}
+module_init(rv30x9_init)
+
+static void __exit rv30x9_exit(void)
+{
+	rv3049_unregister_driver();
+	rv3029_unregister_driver();
+}
+module_exit(rv30x9_exit)
 
 
 MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");
 MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");
 MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
 MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
-MODULE_DESCRIPTION("Micro Crystal RV3029 RTC driver");
+MODULE_DESCRIPTION("Micro Crystal RV3029/RV3049 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:rv3049");

+ 0 - 5
drivers/rtc/rtc-rx8581.c

@@ -18,8 +18,6 @@
 #include <linux/rtc.h>
 #include <linux/rtc.h>
 #include <linux/log2.h>
 #include <linux/log2.h>
 
 
-#define DRV_VERSION "0.1"
-
 #define RX8581_REG_SC		0x00 /* Second in BCD */
 #define RX8581_REG_SC		0x00 /* Second in BCD */
 #define RX8581_REG_MN		0x01 /* Minute in BCD */
 #define RX8581_REG_MN		0x01 /* Minute in BCD */
 #define RX8581_REG_HR		0x02 /* Hour in BCD */
 #define RX8581_REG_HR		0x02 /* Hour in BCD */
@@ -292,8 +290,6 @@ static int rx8581_probe(struct i2c_client *client,
 		rx8581->write_block_data = rx8581_write_block_data;
 		rx8581->write_block_data = rx8581_write_block_data;
 	}
 	}
 
 
-	dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
-
 	rx8581->rtc = devm_rtc_device_register(&client->dev,
 	rx8581->rtc = devm_rtc_device_register(&client->dev,
 		rx8581_driver.driver.name, &rx8581_rtc_ops, THIS_MODULE);
 		rx8581_driver.driver.name, &rx8581_rtc_ops, THIS_MODULE);
 
 
@@ -325,4 +321,3 @@ module_i2c_driver(rx8581_driver);
 MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>");
 MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>");
 MODULE_DESCRIPTION("Epson RX-8581 RTC driver");
 MODULE_DESCRIPTION("Epson RX-8581 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);

+ 0 - 2
drivers/rtc/rtc-sh.c

@@ -30,7 +30,6 @@
 #include <asm/rtc.h>
 #include <asm/rtc.h>
 
 
 #define DRV_NAME	"sh-rtc"
 #define DRV_NAME	"sh-rtc"
-#define DRV_VERSION	"0.2.3"
 
 
 #define RTC_REG(r)	((r) * rtc_reg_size)
 #define RTC_REG(r)	((r) * rtc_reg_size)
 
 
@@ -790,7 +789,6 @@ static struct platform_driver sh_rtc_platform_driver = {
 module_platform_driver_probe(sh_rtc_platform_driver, sh_rtc_probe);
 module_platform_driver_probe(sh_rtc_platform_driver, sh_rtc_probe);
 
 
 MODULE_DESCRIPTION("SuperH on-chip RTC driver");
 MODULE_DESCRIPTION("SuperH on-chip RTC driver");
-MODULE_VERSION(DRV_VERSION);
 MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, "
 MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, "
 	      "Jamie Lenehan <lenehan@twibble.org>, "
 	      "Jamie Lenehan <lenehan@twibble.org>, "
 	      "Angelo Castello <angelo.castello@st.com>");
 	      "Angelo Castello <angelo.castello@st.com>");

+ 1 - 1
drivers/rtc/rtc-snvs.c

@@ -322,7 +322,7 @@ static int snvs_rtc_suspend(struct device *dev)
 	struct snvs_rtc_data *data = dev_get_drvdata(dev);
 	struct snvs_rtc_data *data = dev_get_drvdata(dev);
 
 
 	if (device_may_wakeup(dev))
 	if (device_may_wakeup(dev))
-		enable_irq_wake(data->irq);
+		return enable_irq_wake(data->irq);
 
 
 	return 0;
 	return 0;
 }
 }

+ 0 - 3
drivers/rtc/rtc-stk17ta8.c

@@ -23,8 +23,6 @@
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/module.h>
 
 
-#define DRV_VERSION "0.1"
-
 #define RTC_REG_SIZE		0x20000
 #define RTC_REG_SIZE		0x20000
 #define RTC_OFFSET		0x1fff0
 #define RTC_OFFSET		0x1fff0
 
 
@@ -366,4 +364,3 @@ module_platform_driver(stk17ta8_rtc_driver);
 MODULE_AUTHOR("Thomas Hommel <thomas.hommel@ge.com>");
 MODULE_AUTHOR("Thomas Hommel <thomas.hommel@ge.com>");
 MODULE_DESCRIPTION("Simtek STK17TA8 RTC driver");
 MODULE_DESCRIPTION("Simtek STK17TA8 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);

+ 6 - 1
drivers/rtc/rtc-stmp3xxx.c

@@ -107,14 +107,19 @@ static struct stmp3xxx_wdt_pdata wdt_pdata = {
 
 
 static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev)
 static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev)
 {
 {
+	int rc = -1;
 	struct platform_device *wdt_pdev =
 	struct platform_device *wdt_pdev =
 		platform_device_alloc("stmp3xxx_rtc_wdt", rtc_pdev->id);
 		platform_device_alloc("stmp3xxx_rtc_wdt", rtc_pdev->id);
 
 
 	if (wdt_pdev) {
 	if (wdt_pdev) {
 		wdt_pdev->dev.parent = &rtc_pdev->dev;
 		wdt_pdev->dev.parent = &rtc_pdev->dev;
 		wdt_pdev->dev.platform_data = &wdt_pdata;
 		wdt_pdev->dev.platform_data = &wdt_pdata;
-		platform_device_add(wdt_pdev);
+		rc = platform_device_add(wdt_pdev);
 	}
 	}
+
+	if (rc)
+		dev_err(&rtc_pdev->dev,
+			"failed to register stmp3xxx_rtc_wdt\n");
 }
 }
 #else
 #else
 static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev)
 static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev)

+ 1 - 1
drivers/rtc/rtc-tps6586x.c

@@ -344,7 +344,7 @@ static struct platform_driver tps6586x_rtc_driver = {
 };
 };
 module_platform_driver(tps6586x_rtc_driver);
 module_platform_driver(tps6586x_rtc_driver);
 
 
-MODULE_ALIAS("platform:rtc-tps6586x");
+MODULE_ALIAS("platform:tps6586x-rtc");
 MODULE_DESCRIPTION("TI TPS6586x RTC driver");
 MODULE_DESCRIPTION("TI TPS6586x RTC driver");
 MODULE_AUTHOR("Laxman dewangan <ldewangan@nvidia.com>");
 MODULE_AUTHOR("Laxman dewangan <ldewangan@nvidia.com>");
 MODULE_LICENSE("GPL v2");
 MODULE_LICENSE("GPL v2");

+ 0 - 5
drivers/rtc/rtc-x1205.c

@@ -24,8 +24,6 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/bitops.h>
 
 
-#define DRV_VERSION "1.0.8"
-
 /* offsets into CCR area */
 /* offsets into CCR area */
 
 
 #define CCR_SEC			0
 #define CCR_SEC			0
@@ -634,8 +632,6 @@ static int x1205_probe(struct i2c_client *client,
 	if (x1205_validate_client(client) < 0)
 	if (x1205_validate_client(client) < 0)
 		return -ENODEV;
 		return -ENODEV;
 
 
-	dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
-
 	rtc = devm_rtc_device_register(&client->dev, x1205_driver.driver.name,
 	rtc = devm_rtc_device_register(&client->dev, x1205_driver.driver.name,
 					&x1205_rtc_ops, THIS_MODULE);
 					&x1205_rtc_ops, THIS_MODULE);
 
 
@@ -693,4 +689,3 @@ MODULE_AUTHOR(
 	"Alessandro Zummo <a.zummo@towertech.it>");
 	"Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_DESCRIPTION("Xicor/Intersil X1205 RTC driver");
 MODULE_DESCRIPTION("Xicor/Intersil X1205 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);

+ 61 - 13
drivers/rtc/rtc-zynqmp.c

@@ -45,6 +45,7 @@
 #define RTC_INT_SEC		BIT(0)
 #define RTC_INT_SEC		BIT(0)
 #define RTC_INT_ALRM		BIT(1)
 #define RTC_INT_ALRM		BIT(1)
 #define RTC_OSC_EN		BIT(24)
 #define RTC_OSC_EN		BIT(24)
+#define RTC_BATT_EN		BIT(31)
 
 
 #define RTC_CALIB_DEF		0x198233
 #define RTC_CALIB_DEF		0x198233
 #define RTC_CALIB_MASK		0x1FFFFF
 #define RTC_CALIB_MASK		0x1FFFFF
@@ -55,6 +56,7 @@ struct xlnx_rtc_dev {
 	void __iomem		*reg_base;
 	void __iomem		*reg_base;
 	int			alarm_irq;
 	int			alarm_irq;
 	int			sec_irq;
 	int			sec_irq;
+	int			calibval;
 };
 };
 
 
 static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
 static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -62,21 +64,63 @@ static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
 	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
 	unsigned long new_time;
 	unsigned long new_time;
 
 
-	new_time = rtc_tm_to_time64(tm);
+	/*
+	 * The value written will be updated after 1 sec into the
+	 * seconds read register, so we need to program time +1 sec
+	 * to get the correct time on read.
+	 */
+	new_time = rtc_tm_to_time64(tm) + 1;
 
 
 	if (new_time > RTC_SEC_MAX_VAL)
 	if (new_time > RTC_SEC_MAX_VAL)
 		return -EINVAL;
 		return -EINVAL;
 
 
+	/*
+	 * Writing into calibration register will clear the Tick Counter and
+	 * force the next second to be signaled exactly in 1 second period
+	 */
+	xrtcdev->calibval &= RTC_CALIB_MASK;
+	writel(xrtcdev->calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
+
 	writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);
 	writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);
 
 
+	/*
+	 * Clear the rtc interrupt status register after setting the
+	 * time. During a read_time function, the code should read the
+	 * RTC_INT_STATUS register and if bit 0 is still 0, it means
+	 * that one second has not elapsed yet since RTC was set and
+	 * the current time should be read from SET_TIME_READ register;
+	 * otherwise, CURRENT_TIME register is read to report the time
+	 */
+	writel(RTC_INT_SEC, xrtcdev->reg_base + RTC_INT_STS);
+
 	return 0;
 	return 0;
 }
 }
 
 
 static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
 static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
 {
+	u32 status;
+	unsigned long read_time;
 	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
 	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
 
 
-	rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
+	status = readl(xrtcdev->reg_base + RTC_INT_STS);
+
+	if (status & RTC_INT_SEC) {
+		/*
+		 * RTC has updated the CURRENT_TIME with the time written into
+		 * SET_TIME_WRITE register.
+		 */
+		rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
+	} else {
+		/*
+		 * Time written in SET_TIME_WRITE has not yet updated into
+		 * the seconds read register, so read the time from the
+		 * SET_TIME_WRITE instead of CURRENT_TIME register.
+		 * Since we add +1 sec while writing, we need to -1 sec while
+		 * reading.
+		 */
+		read_time = readl(xrtcdev->reg_base + RTC_SET_TM_RD) - 1;
+		rtc_time64_to_tm(read_time, tm);
+	}
 
 
 	return rtc_valid_tm(tm);
 	return rtc_valid_tm(tm);
 }
 }
@@ -120,16 +164,23 @@ static int xlnx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	return 0;
 	return 0;
 }
 }
 
 
-static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev, u32 calibval)
+static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev)
 {
 {
+	u32 rtc_ctrl;
+
+	/* Enable RTC switch to battery when VCC_PSAUX is not available */
+	rtc_ctrl = readl(xrtcdev->reg_base + RTC_CTRL);
+	rtc_ctrl |= RTC_BATT_EN;
+	writel(rtc_ctrl, xrtcdev->reg_base + RTC_CTRL);
+
 	/*
 	/*
 	 * Based on crystal freq of 33.330 KHz
 	 * Based on crystal freq of 33.330 KHz
 	 * set the seconds counter and enable, set fractions counter
 	 * set the seconds counter and enable, set fractions counter
 	 * to default value suggested as per design spec
 	 * to default value suggested as per design spec
 	 * to correct RTC delay in frequency over period of time.
 	 * to correct RTC delay in frequency over period of time.
 	 */
 	 */
-	calibval &= RTC_CALIB_MASK;
-	writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
+	xrtcdev->calibval &= RTC_CALIB_MASK;
+	writel(xrtcdev->calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
 }
 }
 
 
 static const struct rtc_class_ops xlnx_rtc_ops = {
 static const struct rtc_class_ops xlnx_rtc_ops = {
@@ -150,11 +201,9 @@ static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)
 	if (!(status & (RTC_INT_SEC | RTC_INT_ALRM)))
 	if (!(status & (RTC_INT_SEC | RTC_INT_ALRM)))
 		return IRQ_NONE;
 		return IRQ_NONE;
 
 
-	/* Clear interrupt */
-	writel(status, xrtcdev->reg_base + RTC_INT_STS);
+	/* Clear RTC_INT_ALRM interrupt only */
+	writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_STS);
 
 
-	if (status & RTC_INT_SEC)
-		rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_UF);
 	if (status & RTC_INT_ALRM)
 	if (status & RTC_INT_ALRM)
 		rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF);
 		rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF);
 
 
@@ -166,7 +215,6 @@ static int xlnx_rtc_probe(struct platform_device *pdev)
 	struct xlnx_rtc_dev *xrtcdev;
 	struct xlnx_rtc_dev *xrtcdev;
 	struct resource *res;
 	struct resource *res;
 	int ret;
 	int ret;
-	unsigned int calibvalue;
 
 
 	xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL);
 	xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL);
 	if (!xrtcdev)
 	if (!xrtcdev)
@@ -207,11 +255,11 @@ static int xlnx_rtc_probe(struct platform_device *pdev)
 	}
 	}
 
 
 	ret = of_property_read_u32(pdev->dev.of_node, "calibration",
 	ret = of_property_read_u32(pdev->dev.of_node, "calibration",
-				   &calibvalue);
+				   &xrtcdev->calibval);
 	if (ret)
 	if (ret)
-		calibvalue = RTC_CALIB_DEF;
+		xrtcdev->calibval = RTC_CALIB_DEF;
 
 
-	xlnx_init_rtc(xrtcdev, calibvalue);
+	xlnx_init_rtc(xrtcdev);
 
 
 	device_init_wakeup(&pdev->dev, 1);
 	device_init_wakeup(&pdev->dev, 1);