summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-class-rtc16
-rw-r--r--Documentation/devicetree/bindings/rtc/isil,isl12026.txt28
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/parisc/kernel/time.c2
-rw-r--r--drivers/char/rtc.c83
-rw-r--r--drivers/rtc/Kconfig13
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/class.c77
-rw-r--r--drivers/rtc/hctosys.c5
-rw-r--r--drivers/rtc/interface.c107
-rw-r--r--drivers/rtc/nvmem.c29
-rw-r--r--drivers/rtc/rtc-88pm80x.c4
-rw-r--r--drivers/rtc/rtc-88pm860x.c4
-rw-r--r--drivers/rtc/rtc-ab-b5ze-s3.c4
-rw-r--r--drivers/rtc/rtc-ab3100.c2
-rw-r--r--drivers/rtc/rtc-ab8500.c57
-rw-r--r--drivers/rtc/rtc-abx80x.c6
-rw-r--r--drivers/rtc/rtc-ac100.c26
-rw-r--r--drivers/rtc/rtc-at91sam9.c1
-rw-r--r--drivers/rtc/rtc-au1xxx.c2
-rw-r--r--drivers/rtc/rtc-bq32k.c8
-rw-r--r--drivers/rtc/rtc-brcmstb-waketimer.c3
-rw-r--r--drivers/rtc/rtc-cmos.c87
-rw-r--r--drivers/rtc/rtc-coh901331.c2
-rw-r--r--drivers/rtc/rtc-core.h8
-rw-r--r--drivers/rtc/rtc-cpcap.c2
-rw-r--r--drivers/rtc/rtc-cros-ec.c8
-rw-r--r--drivers/rtc/rtc-da9052.c3
-rw-r--r--drivers/rtc/rtc-da9055.c2
-rw-r--r--drivers/rtc/rtc-da9063.c2
-rw-r--r--drivers/rtc/rtc-ds1216.c2
-rw-r--r--drivers/rtc/rtc-ds1286.c2
-rw-r--r--drivers/rtc/rtc-ds1302.c7
-rw-r--r--drivers/rtc/rtc-ds1305.c24
-rw-r--r--drivers/rtc/rtc-ds1307.c32
-rw-r--r--drivers/rtc/rtc-ds1343.c185
-rw-r--r--drivers/rtc/rtc-ds1347.c2
-rw-r--r--drivers/rtc/rtc-ds1390.c2
-rw-r--r--drivers/rtc/rtc-ds1511.c26
-rw-r--r--drivers/rtc/rtc-ds1553.c78
-rw-r--r--drivers/rtc/rtc-ds1685.c2
-rw-r--r--drivers/rtc/rtc-ds1742.c75
-rw-r--r--drivers/rtc/rtc-ds2404.c2
-rw-r--r--drivers/rtc/rtc-ds3232.c2
-rw-r--r--drivers/rtc/rtc-efi.c2
-rw-r--r--drivers/rtc/rtc-fm3130.c3
-rw-r--r--drivers/rtc/rtc-goldfish.c2
-rw-r--r--drivers/rtc/rtc-isl12022.c20
-rw-r--r--drivers/rtc/rtc-isl12026.c501
-rw-r--r--drivers/rtc/rtc-isl1208.c47
-rw-r--r--drivers/rtc/rtc-jz4740.c2
-rw-r--r--drivers/rtc/rtc-lib.c8
-rw-r--r--drivers/rtc/rtc-lpc24xx.c2
-rw-r--r--drivers/rtc/rtc-lpc32xx.c2
-rw-r--r--drivers/rtc/rtc-ls1x.c2
-rw-r--r--drivers/rtc/rtc-m41t80.c42
-rw-r--r--drivers/rtc/rtc-m41t93.c2
-rw-r--r--drivers/rtc/rtc-m41t94.c3
-rw-r--r--drivers/rtc/rtc-m48t35.c2
-rw-r--r--drivers/rtc/rtc-m48t59.c61
-rw-r--r--drivers/rtc/rtc-m48t86.c25
-rw-r--r--drivers/rtc/rtc-max6900.c19
-rw-r--r--drivers/rtc/rtc-max6902.c2
-rw-r--r--drivers/rtc/rtc-max6916.c2
-rw-r--r--drivers/rtc/rtc-max77686.c4
-rw-r--r--drivers/rtc/rtc-max8997.c2
-rw-r--r--drivers/rtc/rtc-max8998.c2
-rw-r--r--drivers/rtc/rtc-mc13xxx.c2
-rw-r--r--drivers/rtc/rtc-mcp795.c4
-rw-r--r--drivers/rtc/rtc-mpc5121.c2
-rw-r--r--drivers/rtc/rtc-mrst.c4
-rw-r--r--drivers/rtc/rtc-msm6242.c2
-rw-r--r--drivers/rtc/rtc-mt7622.c3
-rw-r--r--drivers/rtc/rtc-mv.c14
-rw-r--r--drivers/rtc/rtc-mxc_v2.c2
-rw-r--r--drivers/rtc/rtc-nuc900.c14
-rw-r--r--drivers/rtc/rtc-omap.c6
-rw-r--r--drivers/rtc/rtc-pcap.c2
-rw-r--r--drivers/rtc/rtc-pcf2123.c2
-rw-r--r--drivers/rtc/rtc-pcf2127.c2
-rw-r--r--drivers/rtc/rtc-pcf50633.c2
-rw-r--r--drivers/rtc/rtc-pcf85063.c20
-rw-r--r--drivers/rtc/rtc-pcf8523.c2
-rw-r--r--drivers/rtc/rtc-pcf85363.c205
-rw-r--r--drivers/rtc/rtc-pic32.c2
-rw-r--r--drivers/rtc/rtc-pm8xxx.c55
-rw-r--r--drivers/rtc/rtc-ps3.c2
-rw-r--r--drivers/rtc/rtc-r7301.c2
-rw-r--r--drivers/rtc/rtc-r9701.c2
-rw-r--r--drivers/rtc/rtc-rk808.c25
-rw-r--r--drivers/rtc/rtc-rp5c01.c67
-rw-r--r--drivers/rtc/rtc-rs5c348.c5
-rw-r--r--drivers/rtc/rtc-rs5c372.c24
-rw-r--r--drivers/rtc/rtc-rv8803.c33
-rw-r--r--drivers/rtc/rtc-rx4581.c6
-rw-r--r--drivers/rtc/rtc-rx6110.c2
-rw-r--r--drivers/rtc/rtc-rx8010.c2
-rw-r--r--drivers/rtc/rtc-rx8025.c2
-rw-r--r--drivers/rtc/rtc-rx8581.c6
-rw-r--r--drivers/rtc/rtc-s35390a.c38
-rw-r--r--drivers/rtc/rtc-s3c.c2
-rw-r--r--drivers/rtc/rtc-s5m.c27
-rw-r--r--drivers/rtc/rtc-sc27xx.c2
-rw-r--r--drivers/rtc/rtc-sh.c2
-rw-r--r--drivers/rtc/rtc-sirfsoc.c18
-rw-r--r--drivers/rtc/rtc-snvs.c15
-rw-r--r--drivers/rtc/rtc-spear.c12
-rw-r--r--drivers/rtc/rtc-st-lpc.c16
-rw-r--r--drivers/rtc/rtc-starfire.c2
-rw-r--r--drivers/rtc/rtc-stk17ta8.c74
-rw-r--r--drivers/rtc/rtc-sun6i.c2
-rw-r--r--drivers/rtc/rtc-sunxi.c2
-rw-r--r--drivers/rtc/rtc-sysfs.c12
-rw-r--r--drivers/rtc/rtc-tegra.c4
-rw-r--r--drivers/rtc/rtc-tps6586x.c2
-rw-r--r--drivers/rtc/rtc-tx4939.c95
-rw-r--r--drivers/rtc/rtc-wm831x.c2
-rw-r--r--drivers/rtc/rtc-xgene.c2
-rw-r--r--drivers/rtc/rtc-zynqmp.c2
-rw-r--r--drivers/rtc/systohc.c2
-rw-r--r--include/linux/mfd/samsung/rtc.h11
-rw-r--r--include/linux/rtc.h29
-rw-r--r--include/trace/events/rtc.h206
123 files changed, 1810 insertions, 1084 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-rtc b/Documentation/ABI/testing/sysfs-class-rtc
index cf60412..9598428 100644
--- a/Documentation/ABI/testing/sysfs-class-rtc
+++ b/Documentation/ABI/testing/sysfs-class-rtc
@@ -43,6 +43,14 @@ Contact: linux-rtc@vger.kernel.org
Description:
(RO) The name of the RTC corresponding to this sysfs directory
+What: /sys/class/rtc/rtcX/range
+Date: January 2018
+KernelVersion: 4.16
+Contact: linux-rtc@vger.kernel.org
+Description:
+ Valid time range for the RTC, as seconds from epoch, formatted
+ as [min, max]
+
What: /sys/class/rtc/rtcX/since_epoch
Date: March 2006
KernelVersion: 2.6.17
@@ -57,14 +65,6 @@ Contact: linux-rtc@vger.kernel.org
Description:
(RO) RTC-provided time in 24-hour notation (hh:mm:ss)
-What: /sys/class/rtc/rtcX/*/nvmem
-Date: February 2016
-KernelVersion: 4.6
-Contact: linux-rtc@vger.kernel.org
-Description:
- (RW) The non volatile storage exported as a raw file, as
- described in Documentation/nvmem/nvmem.txt
-
What: /sys/class/rtc/rtcX/offset
Date: February 2016
KernelVersion: 4.6
diff --git a/Documentation/devicetree/bindings/rtc/isil,isl12026.txt b/Documentation/devicetree/bindings/rtc/isil,isl12026.txt
new file mode 100644
index 0000000..2e0be45
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/isil,isl12026.txt
@@ -0,0 +1,28 @@
+ISL12026 I2C RTC/EEPROM
+
+ISL12026 is an I2C RTC/EEPROM combination device. The RTC and control
+registers respond at bus address 0x6f, and the EEPROM array responds
+at bus address 0x57. The canonical "reg" value will be for the RTC portion.
+
+Required properties supported by the device:
+
+ - "compatible": must be "isil,isl12026"
+ - "reg": I2C bus address of the device (always 0x6f)
+
+Optional properties:
+
+ - "isil,pwr-bsw": If present PWR.BSW bit must be set to the specified
+ value for proper operation.
+
+ - "isil,pwr-sbib": If present PWR.SBIB bit must be set to the specified
+ value for proper operation.
+
+
+Example:
+
+ rtc@6f {
+ compatible = "isil,isl12026";
+ reg = <0x6f>;
+ isil,pwr-bsw = <0>;
+ isil,pwr-sbib = <1>;
+ }
diff --git a/MAINTAINERS b/MAINTAINERS
index 6d296bd..dd7ce917 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11810,7 +11810,7 @@ X: kernel/torture.c
REAL TIME CLOCK (RTC) SUBSYSTEM
M: Alessandro Zummo <a.zummo@towertech.it>
-M: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+M: Alexandre Belloni <alexandre.belloni@bootlin.com>
L: linux-rtc@vger.kernel.org
Q: http://patchwork.ozlabs.org/project/rtc-linux/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index f7e6845..c383040 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -174,7 +174,7 @@ static int rtc_generic_get_time(struct device *dev, struct rtc_time *tm)
/* we treat tod_sec as unsigned, so this can work until year 2106 */
rtc_time64_to_tm(tod_data.tod_sec, tm);
- return rtc_valid_tm(tm);
+ return 0;
}
static int rtc_generic_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 0c858d0..57dc546 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -809,89 +809,6 @@ static __poll_t rtc_poll(struct file *file, poll_table *wait)
}
#endif
-int rtc_register(rtc_task_t *task)
-{
-#ifndef RTC_IRQ
- return -EIO;
-#else
- if (task == NULL || task->func == NULL)
- return -EINVAL;
- spin_lock_irq(&rtc_lock);
- if (rtc_status & RTC_IS_OPEN) {
- spin_unlock_irq(&rtc_lock);
- return -EBUSY;
- }
- spin_lock(&rtc_task_lock);
- if (rtc_callback) {
- spin_unlock(&rtc_task_lock);
- spin_unlock_irq(&rtc_lock);
- return -EBUSY;
- }
- rtc_status |= RTC_IS_OPEN;
- rtc_callback = task;
- spin_unlock(&rtc_task_lock);
- spin_unlock_irq(&rtc_lock);
- return 0;
-#endif
-}
-EXPORT_SYMBOL(rtc_register);
-
-int rtc_unregister(rtc_task_t *task)
-{
-#ifndef RTC_IRQ
- return -EIO;
-#else
- unsigned char tmp;
-
- spin_lock_irq(&rtc_lock);
- spin_lock(&rtc_task_lock);
- if (rtc_callback != task) {
- spin_unlock(&rtc_task_lock);
- spin_unlock_irq(&rtc_lock);
- return -ENXIO;
- }
- rtc_callback = NULL;
-
- /* disable controls */
- if (!hpet_mask_rtc_irq_bit(RTC_PIE | RTC_AIE | RTC_UIE)) {
- tmp = CMOS_READ(RTC_CONTROL);
- tmp &= ~RTC_PIE;
- tmp &= ~RTC_AIE;
- tmp &= ~RTC_UIE;
- CMOS_WRITE(tmp, RTC_CONTROL);
- CMOS_READ(RTC_INTR_FLAGS);
- }
- if (rtc_status & RTC_TIMER_ON) {
- rtc_status &= ~RTC_TIMER_ON;
- del_timer(&rtc_irq_timer);
- }
- rtc_status &= ~RTC_IS_OPEN;
- spin_unlock(&rtc_task_lock);
- spin_unlock_irq(&rtc_lock);
- return 0;
-#endif
-}
-EXPORT_SYMBOL(rtc_unregister);
-
-int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg)
-{
-#ifndef RTC_IRQ
- return -EIO;
-#else
- unsigned long flags;
- if (cmd != RTC_PIE_ON && cmd != RTC_PIE_OFF && cmd != RTC_IRQP_SET)
- return -EINVAL;
- spin_lock_irqsave(&rtc_task_lock, flags);
- if (rtc_callback != task) {
- spin_unlock_irqrestore(&rtc_task_lock, flags);
- return -ENXIO;
- }
- spin_unlock_irqrestore(&rtc_task_lock, flags);
- return rtc_do_ioctl(cmd, arg, 1);
-#endif
-}
-EXPORT_SYMBOL(rtc_control);
-
/*
* The various file operations we support.
*/
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 319e3c8..59e6ded 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -407,6 +407,16 @@ config RTC_DRV_ISL12022
This driver can also be built as a module. If so, the module
will be called rtc-isl12022.
+config RTC_DRV_ISL12026
+ tristate "Intersil ISL12026"
+ depends on OF || COMPILE_TEST
+ help
+ If you say yes here you get support for the
+ Intersil ISL12026 RTC chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-isl12026.
+
config RTC_DRV_X1205
tristate "Xicor/Intersil X1205"
help
@@ -1413,6 +1423,7 @@ config RTC_DRV_AT91RM9200
config RTC_DRV_AT91SAM9
tristate "AT91SAM9 RTT as RTC"
depends on ARCH_AT91 || COMPILE_TEST
+ depends on HAS_IOMEM
select MFD_SYSCON
help
Some AT91SAM9 SoCs provide an RTT (Real Time Timer) block which
@@ -1502,7 +1513,7 @@ config RTC_DRV_STARFIRE
config RTC_DRV_TX4939
tristate "TX4939 SoC"
- depends on SOC_TX4939
+ depends on SOC_TX4939 || COMPILE_TEST
help
Driver for the internal RTC (Realtime Clock) module found on
Toshiba TX4939 SoC.
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index ee0206b..5ff2fc0 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -75,6 +75,7 @@ obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o
obj-$(CONFIG_RTC_DRV_HYM8563) += rtc-hym8563.o
obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o
obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o
+obj-$(CONFIG_RTC_DRV_ISL12026) += rtc-isl12026.o
obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o
obj-$(CONFIG_RTC_DRV_LP8788) += rtc-lp8788.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 722d683..d37588f 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -211,6 +211,73 @@ static int rtc_device_get_id(struct device *dev)
return id;
}
+static void rtc_device_get_offset(struct rtc_device *rtc)
+{
+ time64_t range_secs;
+ u32 start_year;
+ int ret;
+
+ /*
+ * If RTC driver did not implement the range of RTC hardware device,
+ * then we can not expand the RTC range by adding or subtracting one
+ * offset.
+ */
+ if (rtc->range_min == rtc->range_max)
+ return;
+
+ ret = device_property_read_u32(rtc->dev.parent, "start-year",
+ &start_year);
+ if (!ret) {
+ rtc->start_secs = mktime64(start_year, 1, 1, 0, 0, 0);
+ rtc->set_start_time = true;
+ }
+
+ /*
+ * If user did not implement the start time for RTC driver, then no
+ * need to expand the RTC range.
+ */
+ if (!rtc->set_start_time)
+ return;
+
+ range_secs = rtc->range_max - rtc->range_min + 1;
+
+ /*
+ * If the start_secs is larger than the maximum seconds (rtc->range_max)
+ * supported by RTC hardware or the maximum seconds of new expanded
+ * range (start_secs + rtc->range_max - rtc->range_min) is less than
+ * rtc->range_min, which means the minimum seconds (rtc->range_min) of
+ * RTC hardware will be mapped to start_secs by adding one offset, so
+ * the offset seconds calculation formula should be:
+ * rtc->offset_secs = rtc->start_secs - rtc->range_min;
+ *
+ * If the start_secs is larger than the minimum seconds (rtc->range_min)
+ * supported by RTC hardware, then there is one region is overlapped
+ * between the original RTC hardware range and the new expanded range,
+ * and this overlapped region do not need to be mapped into the new
+ * expanded range due to it is valid for RTC device. So the minimum
+ * seconds of RTC hardware (rtc->range_min) should be mapped to
+ * rtc->range_max + 1, then the offset seconds formula should be:
+ * rtc->offset_secs = rtc->range_max - rtc->range_min + 1;
+ *
+ * If the start_secs is less than the minimum seconds (rtc->range_min),
+ * which is similar to case 2. So the start_secs should be mapped to
+ * start_secs + rtc->range_max - rtc->range_min + 1, then the
+ * offset seconds formula should be:
+ * rtc->offset_secs = -(rtc->range_max - rtc->range_min + 1);
+ *
+ * Otherwise the offset seconds should be 0.
+ */
+ if (rtc->start_secs > rtc->range_max ||
+ rtc->start_secs + range_secs - 1 < rtc->range_min)
+ rtc->offset_secs = rtc->start_secs - rtc->range_min;
+ else if (rtc->start_secs > rtc->range_min)
+ rtc->offset_secs = range_secs;
+ else if (rtc->start_secs < rtc->range_min)
+ rtc->offset_secs = -range_secs;
+ else
+ rtc->offset_secs = 0;
+}
+
/**
* rtc_device_register - register w/ RTC class
* @dev: the device to register
@@ -247,6 +314,8 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
dev_set_name(&rtc->dev, "rtc%d", id);
+ rtc_device_get_offset(rtc);
+
/* Check to see if there is an ALARM already set in hw */
err = __rtc_read_alarm(rtc, &alrm);
@@ -293,8 +362,6 @@ EXPORT_SYMBOL_GPL(rtc_device_register);
*/
void rtc_device_unregister(struct rtc_device *rtc)
{
- rtc_nvmem_unregister(rtc);
-
mutex_lock(&rtc->ops_lock);
/*
* Remove innards of this RTC, then disable it, before
@@ -312,6 +379,7 @@ static void devm_rtc_device_release(struct device *dev, void *res)
{
struct rtc_device *rtc = *(struct rtc_device **)res;
+ rtc_nvmem_unregister(rtc);
rtc_device_unregister(rtc);
}
@@ -382,6 +450,8 @@ static void devm_rtc_release_device(struct device *dev, void *res)
{
struct rtc_device *rtc = *(struct rtc_device **)res;
+ rtc_nvmem_unregister(rtc);
+
if (rtc->registered)
rtc_device_unregister(rtc);
else
@@ -435,6 +505,7 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc)
return -EINVAL;
rtc->owner = owner;
+ rtc_device_get_offset(rtc);
/* Check to see if there is an ALARM already set in hw */
err = __rtc_read_alarm(rtc, &alrm);
@@ -453,8 +524,6 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc)
rtc_proc_add_device(rtc);
- rtc_nvmem_register(rtc);
-
rtc->registered = true;
dev_info(rtc->dev.parent, "registered as %s\n",
dev_name(&rtc->dev));
diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c
index e1cfa06..e79f2a1 100644
--- a/drivers/rtc/hctosys.c
+++ b/drivers/rtc/hctosys.c
@@ -49,6 +49,11 @@ static int __init rtc_hctosys(void)
tv64.tv_sec = rtc_tm_to_time64(&tm);
+#if BITS_PER_LONG == 32
+ if (tv64.tv_sec > INT_MAX)
+ goto err_read;
+#endif
+
err = do_settimeofday64(&tv64);
dev_info(rtc->dev.parent,
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 672b192..7cbdc92 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -17,9 +17,73 @@
#include <linux/log2.h>
#include <linux/workqueue.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/rtc.h>
+
static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer);
static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer);
+static void rtc_add_offset(struct rtc_device *rtc, struct rtc_time *tm)
+{
+ time64_t secs;
+
+ if (!rtc->offset_secs)
+ return;
+
+ secs = rtc_tm_to_time64(tm);
+
+ /*
+ * Since the reading time values from RTC device are always in the RTC
+ * original valid range, but we need to skip the overlapped region
+ * between expanded range and original range, which is no need to add
+ * the offset.
+ */
+ if ((rtc->start_secs > rtc->range_min && secs >= rtc->start_secs) ||
+ (rtc->start_secs < rtc->range_min &&
+ secs <= (rtc->start_secs + rtc->range_max - rtc->range_min)))
+ return;
+
+ rtc_time64_to_tm(secs + rtc->offset_secs, tm);
+}
+
+static void rtc_subtract_offset(struct rtc_device *rtc, struct rtc_time *tm)
+{
+ time64_t secs;
+
+ if (!rtc->offset_secs)
+ return;
+
+ secs = rtc_tm_to_time64(tm);
+
+ /*
+ * If the setting time values are in the valid range of RTC hardware
+ * device, then no need to subtract the offset when setting time to RTC
+ * device. Otherwise we need to subtract the offset to make the time
+ * values are valid for RTC hardware device.
+ */
+ if (secs >= rtc->range_min && secs <= rtc->range_max)
+ return;
+
+ rtc_time64_to_tm(secs - rtc->offset_secs, tm);
+}
+
+static int rtc_valid_range(struct rtc_device *rtc, struct rtc_time *tm)
+{
+ if (rtc->range_min != rtc->range_max) {
+ time64_t time = rtc_tm_to_time64(tm);
+ time64_t range_min = rtc->set_start_time ? rtc->start_secs :
+ rtc->range_min;
+ time64_t range_max = rtc->set_start_time ?
+ (rtc->start_secs + rtc->range_max - rtc->range_min) :
+ rtc->range_max;
+
+ if (time < range_min || time > range_max)
+ return -ERANGE;
+ }
+
+ return 0;
+}
+
static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
{
int err;
@@ -36,6 +100,8 @@ static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
return err;
}
+ rtc_add_offset(rtc, tm);
+
err = rtc_valid_tm(tm);
if (err < 0)
dev_dbg(&rtc->dev, "read_time: rtc_time isn't valid\n");
@@ -53,6 +119,8 @@ int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
err = __rtc_read_time(rtc, tm);
mutex_unlock(&rtc->ops_lock);
+
+ trace_rtc_read_time(rtc_tm_to_time64(tm), err);
return err;
}
EXPORT_SYMBOL_GPL(rtc_read_time);
@@ -65,6 +133,12 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
if (err != 0)
return err;
+ err = rtc_valid_range(rtc, tm);
+ if (err)
+ return err;
+
+ rtc_subtract_offset(rtc, tm);
+
err = mutex_lock_interruptible(&rtc->ops_lock);
if (err)
return err;
@@ -87,6 +161,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
mutex_unlock(&rtc->ops_lock);
/* A timer might have just expired */
schedule_work(&rtc->irqwork);
+
+ trace_rtc_set_time(rtc_tm_to_time64(tm), err);
return err;
}
EXPORT_SYMBOL_GPL(rtc_set_time);
@@ -119,6 +195,8 @@ static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *al
}
mutex_unlock(&rtc->ops_lock);
+
+ trace_rtc_read_alarm(rtc_tm_to_time64(&alarm->time), err);
return err;
}
@@ -316,6 +394,7 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
}
mutex_unlock(&rtc->ops_lock);
+ trace_rtc_read_alarm(rtc_tm_to_time64(&alarm->time), err);
return err;
}
EXPORT_SYMBOL_GPL(rtc_read_alarm);
@@ -329,6 +408,8 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
err = rtc_valid_tm(&alarm->time);
if (err)
return err;
+
+ rtc_subtract_offset(rtc, &alarm->time);
scheduled = rtc_tm_to_time64(&alarm->time);
/* Make sure we're not setting alarms in the past */
@@ -352,6 +433,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
else
err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
+ trace_rtc_set_alarm(rtc_tm_to_time64(&alarm->time), err);
return err;
}
@@ -363,6 +445,10 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
if (err != 0)
return err;
+ err = rtc_valid_range(rtc, &alarm->time);
+ if (err)
+ return err;
+
err = mutex_lock_interruptible(&rtc->ops_lock);
if (err)
return err;
@@ -375,6 +461,8 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
err = rtc_timer_enqueue(rtc, &rtc->aie_timer);
mutex_unlock(&rtc->ops_lock);
+
+ rtc_add_offset(rtc, &alarm->time);
return err;
}
EXPORT_SYMBOL_GPL(rtc_set_alarm);
@@ -406,6 +494,7 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
rtc->aie_timer.enabled = 1;
timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node);
+ trace_rtc_timer_enqueue(&rtc->aie_timer);
}
mutex_unlock(&rtc->ops_lock);
return err;
@@ -435,6 +524,8 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled)
err = rtc->ops->alarm_irq_enable(rtc->dev.parent, enabled);
mutex_unlock(&rtc->ops_lock);
+
+ trace_rtc_alarm_irq_enable(enabled, err);
return err;
}
EXPORT_SYMBOL_GPL(rtc_alarm_irq_enable);
@@ -709,6 +800,8 @@ retry:
rtc->pie_enabled = enabled;
}
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
+
+ trace_rtc_irq_set_state(enabled, err);
return err;
}
EXPORT_SYMBOL_GPL(rtc_irq_set_state);
@@ -745,6 +838,8 @@ retry:
}
}
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
+
+ trace_rtc_irq_set_freq(freq, err);
return err;
}
EXPORT_SYMBOL_GPL(rtc_irq_set_freq);
@@ -779,6 +874,7 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
}
timerqueue_add(&rtc->timerqueue, &timer->node);
+ trace_rtc_timer_enqueue(timer);
if (!next || ktime_before(timer->node.expires, next->expires)) {
struct rtc_wkalrm alarm;
int err;
@@ -790,6 +886,7 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
schedule_work(&rtc->irqwork);
} else if (err) {
timerqueue_del(&rtc->timerqueue, &timer->node);
+ trace_rtc_timer_dequeue(timer);
timer->enabled = 0;
return err;
}
@@ -803,6 +900,7 @@ static void rtc_alarm_disable(struct rtc_device *rtc)
return;
rtc->ops->alarm_irq_enable(rtc->dev.parent, false);
+ trace_rtc_alarm_irq_enable(0, 0);
}
/**
@@ -821,6 +919,7 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer)
{
struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue);
timerqueue_del(&rtc->timerqueue, &timer->node);
+ trace_rtc_timer_dequeue(timer);
timer->enabled = 0;
if (next == &timer->node) {
struct rtc_wkalrm alarm;
@@ -871,16 +970,19 @@ again:
/* expire timer */
timer = container_of(next, struct rtc_timer, node);
timerqueue_del(&rtc->timerqueue, &timer->node);
+ trace_rtc_timer_dequeue(timer);
timer->enabled = 0;
if (timer->task.func)
timer->task.func(timer->task.private_data);
+ trace_rtc_timer_fired(timer);
/* Re-add/fwd periodic timers */
if (ktime_to_ns(timer->period)) {
timer->node.expires = ktime_add(timer->node.expires,
timer->period);
timer->enabled = 1;
timerqueue_add(&rtc->timerqueue, &timer->node);
+ trace_rtc_timer_enqueue(timer);
}
}
@@ -902,6 +1004,7 @@ reprogram:
timer = container_of(next, struct rtc_timer, node);
timerqueue_del(&rtc->timerqueue, &timer->node);
+ trace_rtc_timer_dequeue(timer);
timer->enabled = 0;
dev_err(&rtc->dev, "__rtc_set_alarm: err=%d\n", err);
goto again;
@@ -992,6 +1095,8 @@ int rtc_read_offset(struct rtc_device *rtc, long *offset)
mutex_lock(&rtc->ops_lock);
ret = rtc->ops->read_offset(rtc->dev.parent, offset);
mutex_unlock(&rtc->ops_lock);
+
+ trace_rtc_read_offset(*offset, ret);
return ret;
}
@@ -1025,5 +1130,7 @@ int rtc_set_offset(struct rtc_device *rtc, long offset)
mutex_lock(&rtc->ops_lock);
ret = rtc->ops->set_offset(rtc->dev.parent, offset);
mutex_unlock(&rtc->ops_lock);
+
+ trace_rtc_set_offset(offset, ret);
return ret;
}
diff --git a/drivers/rtc/nvmem.c b/drivers/rtc/nvmem.c
index 8567b4e..17ec4c8d 100644
--- a/drivers/rtc/nvmem.c
+++ b/drivers/rtc/nvmem.c
@@ -14,8 +14,6 @@
#include <linux/rtc.h>
#include <linux/sysfs.h>
-#include "rtc-core.h"
-
/*
* Deprecated ABI compatibility, this should be removed at some point
*/
@@ -46,7 +44,7 @@ rtc_nvram_write(struct file *filp, struct kobject *kobj,
return nvmem_device_write(rtc->nvmem, off, count, buf);
}
-static int rtc_nvram_register(struct rtc_device *rtc)
+static int rtc_nvram_register(struct rtc_device *rtc, size_t size)
{
int err;
@@ -64,7 +62,7 @@ static int rtc_nvram_register(struct rtc_device *rtc)
rtc->nvram->read = rtc_nvram_read;
rtc->nvram->write = rtc_nvram_write;
- rtc->nvram->size = rtc->nvmem_config->size;
+ rtc->nvram->size = size;
err = sysfs_create_bin_file(&rtc->dev.parent->kobj,
rtc->nvram);
@@ -84,21 +82,28 @@ static void rtc_nvram_unregister(struct rtc_device *rtc)
/*
* New ABI, uses nvmem
*/
-void rtc_nvmem_register(struct rtc_device *rtc)
+int rtc_nvmem_register(struct rtc_device *rtc,
+ struct nvmem_config *nvmem_config)
{
- if (!rtc->nvmem_config)
- return;
+ if (!IS_ERR_OR_NULL(rtc->nvmem))
+ return -EBUSY;
+
+ if (!nvmem_config)
+ return -ENODEV;
- rtc->nvmem_config->dev = &rtc->dev;
- rtc->nvmem_config->owner = rtc->owner;
- rtc->nvmem = nvmem_register(rtc->nvmem_config);
+ nvmem_config->dev = rtc->dev.parent;
+ nvmem_config->owner = rtc->owner;
+ rtc->nvmem = nvmem_register(nvmem_config);
if (IS_ERR_OR_NULL(rtc->nvmem))
- return;
+ return PTR_ERR(rtc->nvmem);
/* Register the old ABI */
if (rtc->nvram_old_abi)
- rtc_nvram_register(rtc);
+ rtc_nvram_register(rtc, nvmem_config->size);
+
+ return 0;
}
+EXPORT_SYMBOL_GPL(rtc_nvmem_register);
void rtc_nvmem_unregister(struct rtc_device *rtc)
{
diff --git a/drivers/rtc/rtc-88pm80x.c b/drivers/rtc/rtc-88pm80x.c
index 466bf7f..6cbafef 100644
--- a/drivers/rtc/rtc-88pm80x.c
+++ b/drivers/rtc/rtc-88pm80x.c
@@ -134,9 +134,9 @@ static int pm80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
struct pm80x_rtc_info *info = dev_get_drvdata(dev);
unsigned char buf[4];
unsigned long ticks, base, data;
- if ((tm->tm_year < 70) || (tm->tm_year > 138)) {
+ if (tm->tm_year > 206) {
dev_dbg(info->dev,
- "Set time %d out of range. Please set time between 1970 to 2038.\n",
+ "Set time %d out of range. Please set time between 1970 to 2106.\n",
1900 + tm->tm_year);
return -EINVAL;
}
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c
index 19e53b3..01ffc0e 100644
--- a/drivers/rtc/rtc-88pm860x.c
+++ b/drivers/rtc/rtc-88pm860x.c
@@ -135,9 +135,9 @@ static int pm860x_rtc_set_time(struct device *dev, struct rtc_time *tm)
unsigned char buf[4];
unsigned long ticks, base, data;
- if ((tm->tm_year < 70) || (tm->tm_year > 138)) {
+ if (tm->tm_year > 206) {
dev_dbg(info->dev, "Set time %d out of range. "
- "Please set time between 1970 to 2038.\n",
+ "Please set time between 1970 to 2106.\n",
1900 + tm->tm_year);
return -EINVAL;
}
diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c
index ef5c16d..8dc4519 100644
--- a/drivers/rtc/rtc-ab-b5ze-s3.c
+++ b/drivers/rtc/rtc-ab-b5ze-s3.c
@@ -217,7 +217,7 @@ static int _abb5zes3_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct abb5zes3_rtc_data *data = dev_get_drvdata(dev);
u8 regs[ABB5ZES3_REG_RTC_SC + ABB5ZES3_RTC_SEC_LEN];
- int ret;
+ int ret = 0;
/*
* As we need to read CTRL1 register anyway to access 24/12h
@@ -255,8 +255,6 @@ static int _abb5zes3_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_mon = bcd2bin(regs[ABB5ZES3_REG_RTC_MO]) - 1; /* starts at 1 */
tm->tm_year = bcd2bin(regs[ABB5ZES3_REG_RTC_YR]) + 100;
- ret = rtc_valid_tm(tm);
-
err:
return ret;
}
diff --git a/drivers/rtc/rtc-ab3100.c b/drivers/rtc/rtc-ab3100.c
index 9b725c5..821ff52 100644
--- a/drivers/rtc/rtc-ab3100.c
+++ b/drivers/rtc/rtc-ab3100.c
@@ -106,7 +106,7 @@ static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm)
rtc_time64_to_tm(time, tm);
- return rtc_valid_tm(tm);
+ return 0;
}
static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c
index 24a0af6..e28f440 100644
--- a/drivers/rtc/rtc-ab8500.c
+++ b/drivers/rtc/rtc-ab8500.c
@@ -36,10 +36,6 @@
#define AB8500_RTC_FORCE_BKUP_REG 0x0D
#define AB8500_RTC_CALIB_REG 0x0E
#define AB8500_RTC_SWITCH_STAT_REG 0x0F
-#define AB8540_RTC_ALRM_SEC 0x22
-#define AB8540_RTC_ALRM_MIN_LOW_REG 0x23
-#define AB8540_RTC_ALRM_MIN_MID_REG 0x24
-#define AB8540_RTC_ALRM_MIN_HI_REG 0x25
/* RtcReadRequest bits */
#define RTC_READ_REQUEST 0x01
@@ -63,11 +59,6 @@ static const u8 ab8500_rtc_alarm_regs[] = {
AB8500_RTC_ALRM_MIN_LOW_REG
};
-static const u8 ab8540_rtc_alarm_regs[] = {
- AB8540_RTC_ALRM_MIN_HI_REG, AB8540_RTC_ALRM_MIN_MID_REG,
- AB8540_RTC_ALRM_MIN_LOW_REG, AB8540_RTC_ALRM_SEC
-};
-
/* Calculate the seconds from 1970 to 01-01-2000 00:00:00 */
static unsigned long get_elapsed_seconds(int year)
{
@@ -131,7 +122,7 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
secs += get_elapsed_seconds(AB8500_RTC_EPOCH);
rtc_time_to_tm(secs, tm);
- return rtc_valid_tm(tm);
+ return 0;
}
static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -277,43 +268,6 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
return ab8500_rtc_irq_enable(dev, alarm->enabled);
}
-static int ab8540_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
- int retval, i;
- unsigned char buf[ARRAY_SIZE(ab8540_rtc_alarm_regs)];
- unsigned long mins, secs = 0;
-
- if (alarm->time.tm_year < (AB8500_RTC_EPOCH - 1900)) {
- dev_dbg(dev, "year should be equal to or greater than %d\n",
- AB8500_RTC_EPOCH);
- return -EINVAL;
- }
-
- /* Get the number of seconds since 1970 */
- rtc_tm_to_time(&alarm->time, &secs);
-
- /*
- * Convert it to the number of seconds since 01-01-2000 00:00:00
- */
- secs -= get_elapsed_seconds(AB8500_RTC_EPOCH);
- mins = secs / 60;
-
- buf[3] = secs % 60;
- buf[2] = mins & 0xFF;
- buf[1] = (mins >> 8) & 0xFF;
- buf[0] = (mins >> 16) & 0xFF;
-
- /* Set the alarm time */
- for (i = 0; i < ARRAY_SIZE(ab8540_rtc_alarm_regs); i++) {
- retval = abx500_set_register_interruptible(dev, AB8500_RTC,
- ab8540_rtc_alarm_regs[i], buf[i]);
- if (retval < 0)
- return retval;
- }
-
- return ab8500_rtc_irq_enable(dev, alarm->enabled);
-}
-
static int ab8500_rtc_set_calibration(struct device *dev, int calibration)
{
int retval;
@@ -435,17 +389,8 @@ static const struct rtc_class_ops ab8500_rtc_ops = {
.alarm_irq_enable = ab8500_rtc_irq_enable,
};
-static const struct rtc_class_ops ab8540_rtc_ops = {
- .read_time = ab8500_rtc_read_time,
- .set_time = ab8500_rtc_set_time,
- .read_alarm = ab8500_rtc_read_alarm,
- .set_alarm = ab8540_rtc_set_alarm,
- .alarm_irq_enable = ab8500_rtc_irq_enable,
-};
-
static const struct platform_device_id ab85xx_rtc_ids[] = {
{ "ab8500-rtc", (kernel_ulong_t)&ab8500_rtc_ops, },
- { "ab8540-rtc", (kernel_ulong_t)&ab8540_rtc_ops, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, ab85xx_rtc_ids);
diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c
index b033bc5..2cefa67 100644
--- a/drivers/rtc/rtc-abx80x.c
+++ b/drivers/rtc/rtc-abx80x.c
@@ -172,11 +172,7 @@ static int abx80x_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_mon = bcd2bin(buf[ABX8XX_REG_MO] & 0x1F) - 1;
tm->tm_year = bcd2bin(buf[ABX8XX_REG_YR]) + 100;
- err = rtc_valid_tm(tm);
- if (err < 0)
- dev_err(&client->dev, "retrieved date/time is not valid.\n");
-
- return err;
+ return 0;
}
static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-ac100.c b/drivers/rtc/rtc-ac100.c
index 8ff9dc3..3fe576f 100644
--- a/drivers/rtc/rtc-ac100.c
+++ b/drivers/rtc/rtc-ac100.c
@@ -183,7 +183,29 @@ static int ac100_clkout_determine_rate(struct clk_hw *hw,
for (i = 0; i < num_parents; i++) {
struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i);
- unsigned long tmp, prate = clk_hw_get_rate(parent);
+ unsigned long tmp, prate;
+
+ /*
+ * The clock has two parents, one is a fixed clock which is
+ * internally registered by the ac100 driver. The other parent
+ * is a clock from the codec side of the chip, which we
+ * properly declare and reference in the devicetree and is
+ * not implemented in any driver right now.
+ * If the clock core looks for the parent of that second
+ * missing clock, it can't find one that is registered and
+ * returns NULL.
+ * So we end up in a situation where clk_hw_get_num_parents
+ * returns the amount of clocks we can be parented to, but
+ * clk_hw_get_parent_by_index will not return the orphan
+ * clocks.
+ * Thus we need to check if the parent exists before
+ * we get the parent rate, so we could use the RTC
+ * without waiting for the codec to be supported.
+ */
+ if (!parent)
+ continue;
+
+ prate = clk_hw_get_rate(parent);
tmp = ac100_clkout_round_rate(hw, req->rate, prate);
@@ -387,7 +409,7 @@ static int ac100_rtc_get_time(struct device *dev, struct rtc_time *rtc_tm)
rtc_tm->tm_year = bcd2bin(reg[6] & AC100_RTC_YEA_MASK) +
AC100_YEAR_OFF;
- return rtc_valid_tm(rtc_tm);
+ return 0;
}
static int ac100_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm)
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index 7418a76..ee71e64 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -349,6 +349,7 @@ static const struct rtc_class_ops at91_rtc_ops = {
};
static const struct regmap_config gpbr_regmap_config = {
+ .name = "gpbr",
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c
index 2ba44cc..7c5530c 100644
--- a/drivers/rtc/rtc-au1xxx.c
+++ b/drivers/rtc/rtc-au1xxx.c
@@ -36,7 +36,7 @@ static int au1xtoy_rtc_read_time(struct device *dev, struct rtc_time *tm)
rtc_time_to_tm(t, tm);
- return rtc_valid_tm(tm);
+ return 0;
}
static int au1xtoy_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c
index 98ac8d5..ef52741 100644
--- a/drivers/rtc/rtc-bq32k.c
+++ b/drivers/rtc/rtc-bq32k.c
@@ -36,6 +36,10 @@
#define BQ32K_CFG2 0x09 /* Trickle charger control */
#define BQ32K_TCFE BIT(6) /* Trickle charge FET bypass */
+#define MAX_LEN 10 /* Maximum number of consecutive
+ * register for this particular RTC.
+ */
+
struct bq32k_regs {
uint8_t seconds;
uint8_t minutes;
@@ -74,7 +78,7 @@ static int bq32k_read(struct device *dev, void *data, uint8_t off, uint8_t len)
static int bq32k_write(struct device *dev, void *data, uint8_t off, uint8_t len)
{
struct i2c_client *client = to_i2c_client(dev);
- uint8_t buffer[len + 1];
+ uint8_t buffer[MAX_LEN + 1];
buffer[0] = off;
memcpy(&buffer[1], data, len);
@@ -110,7 +114,7 @@ static int bq32k_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_year = bcd2bin(regs.years) +
((regs.cent_hours & BQ32K_CENT) ? 100 : 0);
- return rtc_valid_tm(tm);
+ return 0;
}
static int bq32k_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-brcmstb-waketimer.c b/drivers/rtc/rtc-brcmstb-waketimer.c
index 6cee612..bdd6674 100644
--- a/drivers/rtc/rtc-brcmstb-waketimer.c
+++ b/drivers/rtc/rtc-brcmstb-waketimer.c
@@ -60,6 +60,9 @@ static void brcmstb_waketmr_set_alarm(struct brcmstb_waketmr *timer,
{
brcmstb_waketmr_clear_alarm(timer);
+ /* Make sure we are actually counting in seconds */
+ writel_relaxed(timer->rate, timer->base + BRCMSTB_WKTMR_PRESCALER);
+
writel_relaxed(secs + 1, timer->base + BRCMSTB_WKTMR_ALARM);
}
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index f7c0f72..1b3738a 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -541,11 +541,10 @@ static const struct rtc_class_ops cmos_rtc_ops = {
#define NVRAM_OFFSET (RTC_REG_D + 1)
-static ssize_t
-cmos_nvram_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
+static int cmos_nvram_read(void *priv, unsigned int off, void *val,
+ size_t count)
{
+ unsigned char *buf = val;
int retval;
off += NVRAM_OFFSET;
@@ -563,16 +562,13 @@ cmos_nvram_read(struct file *filp, struct kobject *kobj,
return retval;
}
-static ssize_t
-cmos_nvram_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
+static int cmos_nvram_write(void *priv, unsigned int off, void *val,
+ size_t count)
{
- struct cmos_rtc *cmos;
+ struct cmos_rtc *cmos = priv;
+ unsigned char *buf = val;
int retval;
- cmos = dev_get_drvdata(container_of(kobj, struct device, kobj));
-
/* NOTE: on at least PCs and Ataris, the boot firmware uses a
* checksum on part of the NVRAM data. That's currently ignored
* here. If userspace is smart enough to know what fields of
@@ -598,17 +594,6 @@ cmos_nvram_write(struct file *filp, struct kobject *kobj,
return retval;
}
-static struct bin_attribute nvram = {
- .attr = {
- .name = "nvram",
- .mode = S_IRUGO | S_IWUSR,
- },
-
- .read = cmos_nvram_read,
- .write = cmos_nvram_write,
- /* size gets set up later */
-};
-
/*----------------------------------------------------------------*/
static struct cmos_rtc cmos_rtc;
@@ -675,6 +660,14 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
unsigned char rtc_control;
unsigned address_space;
u32 flags = 0;
+ struct nvmem_config nvmem_cfg = {
+ .name = "cmos_nvram",
+ .word_size = 1,
+ .stride = 1,
+ .reg_read = cmos_nvram_read,
+ .reg_write = cmos_nvram_write,
+ .priv = &cmos_rtc,
+ };
/* there can be only one ... */
if (cmos_rtc.dev)
@@ -751,8 +744,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
cmos_rtc.dev = dev;
dev_set_drvdata(dev, &cmos_rtc);
- cmos_rtc.rtc = rtc_device_register(driver_name, dev,
- &cmos_rtc_ops, THIS_MODULE);
+ cmos_rtc.rtc = devm_rtc_allocate_device(dev);
if (IS_ERR(cmos_rtc.rtc)) {
retval = PTR_ERR(cmos_rtc.rtc);
goto cleanup0;
@@ -814,22 +806,25 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
}
}
- /* export at least the first block of NVRAM */
- nvram.size = address_space - NVRAM_OFFSET;
- retval = sysfs_create_bin_file(&dev->kobj, &nvram);
- if (retval < 0) {
- dev_dbg(dev, "can't create nvram file? %d\n", retval);
+ cmos_rtc.rtc->ops = &cmos_rtc_ops;
+ cmos_rtc.rtc->nvram_old_abi = true;
+ retval = rtc_register_device(cmos_rtc.rtc);
+ if (retval)
goto cleanup2;
- }
- dev_info(dev, "%s%s, %zd bytes nvram%s\n",
- !is_valid_irq(rtc_irq) ? "no alarms" :
- cmos_rtc.mon_alrm ? "alarms up to one year" :
- cmos_rtc.day_alrm ? "alarms up to one month" :
- "alarms up to one day",
- cmos_rtc.century ? ", y3k" : "",
- nvram.size,
- is_hpet_enabled() ? ", hpet irqs" : "");
+ /* export at least the first block of NVRAM */
+ nvmem_cfg.size = address_space - NVRAM_OFFSET;
+ if (rtc_nvmem_register(cmos_rtc.rtc, &nvmem_cfg))
+ dev_err(dev, "nvmem registration failed\n");
+
+ dev_info(dev, "%s%s, %d bytes nvram%s\n",
+ !is_valid_irq(rtc_irq) ? "no alarms" :
+ cmos_rtc.mon_alrm ? "alarms up to one year" :
+ cmos_rtc.day_alrm ? "alarms up to one month" :
+ "alarms up to one day",
+ cmos_rtc.century ? ", y3k" : "",
+ nvmem_cfg.size,
+ is_hpet_enabled() ? ", hpet irqs" : "");
return 0;
@@ -838,7 +833,6 @@ cleanup2:
free_irq(rtc_irq, cmos_rtc.rtc);
cleanup1:
cmos_rtc.dev = NULL;
- rtc_device_unregister(cmos_rtc.rtc);
cleanup0:
if (RTC_IOMAPPED)
release_region(ports->start, resource_size(ports));
@@ -862,14 +856,11 @@ static void cmos_do_remove(struct device *dev)
cmos_do_shutdown(cmos->irq);
- sysfs_remove_bin_file(&dev->kobj, &nvram);
-
if (is_valid_irq(cmos->irq)) {
free_irq(cmos->irq, cmos->rtc);
hpet_unregister_irq_handler(cmos_interrupt);
}
- rtc_device_unregister(cmos->rtc);
cmos->rtc = NULL;
ports = cmos->iomem;
@@ -1271,8 +1262,6 @@ MODULE_DEVICE_TABLE(of, of_cmos_match);
static __init void cmos_of_init(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
- struct rtc_time time;
- int ret;
const __be32 *val;
if (!node)
@@ -1285,16 +1274,6 @@ static __init void cmos_of_init(struct platform_device *pdev)
val = of_get_property(node, "freq-reg", NULL);
if (val)
CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT);
-
- cmos_read_time(&pdev->dev, &time);
- ret = rtc_valid_tm(&time);
- if (ret) {
- struct rtc_time def_time = {
- .tm_year = 1,
- .tm_mday = 1,
- };
- cmos_set_time(&pdev->dev, &def_time);
- }
}
#else
static inline void cmos_of_init(struct platform_device *pdev) {}
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c
index cfc4141..2fc5174 100644
--- a/drivers/rtc/rtc-coh901331.c
+++ b/drivers/rtc/rtc-coh901331.c
@@ -82,7 +82,7 @@ static int coh901331_read_time(struct device *dev, struct rtc_time *tm)
if (readl(rtap->virtbase + COH901331_VALID)) {
rtc_time_to_tm(readl(rtap->virtbase + COH901331_CUR_TIME), tm);
clk_disable(rtap->clk);
- return rtc_valid_tm(tm);
+ return 0;
}
clk_disable(rtap->clk);
return -EINVAL;
diff --git a/drivers/rtc/rtc-core.h b/drivers/rtc/rtc-core.h
index 513b9be..0abf989 100644
--- a/drivers/rtc/rtc-core.h
+++ b/drivers/rtc/rtc-core.h
@@ -46,11 +46,3 @@ static inline const struct attribute_group **rtc_get_dev_attribute_groups(void)
return NULL;
}
#endif
-
-#ifdef CONFIG_RTC_NVMEM
-void rtc_nvmem_register(struct rtc_device *rtc);
-void rtc_nvmem_unregister(struct rtc_device *rtc);
-#else
-static inline void rtc_nvmem_register(struct rtc_device *rtc) {}
-static inline void rtc_nvmem_unregister(struct rtc_device *rtc) {}
-#endif
diff --git a/drivers/rtc/rtc-cpcap.c b/drivers/rtc/rtc-cpcap.c
index 3a0333e..a8856f2 100644
--- a/drivers/rtc/rtc-cpcap.c
+++ b/drivers/rtc/rtc-cpcap.c
@@ -119,7 +119,7 @@ static int cpcap_rtc_read_time(struct device *dev, struct rtc_time *tm)
cpcap2rtc_time(tm, &cpcap_tm);
- return rtc_valid_tm(tm);
+ return 0;
}
static int cpcap_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-cros-ec.c b/drivers/rtc/rtc-cros-ec.c
index f0ea689..bf7ced0 100644
--- a/drivers/rtc/rtc-cros-ec.c
+++ b/drivers/rtc/rtc-cros-ec.c
@@ -197,10 +197,10 @@ static int cros_ec_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
cros_ec_rtc->saved_alarm = (u32)alarm_time;
} else {
/* Don't set an alarm in the past. */
- if ((u32)alarm_time < current_time)
- alarm_offset = EC_RTC_ALARM_CLEAR;
- else
- alarm_offset = (u32)alarm_time - current_time;
+ if ((u32)alarm_time <= current_time)
+ return -ETIME;
+
+ alarm_offset = (u32)alarm_time - current_time;
}
ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM, alarm_offset);
diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c
index 4273377..03044e1 100644
--- a/drivers/rtc/rtc-da9052.c
+++ b/drivers/rtc/rtc-da9052.c
@@ -187,8 +187,7 @@ static int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
rtc_tm->tm_min = v[0][1] & DA9052_RTC_MIN;
rtc_tm->tm_sec = v[0][0] & DA9052_RTC_SEC;
- ret = rtc_valid_tm(rtc_tm);
- return ret;
+ return 0;
}
idx = (1-idx);
diff --git a/drivers/rtc/rtc-da9055.c b/drivers/rtc/rtc-da9055.c
index 678af86..e08cd81 100644
--- a/drivers/rtc/rtc-da9055.c
+++ b/drivers/rtc/rtc-da9055.c
@@ -158,7 +158,7 @@ static int da9055_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
rtc_tm->tm_min = v[1] & DA9055_RTC_MIN;
rtc_tm->tm_sec = v[0] & DA9055_RTC_SEC;
- return rtc_valid_tm(rtc_tm);
+ return 0;
}
static int da9055_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c
index f85cae2..b4e054c 100644
--- a/drivers/rtc/rtc-da9063.c
+++ b/drivers/rtc/rtc-da9063.c
@@ -256,7 +256,7 @@ static int da9063_rtc_read_time(struct device *dev, struct rtc_time *tm)
else
rtc->rtc_sync = false;
- return rtc_valid_tm(tm);
+ return 0;
}
static int da9063_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-ds1216.c b/drivers/rtc/rtc-ds1216.c
index 9c82b1d..5f15871 100644
--- a/drivers/rtc/rtc-ds1216.c
+++ b/drivers/rtc/rtc-ds1216.c
@@ -99,7 +99,7 @@ static int ds1216_rtc_read_time(struct device *dev, struct rtc_time *tm)
if (tm->tm_year < 70)
tm->tm_year += 100;
- return rtc_valid_tm(tm);
+ return 0;
}
static int ds1216_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c
index ef75c34..0744916 100644
--- a/drivers/rtc/rtc-ds1286.c
+++ b/drivers/rtc/rtc-ds1286.c
@@ -211,7 +211,7 @@ static int ds1286_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_mon--;
- return rtc_valid_tm(tm);
+ return 0;
}
static int ds1286_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c
index 0ec4be6..2a88115 100644
--- a/drivers/rtc/rtc-ds1302.c
+++ b/drivers/rtc/rtc-ds1302.c
@@ -43,7 +43,7 @@ static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *time)
{
struct spi_device *spi = dev_get_drvdata(dev);
u8 buf[1 + RTC_CLCK_LEN];
- u8 *bp = buf;
+ u8 *bp;
int status;
/* Enable writing */
@@ -98,8 +98,7 @@ static int ds1302_rtc_get_time(struct device *dev, struct rtc_time *time)
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);
+ return 0;
}
static const struct rtc_class_ops ds1302_rtc_ops = {
@@ -112,7 +111,7 @@ static int ds1302_probe(struct spi_device *spi)
struct rtc_device *rtc;
u8 addr;
u8 buf[4];
- u8 *bp = buf;
+ u8 *bp;
int status;
/* Sanity check board setup data. This may be hooked up
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c
index d8df2e9..2d502fc 100644
--- a/drivers/rtc/rtc-ds1305.c
+++ b/drivers/rtc/rtc-ds1305.c
@@ -203,8 +203,7 @@ static int ds1305_get_time(struct device *dev, struct rtc_time *time)
time->tm_hour, time->tm_mday,
time->tm_mon, time->tm_year, time->tm_wday);
- /* Time may not be set */
- return rtc_valid_tm(time);
+ return 0;
}
static int ds1305_set_time(struct device *dev, struct rtc_time *time)
@@ -544,15 +543,6 @@ static int ds1305_nvram_write(void *priv, unsigned int off, void *buf,
return spi_sync(spi, &m);
}
-static struct nvmem_config ds1305_nvmem_cfg = {
- .name = "ds1305_nvram",
- .word_size = 1,
- .stride = 1,
- .size = DS1305_NVRAM_LEN,
- .reg_read = ds1305_nvram_read,
- .reg_write = ds1305_nvram_write,
-};
-
/*----------------------------------------------------------------------*/
/*
@@ -566,6 +556,14 @@ static int ds1305_probe(struct spi_device *spi)
u8 addr, value;
struct ds1305_platform_data *pdata = dev_get_platdata(&spi->dev);
bool write_ctrl = false;
+ struct nvmem_config ds1305_nvmem_cfg = {
+ .name = "ds1305_nvram",
+ .word_size = 1,
+ .stride = 1,
+ .size = DS1305_NVRAM_LEN,
+ .reg_read = ds1305_nvram_read,
+ .reg_write = ds1305_nvram_write,
+ };
/* Sanity check board setup data. This may be hooked up
* in 3wire mode, but we don't care. Note that unless
@@ -703,15 +701,15 @@ static int ds1305_probe(struct spi_device *spi)
ds1305->rtc->ops = &ds1305_ops;
ds1305_nvmem_cfg.priv = ds1305;
- ds1305->rtc->nvmem_config = &ds1305_nvmem_cfg;
ds1305->rtc->nvram_old_abi = true;
-
status = rtc_register_device(ds1305->rtc);
if (status) {
dev_dbg(&spi->dev, "register rtc --> %d\n", status);
return status;
}
+ rtc_nvmem_register(ds1305->rtc, &ds1305_nvmem_cfg);
+
/* Maybe set up alarm IRQ; be ready to handle it triggering right
* away. NOTE that we don't share this. The signal is active low,
* and we can't ack it before a SPI message delay. We temporarily
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 923dde9..a13e59e 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -114,7 +114,6 @@ enum ds_type {
# define RX8025_BIT_XST 0x20
struct ds1307 {
- struct nvmem_config nvmem_cfg;
enum ds_type type;
unsigned long flags;
#define HAS_NVRAM 0 /* bit 0 == sysfs file active */
@@ -438,8 +437,7 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
t->tm_hour, t->tm_mday,
t->tm_mon, t->tm_year, t->tm_wday);
- /* initial clock setting can be undefined */
- return rtc_valid_tm(t);
+ return 0;
}
static int ds1307_set_time(struct device *dev, struct rtc_time *t)
@@ -1696,24 +1694,26 @@ read_rtc:
}
}
- if (chip->nvram_size) {
- ds1307->nvmem_cfg.name = "ds1307_nvram";
- ds1307->nvmem_cfg.word_size = 1;
- ds1307->nvmem_cfg.stride = 1;
- ds1307->nvmem_cfg.size = chip->nvram_size;
- ds1307->nvmem_cfg.reg_read = ds1307_nvram_read;
- ds1307->nvmem_cfg.reg_write = ds1307_nvram_write;
- ds1307->nvmem_cfg.priv = ds1307;
-
- ds1307->rtc->nvmem_config = &ds1307->nvmem_cfg;
- ds1307->rtc->nvram_old_abi = true;
- }
-
ds1307->rtc->ops = chip->rtc_ops ?: &ds13xx_rtc_ops;
err = rtc_register_device(ds1307->rtc);
if (err)
return err;
+ if (chip->nvram_size) {
+ struct nvmem_config nvmem_cfg = {
+ .name = "ds1307_nvram",
+ .word_size = 1,
+ .stride = 1,
+ .size = chip->nvram_size,
+ .reg_read = ds1307_nvram_read,
+ .reg_write = ds1307_nvram_write,
+ .priv = ds1307,
+ };
+
+ ds1307->rtc->nvram_old_abi = true;
+ rtc_nvmem_register(ds1307->rtc, &nvmem_cfg);
+ }
+
ds1307_hwmon_register(ds1307);
ds1307_clks_register(ds1307);
diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index 895fbee..5208da4 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -153,120 +153,22 @@ static ssize_t ds1343_store_glitchfilter(struct device *dev,
static DEVICE_ATTR(glitch_filter, S_IRUGO | S_IWUSR, ds1343_show_glitchfilter,
ds1343_store_glitchfilter);
-static ssize_t ds1343_nvram_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
+static int ds1343_nvram_write(void *priv, unsigned int off, void *val,
+ size_t bytes)
{
- int ret;
- unsigned char address;
- struct device *dev = kobj_to_dev(kobj);
- struct ds1343_priv *priv = dev_get_drvdata(dev);
-
- address = DS1343_NVRAM + off;
-
- ret = regmap_bulk_write(priv->map, address, buf, count);
- if (ret < 0)
- dev_err(&priv->spi->dev, "Error in nvram write %d", ret);
+ struct ds1343_priv *ds1343 = priv;
- return (ret < 0) ? ret : count;
+ return regmap_bulk_write(ds1343->map, DS1343_NVRAM + off, val, bytes);
}
-
-static ssize_t ds1343_nvram_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
+static int ds1343_nvram_read(void *priv, unsigned int off, void *val,
+ size_t bytes)
{
- int ret;
- unsigned char address;
- struct device *dev = kobj_to_dev(kobj);
- struct ds1343_priv *priv = dev_get_drvdata(dev);
+ struct ds1343_priv *ds1343 = priv;
- address = DS1343_NVRAM + off;
-
- ret = regmap_bulk_read(priv->map, address, buf, count);
- if (ret < 0)
- dev_err(&priv->spi->dev, "Error in nvram read %d\n", ret);
-
- return (ret < 0) ? ret : count;
+ return regmap_bulk_read(ds1343->map, DS1343_NVRAM + off, val, bytes);
}
-
-static struct bin_attribute nvram_attr = {
- .attr.name = "nvram",
- .attr.mode = S_IRUGO | S_IWUSR,
- .read = ds1343_nvram_read,
- .write = ds1343_nvram_write,
- .size = DS1343_NVRAM_LEN,
-};
-
-static ssize_t ds1343_show_alarmstatus(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct ds1343_priv *priv = dev_get_drvdata(dev);
- int alarmstatus, data;
-
- regmap_read(priv->map, DS1343_CONTROL_REG, &data);
-
- alarmstatus = !!(data & DS1343_A0IE);
-
- if (alarmstatus)
- return sprintf(buf, "enabled\n");
- else
- return sprintf(buf, "disabled\n");
-}
-
-static DEVICE_ATTR(alarm_status, S_IRUGO, ds1343_show_alarmstatus, NULL);
-
-static ssize_t ds1343_show_alarmmode(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct ds1343_priv *priv = dev_get_drvdata(dev);
- int alarm_mode, data;
- char *alarm_str;
-
- regmap_read(priv->map, DS1343_ALM0_SEC_REG, &data);
- alarm_mode = (data & 0x80) >> 4;
-
- regmap_read(priv->map, DS1343_ALM0_MIN_REG, &data);
- alarm_mode |= (data & 0x80) >> 5;
-
- regmap_read(priv->map, DS1343_ALM0_HOUR_REG, &data);
- alarm_mode |= (data & 0x80) >> 6;
-
- regmap_read(priv->map, DS1343_ALM0_DAY_REG, &data);
- alarm_mode |= (data & 0x80) >> 7;
-
- switch (alarm_mode) {
- case 15:
- alarm_str = "each second";
- break;
-
- case 7:
- alarm_str = "seconds match";
- break;
-
- case 3:
- alarm_str = "minutes and seconds match";
- break;
-
- case 1:
- alarm_str = "hours, minutes and seconds match";
- break;
-
- case 0:
- alarm_str = "day, hours, minutes and seconds match";
- break;
-
- default:
- alarm_str = "invalid";
- break;
- }
-
- return sprintf(buf, "%s\n", alarm_str);
-}
-
-static DEVICE_ATTR(alarm_mode, S_IRUGO, ds1343_show_alarmmode, NULL);
-
static ssize_t ds1343_show_tricklecharger(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -313,7 +215,6 @@ static DEVICE_ATTR(trickle_charger, S_IRUGO, ds1343_show_tricklecharger, NULL);
static int ds1343_sysfs_register(struct device *dev)
{
- struct ds1343_priv *priv = dev_get_drvdata(dev);
int err;
err = device_create_file(dev, &dev_attr_glitch_filter);
@@ -321,33 +222,9 @@ static int ds1343_sysfs_register(struct device *dev)
return err;
err = device_create_file(dev, &dev_attr_trickle_charger);
- if (err)
- goto error1;
-
- err = device_create_bin_file(dev, &nvram_attr);
- if (err)
- goto error2;
-
- if (priv->irq <= 0)
- return err;
-
- err = device_create_file(dev, &dev_attr_alarm_mode);
- if (err)
- goto error3;
-
- err = device_create_file(dev, &dev_attr_alarm_status);
if (!err)
- return err;
+ return 0;
- device_remove_file(dev, &dev_attr_alarm_mode);
-
-error3:
- device_remove_bin_file(dev, &nvram_attr);
-
-error2:
- device_remove_file(dev, &dev_attr_trickle_charger);
-
-error1:
device_remove_file(dev, &dev_attr_glitch_filter);
return err;
@@ -355,17 +232,8 @@ error1:
static void ds1343_sysfs_unregister(struct device *dev)
{
- struct ds1343_priv *priv = dev_get_drvdata(dev);
-
device_remove_file(dev, &dev_attr_glitch_filter);
device_remove_file(dev, &dev_attr_trickle_charger);
- device_remove_bin_file(dev, &nvram_attr);
-
- if (priv->irq <= 0)
- return;
-
- device_remove_file(dev, &dev_attr_alarm_status);
- device_remove_file(dev, &dev_attr_alarm_mode);
}
static int ds1343_read_time(struct device *dev, struct rtc_time *dt)
@@ -386,7 +254,7 @@ static int ds1343_read_time(struct device *dev, struct rtc_time *dt)
dt->tm_mon = bcd2bin(buf[5] & 0x1F) - 1;
dt->tm_year = bcd2bin(buf[6]) + 100; /* year offset from 1900 */
- return rtc_valid_tm(dt);
+ return 0;
}
static int ds1343_set_time(struct device *dev, struct rtc_time *dt)
@@ -599,14 +467,18 @@ static const struct rtc_class_ops ds1343_rtc_ops = {
static int ds1343_probe(struct spi_device *spi)
{
struct ds1343_priv *priv;
- struct regmap_config config;
+ struct regmap_config config = { .reg_bits = 8, .val_bits = 8,
+ .write_flag_mask = 0x80, };
unsigned int data;
int res;
-
- memset(&config, 0, sizeof(config));
- config.reg_bits = 8;
- config.val_bits = 8;
- config.write_flag_mask = 0x80;
+ struct nvmem_config nvmem_cfg = {
+ .name = "ds1343-",
+ .word_size = 1,
+ .stride = 1,
+ .size = DS1343_NVRAM_LEN,
+ .reg_read = ds1343_nvram_read,
+ .reg_write = ds1343_nvram_write,
+ };
priv = devm_kzalloc(&spi->dev, sizeof(struct ds1343_priv), GFP_KERNEL);
if (!priv)
@@ -646,12 +518,19 @@ static int ds1343_probe(struct spi_device *spi)
data &= ~(DS1343_OSF | DS1343_IRQF1 | DS1343_IRQF0);
regmap_write(priv->map, DS1343_STATUS_REG, data);
- priv->rtc = devm_rtc_device_register(&spi->dev, "ds1343",
- &ds1343_rtc_ops, THIS_MODULE);
- if (IS_ERR(priv->rtc)) {
- dev_err(&spi->dev, "unable to register rtc ds1343\n");
+ priv->rtc = devm_rtc_allocate_device(&spi->dev);
+ if (IS_ERR(priv->rtc))
return PTR_ERR(priv->rtc);
- }
+
+ priv->rtc->nvram_old_abi = true;
+ priv->rtc->ops = &ds1343_rtc_ops;
+
+ res = rtc_register_device(priv->rtc);
+ if (res)
+ return res;
+
+ nvmem_cfg.priv = priv;
+ rtc_nvmem_register(priv->rtc, &nvmem_cfg);
priv->irq = spi->irq;
diff --git a/drivers/rtc/rtc-ds1347.c b/drivers/rtc/rtc-ds1347.c
index ccfc9d4..938512c 100644
--- a/drivers/rtc/rtc-ds1347.c
+++ b/drivers/rtc/rtc-ds1347.c
@@ -66,7 +66,7 @@ static int ds1347_read_time(struct device *dev, struct rtc_time *dt)
dt->tm_wday = bcd2bin(buf[5]) - 1;
dt->tm_year = bcd2bin(buf[6]) + 100;
- return rtc_valid_tm(dt);
+ return 0;
}
static int ds1347_set_time(struct device *dev, struct rtc_time *dt)
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c
index 4d5b007..3b09540 100644
--- a/drivers/rtc/rtc-ds1390.c
+++ b/drivers/rtc/rtc-ds1390.c
@@ -153,7 +153,7 @@ static int ds1390_read_time(struct device *dev, struct rtc_time *dt)
/* adjust for century bit */
dt->tm_year = bcd2bin(chip->txrx_buf[6]) + ((chip->txrx_buf[5] & 0x80) ? 100 : 0);
- return rtc_valid_tm(dt);
+ return 0;
}
static int ds1390_set_time(struct device *dev, struct rtc_time *dt)
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c
index 1e95312..a7d5ca42 100644
--- a/drivers/rtc/rtc-ds1511.c
+++ b/drivers/rtc/rtc-ds1511.c
@@ -277,10 +277,6 @@ static int ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
rtc_tm->tm_mon--;
- if (rtc_valid_tm(rtc_tm) < 0) {
- dev_err(dev, "retrieved date/time is not valid.\n");
- rtc_time_to_tm(0, rtc_tm);
- }
return 0;
}
@@ -422,20 +418,20 @@ static int ds1511_nvram_write(void *priv, unsigned int pos, void *buf,
return 0;
}
-static struct nvmem_config ds1511_nvmem_cfg = {
- .name = "ds1511_nvram",
- .word_size = 1,
- .stride = 1,
- .size = DS1511_RAM_MAX,
- .reg_read = ds1511_nvram_read,
- .reg_write = ds1511_nvram_write,
-};
-
static int ds1511_rtc_probe(struct platform_device *pdev)
{
struct resource *res;
struct rtc_plat_data *pdata;
int ret = 0;
+ struct nvmem_config ds1511_nvmem_cfg = {
+ .name = "ds1511_nvram",
+ .word_size = 1,
+ .stride = 1,
+ .size = DS1511_RAM_MAX,
+ .reg_read = ds1511_nvram_read,
+ .reg_write = ds1511_nvram_write,
+ .priv = &pdev->dev,
+ };
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@@ -478,14 +474,14 @@ static int ds1511_rtc_probe(struct platform_device *pdev)
pdata->rtc->ops = &ds1511_rtc_ops;
- ds1511_nvmem_cfg.priv = &pdev->dev;
- pdata->rtc->nvmem_config = &ds1511_nvmem_cfg;
pdata->rtc->nvram_old_abi = true;
ret = rtc_register_device(pdata->rtc);
if (ret)
return ret;
+ rtc_nvmem_register(pdata->rtc, &ds1511_nvmem_cfg);
+
/*
* if the platform has an interrupt in mind for this device,
* then by all means, set it
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index 9961ec6..2441b9a 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -127,10 +127,6 @@ static int ds1553_rtc_read_time(struct device *dev, struct rtc_time *tm)
/* year is 1900 + tm->tm_year */
tm->tm_year = bcd2bin(year) + bcd2bin(century) * 100 - 1900;
- if (rtc_valid_tm(tm) < 0) {
- dev_err(dev, "retrieved date/time is not valid.\n");
- rtc_time_to_tm(0, tm);
- }
return 0;
}
@@ -233,46 +229,32 @@ static const struct rtc_class_ops ds1553_rtc_ops = {
.alarm_irq_enable = ds1553_rtc_alarm_irq_enable,
};
-static ssize_t ds1553_nvram_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t pos, size_t size)
+static int ds1553_nvram_read(void *priv, unsigned int pos, void *val,
+ size_t bytes)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct platform_device *pdev = to_platform_device(dev);
+ struct platform_device *pdev = priv;
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr;
- ssize_t count;
+ u8 *buf = val;
- for (count = 0; count < size; count++)
+ for (; bytes; bytes--)
*buf++ = readb(ioaddr + pos++);
- return count;
+ return 0;
}
-static ssize_t ds1553_nvram_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t pos, size_t size)
+static int ds1553_nvram_write(void *priv, unsigned int pos, void *val,
+ size_t bytes)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct platform_device *pdev = to_platform_device(dev);
+ struct platform_device *pdev = priv;
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr;
- ssize_t count;
+ u8 *buf = val;
- for (count = 0; count < size; count++)
+ for (; bytes; bytes--)
writeb(*buf++, ioaddr + pos++);
- return count;
+ return 0;
}
-static struct bin_attribute ds1553_nvram_attr = {
- .attr = {
- .name = "nvram",
- .mode = S_IRUGO | S_IWUSR,
- },
- .size = RTC_OFFSET,
- .read = ds1553_nvram_read,
- .write = ds1553_nvram_write,
-};
-
static int ds1553_rtc_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -280,6 +262,15 @@ static int ds1553_rtc_probe(struct platform_device *pdev)
struct rtc_plat_data *pdata;
void __iomem *ioaddr;
int ret = 0;
+ struct nvmem_config nvmem_cfg = {
+ .name = "ds1553_nvram",
+ .word_size = 1,
+ .stride = 1,
+ .size = RTC_OFFSET,
+ .reg_read = ds1553_nvram_read,
+ .reg_write = ds1553_nvram_write,
+ .priv = pdev,
+ };
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@@ -308,11 +299,17 @@ static int ds1553_rtc_probe(struct platform_device *pdev)
pdata->last_jiffies = jiffies;
platform_set_drvdata(pdev, pdata);
- pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
- &ds1553_rtc_ops, THIS_MODULE);
+ pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(pdata->rtc))
return PTR_ERR(pdata->rtc);
+ pdata->rtc->ops = &ds1553_rtc_ops;
+ pdata->rtc->nvram_old_abi = true;
+
+ ret = rtc_register_device(pdata->rtc);
+ if (ret)
+ return ret;
+
if (pdata->irq > 0) {
writeb(0, ioaddr + RTC_INTERRUPTS);
if (devm_request_irq(&pdev->dev, pdata->irq,
@@ -323,21 +320,9 @@ static int ds1553_rtc_probe(struct platform_device *pdev)
}
}
- ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr);
- if (ret)
- dev_err(&pdev->dev, "unable to create sysfs file: %s\n",
- ds1553_nvram_attr.attr.name);
-
- return 0;
-}
-
-static int ds1553_rtc_remove(struct platform_device *pdev)
-{
- struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+ if (rtc_nvmem_register(pdata->rtc, &nvmem_cfg))
+ dev_err(&pdev->dev, "unable to register nvmem\n");
- sysfs_remove_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr);
- if (pdata->irq > 0)
- writeb(0, pdata->ioaddr + RTC_INTERRUPTS);
return 0;
}
@@ -346,7 +331,6 @@ MODULE_ALIAS("platform:rtc-ds1553");
static struct platform_driver ds1553_rtc_driver = {
.probe = ds1553_rtc_probe,
- .remove = ds1553_rtc_remove,
.driver = {
.name = "rtc-ds1553",
},
diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c
index ed43b43..1a39829 100644
--- a/drivers/rtc/rtc-ds1685.c
+++ b/drivers/rtc/rtc-ds1685.c
@@ -306,7 +306,7 @@ ds1685_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
tm->tm_isdst = 0; /* RTC has hardcoded timezone, so don't use. */
- return rtc_valid_tm(tm);
+ return 0;
}
/**
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c
index 3abf1cb..2d78118 100644
--- a/drivers/rtc/rtc-ds1742.c
+++ b/drivers/rtc/rtc-ds1742.c
@@ -53,9 +53,7 @@
struct rtc_plat_data {
void __iomem *ioaddr_nvram;
void __iomem *ioaddr_rtc;
- size_t size_nvram;
unsigned long last_jiffies;
- struct bin_attribute nvram_attr;
};
static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -114,7 +112,7 @@ static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm)
/* year is 1900 + tm->tm_year */
tm->tm_year = bcd2bin(year) + bcd2bin(century) * 100 - 1900;
- return rtc_valid_tm(tm);
+ return 0;
}
static const struct rtc_class_ops ds1742_rtc_ops = {
@@ -122,34 +120,28 @@ static const struct rtc_class_ops ds1742_rtc_ops = {
.set_time = ds1742_rtc_set_time,
};
-static ssize_t ds1742_nvram_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t pos, size_t size)
+static int ds1742_nvram_read(void *priv, unsigned int pos, void *val,
+ size_t bytes)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct platform_device *pdev = to_platform_device(dev);
- struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+ struct rtc_plat_data *pdata = priv;
void __iomem *ioaddr = pdata->ioaddr_nvram;
- ssize_t count;
+ u8 *buf = val;
- for (count = 0; count < size; count++)
+ for (; bytes; bytes--)
*buf++ = readb(ioaddr + pos++);
- return count;
+ return 0;
}
-static ssize_t ds1742_nvram_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t pos, size_t size)
+static int ds1742_nvram_write(void *priv, unsigned int pos, void *val,
+ size_t bytes)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct platform_device *pdev = to_platform_device(dev);
- struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+ struct rtc_plat_data *pdata = priv;
void __iomem *ioaddr = pdata->ioaddr_nvram;
- ssize_t count;
+ u8 *buf = val;
- for (count = 0; count < size; count++)
+ for (; bytes; bytes--)
writeb(*buf++, ioaddr + pos++);
- return count;
+ return 0;
}
static int ds1742_rtc_probe(struct platform_device *pdev)
@@ -160,6 +152,14 @@ static int ds1742_rtc_probe(struct platform_device *pdev)
struct rtc_plat_data *pdata;
void __iomem *ioaddr;
int ret = 0;
+ struct nvmem_config nvmem_cfg = {
+ .name = "ds1742_nvram",
+ .word_size = 1,
+ .stride = 1,
+ .reg_read = ds1742_nvram_read,
+ .reg_write = ds1742_nvram_write,
+ };
+
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@@ -171,15 +171,10 @@ static int ds1742_rtc_probe(struct platform_device *pdev)
return PTR_ERR(ioaddr);
pdata->ioaddr_nvram = ioaddr;
- pdata->size_nvram = resource_size(res) - RTC_SIZE;
- pdata->ioaddr_rtc = ioaddr + pdata->size_nvram;
+ pdata->ioaddr_rtc = ioaddr + resource_size(res) - RTC_SIZE;
- sysfs_bin_attr_init(&pdata->nvram_attr);
- pdata->nvram_attr.attr.name = "nvram";
- pdata->nvram_attr.attr.mode = S_IRUGO | S_IWUSR;
- pdata->nvram_attr.read = ds1742_nvram_read;
- pdata->nvram_attr.write = ds1742_nvram_write;
- pdata->nvram_attr.size = pdata->size_nvram;
+ nvmem_cfg.size = resource_size(res) - RTC_SIZE;
+ nvmem_cfg.priv = pdata;
/* turn RTC on if it was not on */
ioaddr = pdata->ioaddr_rtc;
@@ -196,24 +191,21 @@ static int ds1742_rtc_probe(struct platform_device *pdev)
pdata->last_jiffies = jiffies;
platform_set_drvdata(pdev, pdata);
- rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
- &ds1742_rtc_ops, THIS_MODULE);
+
+ rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
- ret = sysfs_create_bin_file(&pdev->dev.kobj, &pdata->nvram_attr);
- if (ret)
- dev_err(&pdev->dev, "Unable to create sysfs entry: %s\n",
- pdata->nvram_attr.attr.name);
+ rtc->ops = &ds1742_rtc_ops;
+ rtc->nvram_old_abi = true;
- return 0;
-}
+ ret = rtc_register_device(rtc);
+ if (ret)
+ return ret;
-static int ds1742_rtc_remove(struct platform_device *pdev)
-{
- struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+ if (rtc_nvmem_register(rtc, &nvmem_cfg))
+ dev_err(&pdev->dev, "Unable to register nvmem\n");
- sysfs_remove_bin_file(&pdev->dev.kobj, &pdata->nvram_attr);
return 0;
}
@@ -225,7 +217,6 @@ MODULE_DEVICE_TABLE(of, ds1742_rtc_of_match);
static struct platform_driver ds1742_rtc_driver = {
.probe = ds1742_rtc_probe,
- .remove = ds1742_rtc_remove,
.driver = {
.name = "rtc-ds1742",
.of_match_table = of_match_ptr(ds1742_rtc_of_match),
diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c
index 9a1582e..b886b6a 100644
--- a/drivers/rtc/rtc-ds2404.c
+++ b/drivers/rtc/rtc-ds2404.c
@@ -207,7 +207,7 @@ static int ds2404_read_time(struct device *dev, struct rtc_time *dt)
time = le32_to_cpu(time);
rtc_time_to_tm(time, dt);
- return rtc_valid_tm(dt);
+ return 0;
}
static int ds2404_set_mmss(struct device *dev, unsigned long secs)
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c
index 0550f7b..7184e51 100644
--- a/drivers/rtc/rtc-ds3232.c
+++ b/drivers/rtc/rtc-ds3232.c
@@ -145,7 +145,7 @@ static int ds3232_read_time(struct device *dev, struct rtc_time *time)
time->tm_year = bcd2bin(year) + add_century;
- return rtc_valid_tm(time);
+ return 0;
}
static int ds3232_set_time(struct device *dev, struct rtc_time *time)
diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c
index 0130afd..3454e78 100644
--- a/drivers/rtc/rtc-efi.c
+++ b/drivers/rtc/rtc-efi.c
@@ -176,7 +176,7 @@ static int efi_read_time(struct device *dev, struct rtc_time *tm)
if (!convert_from_efi_time(&eft, tm))
return -EIO;
- return rtc_valid_tm(tm);
+ return 0;
}
static int efi_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c
index 576eadb..e113767 100644
--- a/drivers/rtc/rtc-fm3130.c
+++ b/drivers/rtc/rtc-fm3130.c
@@ -136,8 +136,7 @@ static int fm3130_get_time(struct device *dev, struct rtc_time *t)
t->tm_hour, t->tm_mday,
t->tm_mon, t->tm_year, t->tm_wday);
- /* initial clock setting can be undefined */
- return rtc_valid_tm(t);
+ return 0;
}
diff --git a/drivers/rtc/rtc-goldfish.c b/drivers/rtc/rtc-goldfish.c
index d677692..a1c44d0 100644
--- a/drivers/rtc/rtc-goldfish.c
+++ b/drivers/rtc/rtc-goldfish.c
@@ -235,3 +235,5 @@ static struct platform_driver goldfish_rtc = {
};
module_platform_driver(goldfish_rtc);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index 38586a0..890ccfc 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -104,8 +104,9 @@ static int isl12022_write_reg(struct i2c_client *client,
* In the routines that deal directly with the isl12022 hardware, we use
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
*/
-static int isl12022_get_datetime(struct i2c_client *client, struct rtc_time *tm)
+static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
+ struct i2c_client *client = to_i2c_client(dev);
uint8_t buf[ISL12022_REG_INT + 1];
int ret;
@@ -149,11 +150,12 @@ static int isl12022_get_datetime(struct i2c_client *client, struct rtc_time *tm)
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
- return rtc_valid_tm(tm);
+ return 0;
}
-static int isl12022_set_datetime(struct i2c_client *client, struct rtc_time *tm)
+static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct isl12022 *isl12022 = i2c_get_clientdata(client);
size_t i;
int ret;
@@ -199,7 +201,7 @@ static int isl12022_set_datetime(struct i2c_client *client, struct rtc_time *tm)
return ret;
}
- isl12022->write_enabled = 1;
+ isl12022->write_enabled = true;
}
/* hours, minutes and seconds */
@@ -228,16 +230,6 @@ static int isl12022_set_datetime(struct i2c_client *client, struct rtc_time *tm)
return 0;
}
-static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- return isl12022_get_datetime(to_i2c_client(dev), tm);
-}
-
-static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- return isl12022_set_datetime(to_i2c_client(dev), tm);
-}
-
static const struct rtc_class_ops isl12022_rtc_ops = {
.read_time = isl12022_rtc_read_time,
.set_time = isl12022_rtc_set_time,
diff --git a/drivers/rtc/rtc-isl12026.c b/drivers/rtc/rtc-isl12026.c
new file mode 100644
index 0000000..97f594f
--- /dev/null
+++ b/drivers/rtc/rtc-isl12026.c
@@ -0,0 +1,501 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * An I2C driver for the Intersil ISL 12026
+ *
+ * Copyright (c) 2018 Cavium, Inc.
+ */
+#include <linux/bcd.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/rtc.h>
+#include <linux/slab.h>
+
+/* register offsets */
+#define ISL12026_REG_PWR 0x14
+# define ISL12026_REG_PWR_BSW BIT(6)
+# define ISL12026_REG_PWR_SBIB BIT(7)
+#define ISL12026_REG_SC 0x30
+#define ISL12026_REG_HR 0x32
+# define ISL12026_REG_HR_MIL BIT(7) /* military or 24 hour time */
+#define ISL12026_REG_SR 0x3f
+# define ISL12026_REG_SR_RTCF BIT(0)
+# define ISL12026_REG_SR_WEL BIT(1)
+# define ISL12026_REG_SR_RWEL BIT(2)
+# define ISL12026_REG_SR_MBZ BIT(3)
+# define ISL12026_REG_SR_OSCF BIT(4)
+
+/* The EEPROM array responds at i2c address 0x57 */
+#define ISL12026_EEPROM_ADDR 0x57
+
+#define ISL12026_PAGESIZE 16
+#define ISL12026_NVMEM_WRITE_TIME 20
+
+struct isl12026 {
+ struct rtc_device *rtc;
+ struct i2c_client *nvm_client;
+};
+
+static int isl12026_read_reg(struct i2c_client *client, int reg)
+{
+ u8 addr[] = {0, reg};
+ u8 val;
+ int ret;
+
+ struct i2c_msg msgs[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = sizeof(addr),
+ .buf = addr
+ }, {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = &val
+ }
+ };
+
+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+ if (ret != ARRAY_SIZE(msgs)) {
+ dev_err(&client->dev, "read reg error, ret=%d\n", ret);
+ ret = ret < 0 ? ret : -EIO;
+ } else {
+ ret = val;
+ }
+
+ return ret;
+}
+
+static int isl12026_arm_write(struct i2c_client *client)
+{
+ int ret;
+ u8 op[3];
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = op
+ };
+
+ /* Set SR.WEL */
+ op[0] = 0;
+ op[1] = ISL12026_REG_SR;
+ op[2] = ISL12026_REG_SR_WEL;
+ msg.len = 3;
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret != 1) {
+ dev_err(&client->dev, "write error SR.WEL, ret=%d\n", ret);
+ ret = ret < 0 ? ret : -EIO;
+ goto out;
+ }
+
+ /* Set SR.WEL and SR.RWEL */
+ op[2] = ISL12026_REG_SR_WEL | ISL12026_REG_SR_RWEL;
+ msg.len = 3;
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret != 1) {
+ dev_err(&client->dev,
+ "write error SR.WEL|SR.RWEL, ret=%d\n", ret);
+ ret = ret < 0 ? ret : -EIO;
+ goto out;
+ } else {
+ ret = 0;
+ }
+out:
+ return ret;
+}
+
+static int isl12026_disarm_write(struct i2c_client *client)
+{
+ int ret;
+ u8 op[3] = {0, ISL12026_REG_SR, 0};
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .len = sizeof(op),
+ .buf = op
+ };
+
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret != 1) {
+ dev_err(&client->dev,
+ "write error SR, ret=%d\n", ret);
+ ret = ret < 0 ? ret : -EIO;
+ } else {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int isl12026_write_reg(struct i2c_client *client, int reg, u8 val)
+{
+ int ret;
+ u8 op[3] = {0, reg, val};
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .len = sizeof(op),
+ .buf = op
+ };
+
+ ret = isl12026_arm_write(client);
+ if (ret)
+ return ret;
+
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret != 1) {
+ dev_err(&client->dev, "write error CCR, ret=%d\n", ret);
+ ret = ret < 0 ? ret : -EIO;
+ goto out;
+ }
+
+ msleep(ISL12026_NVMEM_WRITE_TIME);
+
+ ret = isl12026_disarm_write(client);
+out:
+ return ret;
+}
+
+static int isl12026_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ int ret;
+ u8 op[10];
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .len = sizeof(op),
+ .buf = op
+ };
+
+ ret = isl12026_arm_write(client);
+ if (ret)
+ return ret;
+
+ /* Set the CCR registers */
+ op[0] = 0;
+ op[1] = ISL12026_REG_SC;
+ op[2] = bin2bcd(tm->tm_sec); /* SC */
+ op[3] = bin2bcd(tm->tm_min); /* MN */
+ op[4] = bin2bcd(tm->tm_hour) | ISL12026_REG_HR_MIL; /* HR */
+ op[5] = bin2bcd(tm->tm_mday); /* DT */
+ op[6] = bin2bcd(tm->tm_mon + 1); /* MO */
+ op[7] = bin2bcd(tm->tm_year % 100); /* YR */
+ op[8] = bin2bcd(tm->tm_wday & 7); /* DW */
+ op[9] = bin2bcd(tm->tm_year >= 100 ? 20 : 19); /* Y2K */
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret != 1) {
+ dev_err(&client->dev, "write error CCR, ret=%d\n", ret);
+ ret = ret < 0 ? ret : -EIO;
+ goto out;
+ }
+
+ ret = isl12026_disarm_write(client);
+out:
+ return ret;
+}
+
+static int isl12026_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 ccr[8];
+ u8 addr[2];
+ u8 sr;
+ int ret;
+ struct i2c_msg msgs[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = sizeof(addr),
+ .buf = addr
+ }, {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ }
+ };
+
+ /* First, read SR */
+ addr[0] = 0;
+ addr[1] = ISL12026_REG_SR;
+ msgs[1].len = 1;
+ msgs[1].buf = &sr;
+
+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+ if (ret != ARRAY_SIZE(msgs)) {
+ dev_err(&client->dev, "read error, ret=%d\n", ret);
+ ret = ret < 0 ? ret : -EIO;
+ goto out;
+ }
+
+ if (sr & ISL12026_REG_SR_RTCF)
+ dev_warn(&client->dev, "Real-Time Clock Failure on read\n");
+ if (sr & ISL12026_REG_SR_OSCF)
+ dev_warn(&client->dev, "Oscillator Failure on read\n");
+
+ /* Second, CCR regs */
+ addr[0] = 0;
+ addr[1] = ISL12026_REG_SC;
+ msgs[1].len = sizeof(ccr);
+ msgs[1].buf = ccr;
+
+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+ if (ret != ARRAY_SIZE(msgs)) {
+ dev_err(&client->dev, "read error, ret=%d\n", ret);
+ ret = ret < 0 ? ret : -EIO;
+ goto out;
+ }
+
+ tm->tm_sec = bcd2bin(ccr[0] & 0x7F);
+ tm->tm_min = bcd2bin(ccr[1] & 0x7F);
+ if (ccr[2] & ISL12026_REG_HR_MIL)
+ tm->tm_hour = bcd2bin(ccr[2] & 0x3F);
+ else
+ tm->tm_hour = bcd2bin(ccr[2] & 0x1F) +
+ ((ccr[2] & 0x20) ? 12 : 0);
+ tm->tm_mday = bcd2bin(ccr[3] & 0x3F);
+ tm->tm_mon = bcd2bin(ccr[4] & 0x1F) - 1;
+ tm->tm_year = bcd2bin(ccr[5]);
+ if (bcd2bin(ccr[7]) == 20)
+ tm->tm_year += 100;
+ tm->tm_wday = ccr[6] & 0x07;
+
+ ret = 0;
+out:
+ return ret;
+}
+
+static const struct rtc_class_ops isl12026_rtc_ops = {
+ .read_time = isl12026_rtc_read_time,
+ .set_time = isl12026_rtc_set_time,
+};
+
+static int isl12026_nvm_read(void *p, unsigned int offset,
+ void *val, size_t bytes)
+{
+ struct isl12026 *priv = p;
+ int ret;
+ u8 addr[2];
+ struct i2c_msg msgs[] = {
+ {
+ .addr = priv->nvm_client->addr,
+ .flags = 0,
+ .len = sizeof(addr),
+ .buf = addr
+ }, {
+ .addr = priv->nvm_client->addr,
+ .flags = I2C_M_RD,
+ .buf = val
+ }
+ };
+
+ /*
+ * offset and bytes checked and limited by nvmem core, so
+ * proceed without further checks.
+ */
+ ret = mutex_lock_interruptible(&priv->rtc->ops_lock);
+ if (ret)
+ return ret;
+
+ /* 2 bytes of address, most significant first */
+ addr[0] = offset >> 8;
+ addr[1] = offset;
+ msgs[1].len = bytes;
+ ret = i2c_transfer(priv->nvm_client->adapter, msgs, ARRAY_SIZE(msgs));
+
+ mutex_unlock(&priv->rtc->ops_lock);
+
+ if (ret != ARRAY_SIZE(msgs)) {
+ dev_err(&priv->nvm_client->dev,
+ "nvmem read error, ret=%d\n", ret);
+ return ret < 0 ? ret : -EIO;
+ }
+
+ return 0;
+}
+
+static int isl12026_nvm_write(void *p, unsigned int offset,
+ void *val, size_t bytes)
+{
+ struct isl12026 *priv = p;
+ int ret;
+ u8 *v = val;
+ size_t chunk_size, num_written;
+ u8 payload[ISL12026_PAGESIZE + 2]; /* page + 2 address bytes */
+ struct i2c_msg msgs[] = {
+ {
+ .addr = priv->nvm_client->addr,
+ .flags = 0,
+ .buf = payload
+ }
+ };
+
+ /*
+ * offset and bytes checked and limited by nvmem core, so
+ * proceed without further checks.
+ */
+ ret = mutex_lock_interruptible(&priv->rtc->ops_lock);
+ if (ret)
+ return ret;
+
+ num_written = 0;
+ while (bytes) {
+ chunk_size = round_down(offset, ISL12026_PAGESIZE) +
+ ISL12026_PAGESIZE - offset;
+ chunk_size = min(bytes, chunk_size);
+ /*
+ * 2 bytes of address, most significant first, followed
+ * by page data bytes
+ */
+ memcpy(payload + 2, v + num_written, chunk_size);
+ payload[0] = offset >> 8;
+ payload[1] = offset;
+ msgs[0].len = chunk_size + 2;
+ ret = i2c_transfer(priv->nvm_client->adapter,
+ msgs, ARRAY_SIZE(msgs));
+ if (ret != ARRAY_SIZE(msgs)) {
+ dev_err(&priv->nvm_client->dev,
+ "nvmem write error, ret=%d\n", ret);
+ ret = ret < 0 ? ret : -EIO;
+ break;
+ }
+ ret = 0;
+ bytes -= chunk_size;
+ offset += chunk_size;
+ num_written += chunk_size;
+ msleep(ISL12026_NVMEM_WRITE_TIME);
+ }
+
+ mutex_unlock(&priv->rtc->ops_lock);
+
+ return ret;
+}
+
+static void isl12026_force_power_modes(struct i2c_client *client)
+{
+ int ret;
+ int pwr, requested_pwr;
+ u32 bsw_val, sbib_val;
+ bool set_bsw, set_sbib;
+
+ /*
+ * If we can read the of_property, set the specified value.
+ * If there is an error reading the of_property (likely
+ * because it does not exist), keep the current value.
+ */
+ ret = of_property_read_u32(client->dev.of_node,
+ "isil,pwr-bsw", &bsw_val);
+ set_bsw = (ret == 0);
+
+ ret = of_property_read_u32(client->dev.of_node,
+ "isil,pwr-sbib", &sbib_val);
+ set_sbib = (ret == 0);
+
+ /* Check if PWR.BSW and/or PWR.SBIB need specified values */
+ if (!set_bsw && !set_sbib)
+ return;
+
+ pwr = isl12026_read_reg(client, ISL12026_REG_PWR);
+ if (pwr < 0) {
+ dev_warn(&client->dev, "Error: Failed to read PWR %d\n", pwr);
+ return;
+ }
+
+ requested_pwr = pwr;
+
+ if (set_bsw) {
+ if (bsw_val)
+ requested_pwr |= ISL12026_REG_PWR_BSW;
+ else
+ requested_pwr &= ~ISL12026_REG_PWR_BSW;
+ } /* else keep current BSW */
+
+ if (set_sbib) {
+ if (sbib_val)
+ requested_pwr |= ISL12026_REG_PWR_SBIB;
+ else
+ requested_pwr &= ~ISL12026_REG_PWR_SBIB;
+ } /* else keep current SBIB */
+
+ if (pwr >= 0 && pwr != requested_pwr) {
+ dev_dbg(&client->dev, "PWR: %02x\n", pwr);
+ dev_dbg(&client->dev, "Updating PWR to: %02x\n", requested_pwr);
+ isl12026_write_reg(client, ISL12026_REG_PWR, requested_pwr);
+ }
+}
+
+static int isl12026_probe_new(struct i2c_client *client)
+{
+ struct isl12026 *priv;
+ int ret;
+ struct nvmem_config nvm_cfg = {
+ .name = "isl12026-",
+ .base_dev = &client->dev,
+ .stride = 1,
+ .word_size = 1,
+ .size = 512,
+ .reg_read = isl12026_nvm_read,
+ .reg_write = isl12026_nvm_write,
+ };
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ return -ENODEV;
+
+ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, priv);
+
+ isl12026_force_power_modes(client);
+
+ priv->nvm_client = i2c_new_dummy(client->adapter, ISL12026_EEPROM_ADDR);
+ if (!priv->nvm_client)
+ return -ENOMEM;
+
+ priv->rtc = devm_rtc_allocate_device(&client->dev);
+ ret = PTR_ERR_OR_ZERO(priv->rtc);
+ if (ret)
+ return ret;
+
+ priv->rtc->ops = &isl12026_rtc_ops;
+ nvm_cfg.priv = priv;
+ ret = rtc_nvmem_register(priv->rtc, &nvm_cfg);
+ if (ret)
+ return ret;
+
+ return rtc_register_device(priv->rtc);
+}
+
+static int isl12026_remove(struct i2c_client *client)
+{
+ struct isl12026 *priv = i2c_get_clientdata(client);
+
+ i2c_unregister_device(priv->nvm_client);
+ return 0;
+}
+
+static const struct of_device_id isl12026_dt_match[] = {
+ { .compatible = "isil,isl12026" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, isl12026_dt_match);
+
+static struct i2c_driver isl12026_driver = {
+ .driver = {
+ .name = "rtc-isl12026",
+ .of_match_table = isl12026_dt_match,
+ },
+ .probe_new = isl12026_probe_new,
+ .remove = isl12026_remove,
+};
+
+module_i2c_driver(isl12026_driver);
+
+MODULE_DESCRIPTION("ISL 12026 RTC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index 8dd299c..1a2c38c 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -459,6 +459,11 @@ isl1208_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
}
/* clear WRTC again */
+ sr = isl1208_i2c_get_sr(client);
+ if (sr < 0) {
+ dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+ return sr;
+ }
sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR,
sr & ~ISL1208_REG_SR_WRTC);
if (sr < 0) {
@@ -630,29 +635,12 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
if (isl1208_i2c_validate_client(client) < 0)
return -ENODEV;
- if (client->irq > 0) {
- rc = devm_request_threaded_irq(&client->dev, client->irq, NULL,
- isl1208_rtc_interrupt,
- IRQF_SHARED | IRQF_ONESHOT,
- isl1208_driver.driver.name,
- client);
- if (!rc) {
- device_init_wakeup(&client->dev, 1);
- enable_irq_wake(client->irq);
- } else {
- dev_err(&client->dev,
- "Unable to request irq %d, no alarm support\n",
- client->irq);
- client->irq = 0;
- }
- }
-
- rtc = devm_rtc_device_register(&client->dev, isl1208_driver.driver.name,
- &isl1208_rtc_ops,
- THIS_MODULE);
+ rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
+ rtc->ops = &isl1208_rtc_ops;
+
i2c_set_clientdata(client, rtc);
rc = isl1208_i2c_get_sr(client);
@@ -669,7 +657,24 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
if (rc)
return rc;
- return 0;
+ if (client->irq > 0) {
+ rc = devm_request_threaded_irq(&client->dev, client->irq, NULL,
+ isl1208_rtc_interrupt,
+ IRQF_SHARED | IRQF_ONESHOT,
+ isl1208_driver.driver.name,
+ client);
+ if (!rc) {
+ device_init_wakeup(&client->dev, 1);
+ enable_irq_wake(client->irq);
+ } else {
+ dev_err(&client->dev,
+ "Unable to request irq %d, no alarm support\n",
+ client->irq);
+ client->irq = 0;
+ }
+ }
+
+ return rtc_register_device(rtc);
}
static int
diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c
index ff65a7d..d0a8917 100644
--- a/drivers/rtc/rtc-jz4740.c
+++ b/drivers/rtc/rtc-jz4740.c
@@ -173,7 +173,7 @@ static int jz4740_rtc_read_time(struct device *dev, struct rtc_time *time)
rtc_time_to_tm(secs, time);
- return rtc_valid_tm(time);
+ return 0;
}
static int jz4740_rtc_set_mmss(struct device *dev, unsigned long secs)
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
index 1ae7da5..4a3c0f3 100644
--- a/drivers/rtc/rtc-lib.c
+++ b/drivers/rtc/rtc-lib.c
@@ -52,13 +52,11 @@ EXPORT_SYMBOL(rtc_year_days);
*/
void rtc_time64_to_tm(time64_t time, struct rtc_time *tm)
{
- unsigned int month, year;
- unsigned long secs;
+ unsigned int month, year, secs;
int days;
/* time must be positive */
- days = div_s64(time, 86400);
- secs = time - (unsigned int) days * 86400;
+ days = div_s64_rem(time, 86400, &secs);
/* day of the week, 1970-01-01 was a Thursday */
tm->tm_wday = (days + 4) % 7;
@@ -67,7 +65,7 @@ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm)
days -= (year - 1970) * 365
+ LEAPS_THRU_END_OF(year - 1)
- LEAPS_THRU_END_OF(1970 - 1);
- if (days < 0) {
+ while (days < 0) {
year -= 1;
days += 365 + is_leap_year(year);
}
diff --git a/drivers/rtc/rtc-lpc24xx.c b/drivers/rtc/rtc-lpc24xx.c
index 59d9959..14dc7b0 100644
--- a/drivers/rtc/rtc-lpc24xx.c
+++ b/drivers/rtc/rtc-lpc24xx.c
@@ -110,7 +110,7 @@ static int lpc24xx_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_year = CT1_YEAR(ct1);
tm->tm_yday = CT2_DOY(ct2);
- return rtc_valid_tm(tm);
+ return 0;
}
static int lpc24xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c
index 887871c..3ba8723 100644
--- a/drivers/rtc/rtc-lpc32xx.c
+++ b/drivers/rtc/rtc-lpc32xx.c
@@ -70,7 +70,7 @@ static int lpc32xx_rtc_read_time(struct device *dev, struct rtc_time *time)
elapsed_sec = rtc_readl(rtc, LPC32XX_RTC_UCOUNT);
rtc_time_to_tm(elapsed_sec, time);
- return rtc_valid_tm(time);
+ return 0;
}
static int lpc32xx_rtc_set_mmss(struct device *dev, unsigned long secs)
diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c
index e04ca54..045af11 100644
--- a/drivers/rtc/rtc-ls1x.c
+++ b/drivers/rtc/rtc-ls1x.c
@@ -98,7 +98,7 @@ static int ls1x_rtc_read_time(struct device *dev, struct rtc_time *rtm)
ls1x_get_min(v), ls1x_get_sec(v));
rtc_time_to_tm(t, rtm);
- return rtc_valid_tm(rtm);
+ return 0;
}
static int ls1x_rtc_set_time(struct device *dev, struct rtc_time *rtm)
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index c90fba3..ad03e2f 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -73,7 +73,6 @@
#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 const struct i2c_device_id m41t80_id[] = {
{ "m41t62", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT },
{ "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD },
@@ -199,9 +198,9 @@ static irqreturn_t m41t80_handle_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int m41t80_get_datetime(struct i2c_client *client,
- struct rtc_time *tm)
+static int m41t80_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
+ struct i2c_client *client = to_i2c_client(dev);
unsigned char buf[8];
int err, flags;
@@ -230,12 +229,12 @@ static int m41t80_get_datetime(struct i2c_client *client,
/* assume 20YY not 19YY, and ignore the Century Bit */
tm->tm_year = bcd2bin(buf[M41T80_REG_YEAR]) + 100;
- return rtc_valid_tm(tm);
+ return 0;
}
-/* 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_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct m41t80_data *clientdata = i2c_get_clientdata(client);
unsigned char buf[8];
int err, flags;
@@ -298,16 +297,6 @@ static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq)
return 0;
}
-static int m41t80_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- return m41t80_get_datetime(to_i2c_client(dev), tm);
-}
-
-static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- return m41t80_set_datetime(to_i2c_client(dev), tm);
-}
-
static int m41t80_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -598,6 +587,7 @@ static struct clk *m41t80_sqw_register_clk(struct m41t80_data *m41t80)
*
*****************************************************************************
*/
+static DEFINE_MUTEX(m41t80_rtc_mutex);
static struct i2c_client *save_client;
/* Default margin */
@@ -885,7 +875,6 @@ static int m41t80_probe(struct i2c_client *client,
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
int rc = 0;
- struct rtc_device *rtc = NULL;
struct rtc_time tm;
struct m41t80_data *m41t80_data = NULL;
bool wakeup_source = false;
@@ -909,6 +898,10 @@ static int m41t80_probe(struct i2c_client *client,
m41t80_data->features = id->driver_data;
i2c_set_clientdata(client, m41t80_data);
+ m41t80_data->rtc = devm_rtc_allocate_device(&client->dev);
+ if (IS_ERR(m41t80_data->rtc))
+ return PTR_ERR(m41t80_data->rtc);
+
#ifdef CONFIG_OF
wakeup_source = of_property_read_bool(client->dev.of_node,
"wakeup-source");
@@ -932,15 +925,11 @@ static int m41t80_probe(struct i2c_client *client,
device_init_wakeup(&client->dev, true);
}
- rtc = devm_rtc_device_register(&client->dev, client->name,
- &m41t80_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc))
- return PTR_ERR(rtc);
+ m41t80_data->rtc->ops = &m41t80_rtc_ops;
- m41t80_data->rtc = rtc;
if (client->irq <= 0) {
/* We cannot support UIE mode if we do not have an IRQ line */
- rtc->uie_unsupported = 1;
+ m41t80_data->rtc->uie_unsupported = 1;
}
/* Make sure HT (Halt Update) bit is cleared */
@@ -948,7 +937,7 @@ static int m41t80_probe(struct i2c_client *client,
if (rc >= 0 && rc & M41T80_ALHOUR_HT) {
if (m41t80_data->features & M41T80_FEATURE_HT) {
- m41t80_get_datetime(client, &tm);
+ m41t80_rtc_read_time(&client->dev, &tm);
dev_info(&client->dev, "HT bit was set!\n");
dev_info(&client->dev,
"Power Down at %04i-%02i-%02i %02i:%02i:%02i\n",
@@ -993,6 +982,11 @@ static int m41t80_probe(struct i2c_client *client,
if (m41t80_data->features & M41T80_FEATURE_SQ)
m41t80_sqw_register_clk(m41t80_data);
#endif
+
+ rc = rtc_register_device(m41t80_data->rtc);
+ if (rc)
+ return rc;
+
return 0;
}
diff --git a/drivers/rtc/rtc-m41t93.c b/drivers/rtc/rtc-m41t93.c
index 5ac45fc..4a08a9d 100644
--- a/drivers/rtc/rtc-m41t93.c
+++ b/drivers/rtc/rtc-m41t93.c
@@ -159,7 +159,7 @@ static int m41t93_get_time(struct device *dev, struct rtc_time *tm)
tm->tm_hour, tm->tm_mday,
tm->tm_mon, tm->tm_year, tm->tm_wday);
- return ret < 0 ? ret : rtc_valid_tm(tm);
+ return ret;
}
diff --git a/drivers/rtc/rtc-m41t94.c b/drivers/rtc/rtc-m41t94.c
index 1f0eb79..bab82b4 100644
--- a/drivers/rtc/rtc-m41t94.c
+++ b/drivers/rtc/rtc-m41t94.c
@@ -99,8 +99,7 @@ static int m41t94_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_hour, tm->tm_mday,
tm->tm_mon, tm->tm_year, tm->tm_wday);
- /* initial clock setting can be undefined */
- return rtc_valid_tm(tm);
+ return 0;
}
static const struct rtc_class_ops m41t94_rtc_ops = {
diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c
index 810f4ea..0cf6507 100644
--- a/drivers/rtc/rtc-m48t35.c
+++ b/drivers/rtc/rtc-m48t35.c
@@ -84,7 +84,7 @@ static int m48t35_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_year += 100;
tm->tm_mon--;
- return rtc_valid_tm(tm);
+ return 0;
}
static int m48t35_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c
index d99a705..216fac6 100644
--- a/drivers/rtc/rtc-m48t59.c
+++ b/drivers/rtc/rtc-m48t59.c
@@ -105,7 +105,7 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm)
dev_dbg(dev, "RTC read time %04d-%02d-%02d %02d/%02d/%02d\n",
tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
- return rtc_valid_tm(tm);
+ return 0;
}
static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -334,16 +334,16 @@ static const struct rtc_class_ops m48t02_rtc_ops = {
.set_time = m48t59_rtc_set_time,
};
-static ssize_t m48t59_nvram_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t pos, size_t size)
+static int m48t59_nvram_read(void *priv, unsigned int offset, void *val,
+ size_t size)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct platform_device *pdev = to_platform_device(dev);
+ struct platform_device *pdev = priv;
+ struct device *dev = &pdev->dev;
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
ssize_t cnt = 0;
unsigned long flags;
+ u8 *buf = val;
spin_lock_irqsave(&m48t59->lock, flags);
@@ -352,19 +352,19 @@ static ssize_t m48t59_nvram_read(struct file *filp, struct kobject *kobj,
spin_unlock_irqrestore(&m48t59->lock, flags);
- return cnt;
+ return 0;
}
-static ssize_t m48t59_nvram_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t pos, size_t size)
+static int m48t59_nvram_write(void *priv, unsigned int offset, void *val,
+ size_t size)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct platform_device *pdev = to_platform_device(dev);
+ struct platform_device *pdev = priv;
+ struct device *dev = &pdev->dev;
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
ssize_t cnt = 0;
unsigned long flags;
+ u8 *buf = val;
spin_lock_irqsave(&m48t59->lock, flags);
@@ -373,18 +373,9 @@ static ssize_t m48t59_nvram_write(struct file *filp, struct kobject *kobj,
spin_unlock_irqrestore(&m48t59->lock, flags);
- return cnt;
+ return 0;
}
-static struct bin_attribute m48t59_nvram_attr = {
- .attr = {
- .name = "nvram",
- .mode = S_IRUGO | S_IWUSR,
- },
- .read = m48t59_nvram_read,
- .write = m48t59_nvram_write,
-};
-
static int m48t59_rtc_probe(struct platform_device *pdev)
{
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
@@ -393,6 +384,14 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
int ret = -ENOMEM;
char *name;
const struct rtc_class_ops *ops;
+ struct nvmem_config nvmem_cfg = {
+ .name = "m48t59-",
+ .word_size = 1,
+ .stride = 1,
+ .reg_read = m48t59_nvram_read,
+ .reg_write = m48t59_nvram_write,
+ .priv = pdev,
+ };
/* This chip could be memory-mapped or I/O-mapped */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -480,23 +479,22 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
spin_lock_init(&m48t59->lock);
platform_set_drvdata(pdev, m48t59);
- m48t59->rtc = devm_rtc_device_register(&pdev->dev, name, ops,
- THIS_MODULE);
+ m48t59->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(m48t59->rtc))
return PTR_ERR(m48t59->rtc);
- m48t59_nvram_attr.size = pdata->offset;
+ m48t59->rtc->nvram_old_abi = true;
+ m48t59->rtc->ops = ops;
- ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
+ nvmem_cfg.size = pdata->offset;
+ ret = rtc_nvmem_register(m48t59->rtc, &nvmem_cfg);
if (ret)
return ret;
- return 0;
-}
+ ret = rtc_register_device(m48t59->rtc);
+ if (ret)
+ return ret;
-static int m48t59_rtc_remove(struct platform_device *pdev)
-{
- sysfs_remove_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
return 0;
}
@@ -508,7 +506,6 @@ static struct platform_driver m48t59_rtc_driver = {
.name = "rtc-m48t59",
},
.probe = m48t59_rtc_probe,
- .remove = m48t59_rtc_remove,
};
module_platform_driver(m48t59_rtc_driver);
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c
index d9aea9b..a953353 100644
--- a/drivers/rtc/rtc-m48t86.c
+++ b/drivers/rtc/rtc-m48t86.c
@@ -100,7 +100,7 @@ static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm)
if (m48t86_readb(dev, M48T86_HOUR) & 0x80)
tm->tm_hour += 12;
- return rtc_valid_tm(tm);
+ return 0;
}
static int m48t86_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -218,21 +218,21 @@ static bool m48t86_verify_chip(struct platform_device *pdev)
return false;
}
-static struct nvmem_config m48t86_nvmem_cfg = {
- .name = "m48t86_nvram",
- .word_size = 1,
- .stride = 1,
- .size = M48T86_NVRAM_LEN,
- .reg_read = m48t86_nvram_read,
- .reg_write = m48t86_nvram_write,
-};
-
static int m48t86_rtc_probe(struct platform_device *pdev)
{
struct m48t86_rtc_info *info;
struct resource *res;
unsigned char reg;
int err;
+ struct nvmem_config m48t86_nvmem_cfg = {
+ .name = "m48t86_nvram",
+ .word_size = 1,
+ .stride = 1,
+ .size = M48T86_NVRAM_LEN,
+ .reg_read = m48t86_nvram_read,
+ .reg_write = m48t86_nvram_write,
+ .priv = &pdev->dev,
+ };
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (!info)
@@ -264,15 +264,14 @@ static int m48t86_rtc_probe(struct platform_device *pdev)
return PTR_ERR(info->rtc);
info->rtc->ops = &m48t86_rtc_ops;
-
- m48t86_nvmem_cfg.priv = &pdev->dev;
- info->rtc->nvmem_config = &m48t86_nvmem_cfg;
info->rtc->nvram_old_abi = true;
err = rtc_register_device(info->rtc);
if (err)
return err;
+ rtc_nvmem_register(info->rtc, &m48t86_nvmem_cfg);
+
/* read battery status */
reg = m48t86_readb(&pdev->dev, M48T86_D);
dev_info(&pdev->dev, "battery %s\n",
diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c
index cbdc86a..ab60f13 100644
--- a/drivers/rtc/rtc-max6900.c
+++ b/drivers/rtc/rtc-max6900.c
@@ -139,8 +139,9 @@ static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
return -EIO;
}
-static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
+static int max6900_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
+ struct i2c_client *client = to_i2c_client(dev);
int rc;
u8 regs[MAX6900_REG_LEN];
@@ -157,7 +158,7 @@ static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
bcd2bin(regs[MAX6900_REG_CENTURY]) * 100 - 1900;
tm->tm_wday = bcd2bin(regs[MAX6900_REG_DW]);
- return rtc_valid_tm(tm);
+ return 0;
}
static int max6900_i2c_clear_write_protect(struct i2c_client *client)
@@ -165,9 +166,9 @@ static int max6900_i2c_clear_write_protect(struct i2c_client *client)
return i2c_smbus_write_byte_data(client, MAX6900_REG_CONTROL_WRITE, 0);
}
-static int
-max6900_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
+static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
+ struct i2c_client *client = to_i2c_client(dev);
u8 regs[MAX6900_REG_LEN];
int rc;
@@ -193,16 +194,6 @@ max6900_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
return 0;
}
-static int max6900_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- return max6900_i2c_read_time(to_i2c_client(dev), tm);
-}
-
-static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- return max6900_i2c_set_time(to_i2c_client(dev), tm);
-}
-
static const struct rtc_class_ops max6900_rtc_ops = {
.read_time = max6900_rtc_read_time,
.set_time = max6900_rtc_set_time,
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c
index 315d09e..7458274 100644
--- a/drivers/rtc/rtc-max6902.c
+++ b/drivers/rtc/rtc-max6902.c
@@ -85,7 +85,7 @@ static int max6902_read_time(struct device *dev, struct rtc_time *dt)
dt->tm_year += century;
dt->tm_year -= 1900;
- return rtc_valid_tm(dt);
+ return 0;
}
static int max6902_set_time(struct device *dev, struct rtc_time *dt)
diff --git a/drivers/rtc/rtc-max6916.c b/drivers/rtc/rtc-max6916.c
index 623ab27..7e908a4 100644
--- a/drivers/rtc/rtc-max6916.c
+++ b/drivers/rtc/rtc-max6916.c
@@ -75,7 +75,7 @@ static int max6916_read_time(struct device *dev, struct rtc_time *dt)
dt->tm_wday = bcd2bin(buf[5]) - 1;
dt->tm_year = bcd2bin(buf[6]) + 100;
- return rtc_valid_tm(dt);
+ return 0;
}
static int max6916_set_time(struct device *dev, struct rtc_time *dt)
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c
index 182fdd0..cefde27 100644
--- a/drivers/rtc/rtc-max77686.c
+++ b/drivers/rtc/rtc-max77686.c
@@ -364,11 +364,9 @@ static int max77686_rtc_read_time(struct device *dev, struct rtc_time *tm)
max77686_rtc_data_to_tm(data, tm, info);
- ret = rtc_valid_tm(tm);
-
out:
mutex_unlock(&info->lock);
- return ret;
+ return 0;
}
static int max77686_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-max8997.c b/drivers/rtc/rtc-max8997.c
index db984d4..e8cee12 100644
--- a/drivers/rtc/rtc-max8997.c
+++ b/drivers/rtc/rtc-max8997.c
@@ -153,7 +153,7 @@ static int max8997_rtc_read_time(struct device *dev, struct rtc_time *tm)
max8997_rtc_data_to_tm(data, tm, info->rtc_24hr_mode);
- return rtc_valid_tm(tm);
+ return 0;
}
static int max8997_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c
index 30804b0..d8c0f9b 100644
--- a/drivers/rtc/rtc-max8998.c
+++ b/drivers/rtc/rtc-max8998.c
@@ -120,7 +120,7 @@ static int max8998_rtc_read_time(struct device *dev, struct rtc_time *tm)
max8998_data_to_tm(data, tm);
- return rtc_valid_tm(tm);
+ return 0;
}
static int max8998_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c
index 30b8ef6..1f892b2 100644
--- a/drivers/rtc/rtc-mc13xxx.c
+++ b/drivers/rtc/rtc-mc13xxx.c
@@ -85,7 +85,7 @@ static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
rtc_time64_to_tm((time64_t)days1 * SEC_PER_DAY + seconds, tm);
- return rtc_valid_tm(tm);
+ return 0;
}
static int mc13xxx_rtc_set_mmss(struct device *dev, time64_t secs)
diff --git a/drivers/rtc/rtc-mcp795.c b/drivers/rtc/rtc-mcp795.c
index 77f2133..00e11c1 100644
--- a/drivers/rtc/rtc-mcp795.c
+++ b/drivers/rtc/rtc-mcp795.c
@@ -82,7 +82,7 @@ static int mcp795_rtcc_write(struct device *dev, u8 addr, u8 *data, u8 count)
{
struct spi_device *spi = to_spi_device(dev);
int ret;
- u8 tx[2 + count];
+ u8 tx[257];
tx[0] = MCP795_WRITE;
tx[1] = addr;
@@ -262,7 +262,7 @@ static int mcp795_read_time(struct device *dev, struct rtc_time *tim)
tim->tm_year + 1900, tim->tm_mon, tim->tm_mday,
tim->tm_wday, tim->tm_hour, tim->tm_min, tim->tm_sec);
- return rtc_valid_tm(tim);
+ return 0;
}
static int mcp795_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c
index 4ca4daa..dd03642 100644
--- a/drivers/rtc/rtc-mpc5121.c
+++ b/drivers/rtc/rtc-mpc5121.c
@@ -122,7 +122,7 @@ static int mpc5121_rtc_read_time(struct device *dev, struct rtc_time *tm)
*/
mpc5121_rtc_update_smh(regs, tm);
- return rtc_valid_tm(tm);
+ return 0;
}
static int mpc5121_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c
index 7334c44..fcb9de5 100644
--- a/drivers/rtc/rtc-mrst.c
+++ b/drivers/rtc/rtc-mrst.c
@@ -105,7 +105,7 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time)
/* Adjust for the 1972/1900 */
time->tm_year += 72;
time->tm_mon--;
- return rtc_valid_tm(time);
+ return 0;
}
static int mrst_set_time(struct device *dev, struct rtc_time *time)
@@ -122,7 +122,7 @@ static int mrst_set_time(struct device *dev, struct rtc_time *time)
min = time->tm_min;
sec = time->tm_sec;
- if (yrs < 72 || yrs > 138)
+ if (yrs < 72 || yrs > 172)
return -EINVAL;
yrs -= 72;
diff --git a/drivers/rtc/rtc-msm6242.c b/drivers/rtc/rtc-msm6242.c
index c1c5c4e..0c72a2e 100644
--- a/drivers/rtc/rtc-msm6242.c
+++ b/drivers/rtc/rtc-msm6242.c
@@ -155,7 +155,7 @@ static int msm6242_read_time(struct device *dev, struct rtc_time *tm)
msm6242_unlock(priv);
- return rtc_valid_tm(tm);
+ return 0;
}
static int msm6242_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-mt7622.c b/drivers/rtc/rtc-mt7622.c
index d79b9ae..fd0cea7 100644
--- a/drivers/rtc/rtc-mt7622.c
+++ b/drivers/rtc/rtc-mt7622.c
@@ -232,7 +232,7 @@ static int mtk_rtc_gettime(struct device *dev, struct rtc_time *tm)
mtk_rtc_get_alarm_or_time(hw, tm, MTK_TC);
- return rtc_valid_tm(tm);
+ return 0;
}
static int mtk_rtc_settime(struct device *dev, struct rtc_time *tm)
@@ -307,6 +307,7 @@ static const struct of_device_id mtk_rtc_match[] = {
{ .compatible = "mediatek,soc-rtc" },
{},
};
+MODULE_DEVICE_TABLE(of, mtk_rtc_match);
static int mtk_rtc_probe(struct platform_device *pdev)
{
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
index 79bb286..bc52dbb 100644
--- a/drivers/rtc/rtc-mv.c
+++ b/drivers/rtc/rtc-mv.c
@@ -94,7 +94,7 @@ static int mv_rtc_read_time(struct device *dev, struct rtc_time *tm)
/* hw counts from year 2000, but tm_year is relative to 1900 */
tm->tm_year = bcd2bin(year) + 100;
- return rtc_valid_tm(tm);
+ return 0;
}
static int mv_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
@@ -223,7 +223,6 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
struct resource *res;
struct rtc_plat_data *pdata;
u32 rtc_time;
- u32 rtc_date;
int ret = 0;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
@@ -259,17 +258,6 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
}
}
- /*
- * A date after January 19th, 2038 does not fit on 32 bits and
- * will confuse the kernel and userspace. Reset to a sane date
- * (January 1st, 2013) if we're after 2038.
- */
- rtc_date = readl(pdata->ioaddr + RTC_DATE_REG_OFFS);
- if (bcd2bin((rtc_date >> RTC_YEAR_OFFS) & 0xff) >= 38) {
- dev_info(&pdev->dev, "invalid RTC date, resetting to January 1st, 2013\n");
- writel(0x130101, pdata->ioaddr + RTC_DATE_REG_OFFS);
- }
-
pdata->irq = platform_get_irq(pdev, 0);
platform_set_drvdata(pdev, pdata);
diff --git a/drivers/rtc/rtc-mxc_v2.c b/drivers/rtc/rtc-mxc_v2.c
index 784221d..9e14efb 100644
--- a/drivers/rtc/rtc-mxc_v2.c
+++ b/drivers/rtc/rtc-mxc_v2.c
@@ -273,7 +273,7 @@ static const struct rtc_class_ops mxc_rtc_ops = {
.alarm_irq_enable = mxc_rtc_alarm_irq_enable,
};
-static int mxc_rtc_wait_for_flag(void *__iomem ioaddr, int flag)
+static int mxc_rtc_wait_for_flag(void __iomem *ioaddr, int flag)
{
unsigned int timeout = REG_READ_TIMEOUT;
diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c
index 4ed8111..7da664a 100644
--- a/drivers/rtc/rtc-nuc900.c
+++ b/drivers/rtc/rtc-nuc900.c
@@ -102,8 +102,8 @@ static int *check_rtc_access_enable(struct nuc900_rtc *nuc900_rtc)
return NULL;
}
-static int nuc900_rtc_bcd2bin(unsigned int timereg,
- unsigned int calreg, struct rtc_time *tm)
+static void nuc900_rtc_bcd2bin(unsigned int timereg,
+ unsigned int calreg, struct rtc_time *tm)
{
tm->tm_mday = bcd2bin(calreg >> 0);
tm->tm_mon = bcd2bin(calreg >> 8);
@@ -112,8 +112,6 @@ static int nuc900_rtc_bcd2bin(unsigned int timereg,
tm->tm_sec = bcd2bin(timereg >> 0);
tm->tm_min = bcd2bin(timereg >> 8);
tm->tm_hour = bcd2bin(timereg >> 16);
-
- return rtc_valid_tm(tm);
}
static void nuc900_rtc_bin2bcd(struct device *dev, struct rtc_time *settm,
@@ -156,7 +154,9 @@ static int nuc900_rtc_read_time(struct device *dev, struct rtc_time *tm)
timeval = __raw_readl(rtc->rtc_reg + REG_RTC_TLR);
clrval = __raw_readl(rtc->rtc_reg + REG_RTC_CLR);
- return nuc900_rtc_bcd2bin(timeval, clrval, tm);
+ nuc900_rtc_bcd2bin(timeval, clrval, tm);
+
+ return 0;
}
static int nuc900_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -189,7 +189,9 @@ static int nuc900_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
timeval = __raw_readl(rtc->rtc_reg + REG_RTC_TAR);
carval = __raw_readl(rtc->rtc_reg + REG_RTC_CAR);
- return nuc900_rtc_bcd2bin(timeval, carval, &alrm->time);
+ nuc900_rtc_bcd2bin(timeval, carval, &alrm->time);
+
+ return rtc_valid_tm(&alrm->time);
}
static int nuc900_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 09ef802..3908639 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -273,9 +273,6 @@ static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
/* this hardware doesn't support "don't care" alarm fields */
static int tm2bcd(struct rtc_time *tm)
{
- if (rtc_valid_tm(tm) != 0)
- return -EINVAL;
-
tm->tm_sec = bin2bcd(tm->tm_sec);
tm->tm_min = bin2bcd(tm->tm_min);
tm->tm_hour = bin2bcd(tm->tm_hour);
@@ -850,7 +847,6 @@ static int omap_rtc_probe(struct platform_device *pdev)
rtc->rtc->ops = &omap_rtc_ops;
omap_rtc_nvmem_config.priv = rtc;
- rtc->rtc->nvmem_config = &omap_rtc_nvmem_config;
/* handle periodic and alarm irqs */
ret = devm_request_irq(&pdev->dev, rtc->irq_timer, rtc_irq, 0,
@@ -886,6 +882,8 @@ static int omap_rtc_probe(struct platform_device *pdev)
if (ret)
goto err;
+ rtc_nvmem_register(rtc->rtc, &omap_rtc_nvmem_config);
+
return 0;
err:
diff --git a/drivers/rtc/rtc-pcap.c b/drivers/rtc/rtc-pcap.c
index c443324..c05f524 100644
--- a/drivers/rtc/rtc-pcap.c
+++ b/drivers/rtc/rtc-pcap.c
@@ -95,7 +95,7 @@ static int pcap_rtc_read_time(struct device *dev, struct rtc_time *tm)
rtc_time_to_tm(secs, tm);
- return rtc_valid_tm(tm);
+ return 0;
}
static int pcap_rtc_set_mmss(struct device *dev, unsigned long secs)
diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c
index 8895f77..e5222c5 100644
--- a/drivers/rtc/rtc-pcf2123.c
+++ b/drivers/rtc/rtc-pcf2123.c
@@ -289,7 +289,7 @@ static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
- return rtc_valid_tm(tm);
+ return 0;
}
static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c
index f33447c..e83be18 100644
--- a/drivers/rtc/rtc-pcf2127.c
+++ b/drivers/rtc/rtc-pcf2127.c
@@ -111,7 +111,7 @@ static int pcf2127_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
- return rtc_valid_tm(tm);
+ return 0;
}
static int pcf2127_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c
index 00c31c9..ef72b0c 100644
--- a/drivers/rtc/rtc-pcf50633.c
+++ b/drivers/rtc/rtc-pcf50633.c
@@ -135,7 +135,7 @@ static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_mday, tm->tm_mon, tm->tm_year,
tm->tm_hour, tm->tm_min, tm->tm_sec);
- return rtc_valid_tm(tm);
+ return 0;
}
static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
index a06dff9..49bcbb3 100644
--- a/drivers/rtc/rtc-pcf85063.c
+++ b/drivers/rtc/rtc-pcf85063.c
@@ -70,7 +70,7 @@ static int pcf85063_start_clock(struct i2c_client *client, u8 ctrl1)
s32 ret;
/* start the clock */
- ctrl1 &= PCF85063_REG_CTRL1_STOP;
+ ctrl1 &= ~PCF85063_REG_CTRL1_STOP;
ret = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, ctrl1);
if (ret < 0) {
@@ -81,8 +81,9 @@ static int pcf85063_start_clock(struct i2c_client *client, u8 ctrl1)
return 0;
}
-static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm)
+static int pcf85063_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
+ struct i2c_client *client = to_i2c_client(dev);
int rc;
u8 regs[7];
@@ -114,11 +115,12 @@ static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm)
tm->tm_year = bcd2bin(regs[6]);
tm->tm_year += 100;
- return rtc_valid_tm(tm);
+ return 0;
}
-static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm)
+static int pcf85063_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
+ struct i2c_client *client = to_i2c_client(dev);
int rc;
u8 regs[7];
u8 ctrl1;
@@ -172,16 +174,6 @@ static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm)
return 0;
}
-static int pcf85063_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- return pcf85063_get_datetime(to_i2c_client(dev), tm);
-}
-
-static int pcf85063_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- return pcf85063_set_datetime(to_i2c_client(dev), tm);
-}
-
static const struct rtc_class_ops pcf85063_rtc_ops = {
.read_time = pcf85063_rtc_read_time,
.set_time = pcf85063_rtc_set_time
diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c
index c312af0..453615f 100644
--- a/drivers/rtc/rtc-pcf8523.c
+++ b/drivers/rtc/rtc-pcf8523.c
@@ -192,7 +192,7 @@ static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_mon = bcd2bin(regs[5] & 0x1f) - 1;
tm->tm_year = bcd2bin(regs[6]) + 100;
- return rtc_valid_tm(tm);
+ return 0;
}
static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c
index ea04e9f..c04a1ed 100644
--- a/drivers/rtc/rtc-pcf85363.c
+++ b/drivers/rtc/rtc-pcf85363.c
@@ -73,6 +73,43 @@
#define CTRL_RESETS 0x2f
#define CTRL_RAM 0x40
+#define ALRM_SEC_A1E BIT(0)
+#define ALRM_MIN_A1E BIT(1)
+#define ALRM_HR_A1E BIT(2)
+#define ALRM_DAY_A1E BIT(3)
+#define ALRM_MON_A1E BIT(4)
+#define ALRM_MIN_A2E BIT(5)
+#define ALRM_HR_A2E BIT(6)
+#define ALRM_DAY_A2E BIT(7)
+
+#define INT_WDIE BIT(0)
+#define INT_BSIE BIT(1)
+#define INT_TSRIE BIT(2)
+#define INT_A2IE BIT(3)
+#define INT_A1IE BIT(4)
+#define INT_OIE BIT(5)
+#define INT_PIE BIT(6)
+#define INT_ILP BIT(7)
+
+#define FLAGS_TSR1F BIT(0)
+#define FLAGS_TSR2F BIT(1)
+#define FLAGS_TSR3F BIT(2)
+#define FLAGS_BSF BIT(3)
+#define FLAGS_WDF BIT(4)
+#define FLAGS_A1F BIT(5)
+#define FLAGS_A2F BIT(6)
+#define FLAGS_PIF BIT(7)
+
+#define PIN_IO_INTAPM GENMASK(1, 0)
+#define PIN_IO_INTA_CLK 0
+#define PIN_IO_INTA_BAT 1
+#define PIN_IO_INTA_OUT 2
+#define PIN_IO_INTA_HIZ 3
+
+#define STOP_EN_STOP BIT(0)
+
+#define RESET_CPR 0xa4
+
#define NVRAM_SIZE 0x40
static struct i2c_driver pcf85363_driver;
@@ -80,7 +117,6 @@ static struct i2c_driver pcf85363_driver;
struct pcf85363 {
struct device *dev;
struct rtc_device *rtc;
- struct nvmem_config nvmem_cfg;
struct regmap *regmap;
};
@@ -116,8 +152,12 @@ static int pcf85363_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int pcf85363_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct pcf85363 *pcf85363 = dev_get_drvdata(dev);
- unsigned char buf[DT_YEARS + 1];
- int len = sizeof(buf);
+ unsigned char tmp[11];
+ unsigned char *buf = &tmp[2];
+ int ret;
+
+ tmp[0] = STOP_EN_STOP;
+ tmp[1] = RESET_CPR;
buf[DT_100THS] = 0;
buf[DT_SECS] = bin2bcd(tm->tm_sec);
@@ -128,8 +168,116 @@ static int pcf85363_rtc_set_time(struct device *dev, struct rtc_time *tm)
buf[DT_MONTHS] = bin2bcd(tm->tm_mon + 1);
buf[DT_YEARS] = bin2bcd(tm->tm_year % 100);
- return regmap_bulk_write(pcf85363->regmap, DT_100THS,
- buf, len);
+ ret = regmap_bulk_write(pcf85363->regmap, CTRL_STOP_EN,
+ tmp, sizeof(tmp));
+ if (ret)
+ return ret;
+
+ return regmap_write(pcf85363->regmap, CTRL_STOP_EN, 0);
+}
+
+static int pcf85363_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct pcf85363 *pcf85363 = dev_get_drvdata(dev);
+ unsigned char buf[DT_MONTH_ALM1 - DT_SECOND_ALM1 + 1];
+ unsigned int val;
+ int ret;
+
+ ret = regmap_bulk_read(pcf85363->regmap, DT_SECOND_ALM1, buf,
+ sizeof(buf));
+ if (ret)
+ return ret;
+
+ alrm->time.tm_sec = bcd2bin(buf[0]);
+ alrm->time.tm_min = bcd2bin(buf[1]);
+ alrm->time.tm_hour = bcd2bin(buf[2]);
+ alrm->time.tm_mday = bcd2bin(buf[3]);
+ alrm->time.tm_mon = bcd2bin(buf[4]) - 1;
+
+ ret = regmap_read(pcf85363->regmap, CTRL_INTA_EN, &val);
+ if (ret)
+ return ret;
+
+ alrm->enabled = !!(val & INT_A1IE);
+
+ return 0;
+}
+
+static int _pcf85363_rtc_alarm_irq_enable(struct pcf85363 *pcf85363, unsigned
+ int enabled)
+{
+ unsigned int alarm_flags = ALRM_SEC_A1E | ALRM_MIN_A1E | ALRM_HR_A1E |
+ ALRM_DAY_A1E | ALRM_MON_A1E;
+ int ret;
+
+ ret = regmap_update_bits(pcf85363->regmap, DT_ALARM_EN, alarm_flags,
+ enabled ? alarm_flags : 0);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(pcf85363->regmap, CTRL_INTA_EN,
+ INT_A1IE, enabled ? INT_A1IE : 0);
+
+ if (ret || enabled)
+ return ret;
+
+ /* clear current flags */
+ return regmap_update_bits(pcf85363->regmap, CTRL_FLAGS, FLAGS_A1F, 0);
+}
+
+static int pcf85363_rtc_alarm_irq_enable(struct device *dev,
+ unsigned int enabled)
+{
+ struct pcf85363 *pcf85363 = dev_get_drvdata(dev);
+
+ return _pcf85363_rtc_alarm_irq_enable(pcf85363, enabled);
+}
+
+static int pcf85363_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct pcf85363 *pcf85363 = dev_get_drvdata(dev);
+ unsigned char buf[DT_MONTH_ALM1 - DT_SECOND_ALM1 + 1];
+ int ret;
+
+ buf[0] = bin2bcd(alrm->time.tm_sec);
+ buf[1] = bin2bcd(alrm->time.tm_min);
+ buf[2] = bin2bcd(alrm->time.tm_hour);
+ buf[3] = bin2bcd(alrm->time.tm_mday);
+ buf[4] = bin2bcd(alrm->time.tm_mon + 1);
+
+ /*
+ * Disable the alarm interrupt before changing the value to avoid
+ * spurious interrupts
+ */
+ ret = _pcf85363_rtc_alarm_irq_enable(pcf85363, 0);
+ if (ret)
+ return ret;
+
+ ret = regmap_bulk_write(pcf85363->regmap, DT_SECOND_ALM1, buf,
+ sizeof(buf));
+ if (ret)
+ return ret;
+
+ return _pcf85363_rtc_alarm_irq_enable(pcf85363, alrm->enabled);
+}
+
+static irqreturn_t pcf85363_rtc_handle_irq(int irq, void *dev_id)
+{
+ struct pcf85363 *pcf85363 = i2c_get_clientdata(dev_id);
+ unsigned int flags;
+ int err;
+
+ err = regmap_read(pcf85363->regmap, CTRL_FLAGS, &flags);
+ if (err)
+ return IRQ_NONE;
+
+ if (flags & FLAGS_A1F) {
+ rtc_update_irq(pcf85363->rtc, 1, RTC_IRQF | RTC_AF);
+ regmap_update_bits(pcf85363->regmap, CTRL_FLAGS, FLAGS_A1F, 0);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
}
static const struct rtc_class_ops rtc_ops = {
@@ -137,6 +285,14 @@ static const struct rtc_class_ops rtc_ops = {
.set_time = pcf85363_rtc_set_time,
};
+static const struct rtc_class_ops rtc_ops_alarm = {
+ .read_time = pcf85363_rtc_read_time,
+ .set_time = pcf85363_rtc_set_time,
+ .read_alarm = pcf85363_rtc_read_alarm,
+ .set_alarm = pcf85363_rtc_set_alarm,
+ .alarm_irq_enable = pcf85363_rtc_alarm_irq_enable,
+};
+
static int pcf85363_nvram_read(void *priv, unsigned int offset, void *val,
size_t bytes)
{
@@ -158,12 +314,22 @@ static int pcf85363_nvram_write(void *priv, unsigned int offset, void *val,
static const struct regmap_config regmap_config = {
.reg_bits = 8,
.val_bits = 8,
+ .max_register = 0x7f,
};
static int pcf85363_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pcf85363 *pcf85363;
+ struct nvmem_config nvmem_cfg = {
+ .name = "pcf85363-",
+ .word_size = 1,
+ .stride = 1,
+ .size = NVRAM_SIZE,
+ .reg_read = pcf85363_nvram_read,
+ .reg_write = pcf85363_nvram_write,
+ };
+ int ret;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV;
@@ -186,17 +352,28 @@ static int pcf85363_probe(struct i2c_client *client,
if (IS_ERR(pcf85363->rtc))
return PTR_ERR(pcf85363->rtc);
- pcf85363->nvmem_cfg.name = "pcf85363-";
- pcf85363->nvmem_cfg.word_size = 1;
- pcf85363->nvmem_cfg.stride = 1;
- pcf85363->nvmem_cfg.size = NVRAM_SIZE;
- pcf85363->nvmem_cfg.reg_read = pcf85363_nvram_read;
- pcf85363->nvmem_cfg.reg_write = pcf85363_nvram_write;
- pcf85363->nvmem_cfg.priv = pcf85363;
- pcf85363->rtc->nvmem_config = &pcf85363->nvmem_cfg;
pcf85363->rtc->ops = &rtc_ops;
- return rtc_register_device(pcf85363->rtc);
+ if (client->irq > 0) {
+ regmap_write(pcf85363->regmap, CTRL_FLAGS, 0);
+ regmap_update_bits(pcf85363->regmap, CTRL_PIN_IO,
+ PIN_IO_INTA_OUT, PIN_IO_INTAPM);
+ ret = devm_request_threaded_irq(pcf85363->dev, client->irq,
+ NULL, pcf85363_rtc_handle_irq,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ "pcf85363", client);
+ if (ret)
+ dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
+ else
+ pcf85363->rtc->ops = &rtc_ops_alarm;
+ }
+
+ ret = rtc_register_device(pcf85363->rtc);
+
+ nvmem_cfg.priv = pcf85363;
+ rtc_nvmem_register(pcf85363->rtc, &nvmem_cfg);
+
+ return ret;
}
static const struct of_device_id dev_ids[] = {
diff --git a/drivers/rtc/rtc-pic32.c b/drivers/rtc/rtc-pic32.c
index 5cfb6df..3c08eab 100644
--- a/drivers/rtc/rtc-pic32.c
+++ b/drivers/rtc/rtc-pic32.c
@@ -175,7 +175,7 @@ static int pic32_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
clk_disable(pdata->clk);
- return rtc_valid_tm(rtc_tm);
+ return 0;
}
static int pic32_rtc_settime(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
index fac8355..29358a0 100644
--- a/drivers/rtc/rtc-pm8xxx.c
+++ b/drivers/rtc/rtc-pm8xxx.c
@@ -74,16 +74,18 @@ struct pm8xxx_rtc {
/*
* Steps to write the RTC registers.
* 1. Disable alarm if enabled.
- * 2. Write 0x00 to LSB.
- * 3. Write Byte[1], Byte[2], Byte[3] then Byte[0].
- * 4. Enable alarm if disabled in step 1.
+ * 2. Disable rtc if enabled.
+ * 3. Write 0x00 to LSB.
+ * 4. Write Byte[1], Byte[2], Byte[3] then Byte[0].
+ * 5. Enable rtc if disabled in step 2.
+ * 6. Enable alarm if disabled in step 1.
*/
static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
int rc, i;
unsigned long secs, irq_flags;
- u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0;
- unsigned int ctrl_reg;
+ u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0, rtc_disabled = 0;
+ unsigned int ctrl_reg, rtc_ctrl_reg;
struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
const struct pm8xxx_rtc_regs *regs = rtc_dd->regs;
@@ -92,23 +94,38 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm)
rtc_tm_to_time(tm, &secs);
+ dev_dbg(dev, "Seconds value to be written to RTC = %lu\n", secs);
+
for (i = 0; i < NUM_8_BIT_RTC_REGS; i++) {
value[i] = secs & 0xFF;
secs >>= 8;
}
- dev_dbg(dev, "Seconds value to be written to RTC = %lu\n", secs);
-
spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags);
- rc = regmap_read(rtc_dd->regmap, regs->ctrl, &ctrl_reg);
+ rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg);
if (rc)
goto rtc_rw_fail;
if (ctrl_reg & regs->alarm_en) {
alarm_enabled = 1;
ctrl_reg &= ~regs->alarm_en;
- rc = regmap_write(rtc_dd->regmap, regs->ctrl, ctrl_reg);
+ rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg);
+ if (rc) {
+ dev_err(dev, "Write to RTC Alarm control register failed\n");
+ goto rtc_rw_fail;
+ }
+ }
+
+ /* Disable RTC H/w before writing on RTC register */
+ rc = regmap_read(rtc_dd->regmap, regs->ctrl, &rtc_ctrl_reg);
+ if (rc)
+ goto rtc_rw_fail;
+
+ if (rtc_ctrl_reg & PM8xxx_RTC_ENABLE) {
+ rtc_disabled = 1;
+ rtc_ctrl_reg &= ~PM8xxx_RTC_ENABLE;
+ rc = regmap_write(rtc_dd->regmap, regs->ctrl, rtc_ctrl_reg);
if (rc) {
dev_err(dev, "Write to RTC control register failed\n");
goto rtc_rw_fail;
@@ -137,11 +154,21 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm)
goto rtc_rw_fail;
}
+ /* Enable RTC H/w after writing on RTC register */
+ if (rtc_disabled) {
+ rtc_ctrl_reg |= PM8xxx_RTC_ENABLE;
+ rc = regmap_write(rtc_dd->regmap, regs->ctrl, rtc_ctrl_reg);
+ if (rc) {
+ dev_err(dev, "Write to RTC control register failed\n");
+ goto rtc_rw_fail;
+ }
+ }
+
if (alarm_enabled) {
ctrl_reg |= regs->alarm_en;
- rc = regmap_write(rtc_dd->regmap, regs->ctrl, ctrl_reg);
+ rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg);
if (rc) {
- dev_err(dev, "Write to RTC control register failed\n");
+ dev_err(dev, "Write to RTC Alarm control register failed\n");
goto rtc_rw_fail;
}
}
@@ -190,12 +217,6 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
rtc_time_to_tm(secs, tm);
- rc = rtc_valid_tm(tm);
- if (rc < 0) {
- dev_err(dev, "Invalid time read from RTC\n");
- return rc;
- }
-
dev_dbg(dev, "secs = %lu, h:m:s == %d:%d:%d, d/m/y = %d/%d/%d\n",
secs, tm->tm_hour, tm->tm_min, tm->tm_sec,
tm->tm_mday, tm->tm_mon, tm->tm_year);
diff --git a/drivers/rtc/rtc-ps3.c b/drivers/rtc/rtc-ps3.c
index 6a8f5d7..347288b 100644
--- a/drivers/rtc/rtc-ps3.c
+++ b/drivers/rtc/rtc-ps3.c
@@ -41,7 +41,7 @@ static u64 read_rtc(void)
static int ps3_get_time(struct device *dev, struct rtc_time *tm)
{
rtc_time_to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm);
- return rtc_valid_tm(tm);
+ return 0;
}
static int ps3_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-r7301.c b/drivers/rtc/rtc-r7301.c
index 500e8c8..169704b 100644
--- a/drivers/rtc/rtc-r7301.c
+++ b/drivers/rtc/rtc-r7301.c
@@ -224,7 +224,7 @@ static int rtc7301_read_time(struct device *dev, struct rtc_time *tm)
spin_unlock_irqrestore(&priv->lock, flags);
- return err ? err : rtc_valid_tm(tm);
+ return err;
}
static int rtc7301_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-r9701.c b/drivers/rtc/rtc-r9701.c
index b6c5eb9..a39ccd1 100644
--- a/drivers/rtc/rtc-r9701.c
+++ b/drivers/rtc/rtc-r9701.c
@@ -92,7 +92,7 @@ static int r9701_get_datetime(struct device *dev, struct rtc_time *dt)
* according to the data sheet. make sure they are valid.
*/
- return rtc_valid_tm(dt);
+ return 0;
}
static int r9701_set_datetime(struct device *dev, struct rtc_time *dt)
diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c
index 35c9aad..739c0d4 100644
--- a/drivers/rtc/rtc-rk808.c
+++ b/drivers/rtc/rtc-rk808.c
@@ -375,7 +375,6 @@ static int rk808_rtc_probe(struct platform_device *pdev)
{
struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
struct rk808_rtc *rk808_rtc;
- struct rtc_time tm;
int ret;
rk808_rtc = devm_kzalloc(&pdev->dev, sizeof(*rk808_rtc), GFP_KERNEL);
@@ -404,24 +403,13 @@ static int rk808_rtc_probe(struct platform_device *pdev)
return ret;
}
- /* set init time */
- ret = rk808_rtc_readtime(&pdev->dev, &tm);
- if (ret) {
- dev_err(&pdev->dev, "Failed to read RTC time\n");
- return ret;
- }
- ret = rtc_valid_tm(&tm);
- if (ret)
- dev_warn(&pdev->dev, "invalid date/time\n");
-
device_init_wakeup(&pdev->dev, 1);
- rk808_rtc->rtc = devm_rtc_device_register(&pdev->dev, "rk808-rtc",
- &rk808_rtc_ops, THIS_MODULE);
- if (IS_ERR(rk808_rtc->rtc)) {
- ret = PTR_ERR(rk808_rtc->rtc);
- return ret;
- }
+ rk808_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
+ if (IS_ERR(rk808_rtc->rtc))
+ return PTR_ERR(rk808_rtc->rtc);
+
+ rk808_rtc->rtc->ops = &rk808_rtc_ops;
rk808_rtc->irq = platform_get_irq(pdev, 0);
if (rk808_rtc->irq < 0) {
@@ -438,9 +426,10 @@ static int rk808_rtc_probe(struct platform_device *pdev)
if (ret) {
dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",
rk808_rtc->irq, ret);
+ return ret;
}
- return ret;
+ return rtc_register_device(rk808_rtc->rtc);
}
static struct platform_driver rk808_rtc_driver = {
diff --git a/drivers/rtc/rtc-rp5c01.c b/drivers/rtc/rtc-rp5c01.c
index 0260353..f1c160f 100644
--- a/drivers/rtc/rtc-rp5c01.c
+++ b/drivers/rtc/rtc-rp5c01.c
@@ -64,7 +64,6 @@ struct rp5c01_priv {
u32 __iomem *regs;
struct rtc_device *rtc;
spinlock_t lock; /* against concurrent RTC/NVRAM access */
- struct bin_attribute nvram_attr;
};
static inline unsigned int rp5c01_read(struct rp5c01_priv *priv,
@@ -116,7 +115,7 @@ static int rp5c01_read_time(struct device *dev, struct rtc_time *tm)
rp5c01_unlock(priv);
spin_unlock_irq(&priv->lock);
- return rtc_valid_tm(tm);
+ return 0;
}
static int rp5c01_set_time(struct device *dev, struct rtc_time *tm)
@@ -160,17 +159,15 @@ static const struct rtc_class_ops rp5c01_rtc_ops = {
* byte is stored in BLOCK10, the low nibble in BLOCK11.
*/
-static ssize_t rp5c01_nvram_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t pos, size_t size)
+static int rp5c01_nvram_read(void *_priv, unsigned int pos, void *val,
+ size_t bytes)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct rp5c01_priv *priv = dev_get_drvdata(dev);
- ssize_t count;
+ struct rp5c01_priv *priv = _priv;
+ u8 *buf = val;
spin_lock_irq(&priv->lock);
- for (count = 0; count < size; count++) {
+ for (; bytes; bytes--) {
u8 data;
rp5c01_write(priv,
@@ -187,20 +184,18 @@ static ssize_t rp5c01_nvram_read(struct file *filp, struct kobject *kobj,
}
spin_unlock_irq(&priv->lock);
- return count;
+ return 0;
}
-static ssize_t rp5c01_nvram_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t pos, size_t size)
+static int rp5c01_nvram_write(void *_priv, unsigned int pos, void *val,
+ size_t bytes)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct rp5c01_priv *priv = dev_get_drvdata(dev);
- ssize_t count;
+ struct rp5c01_priv *priv = _priv;
+ u8 *buf = val;
spin_lock_irq(&priv->lock);
- for (count = 0; count < size; count++) {
+ for (; bytes; bytes--) {
u8 data = *buf++;
rp5c01_write(priv,
@@ -216,7 +211,7 @@ static ssize_t rp5c01_nvram_write(struct file *filp, struct kobject *kobj,
}
spin_unlock_irq(&priv->lock);
- return count;
+ return 0;
}
static int __init rp5c01_rtc_probe(struct platform_device *dev)
@@ -225,6 +220,14 @@ static int __init rp5c01_rtc_probe(struct platform_device *dev)
struct rp5c01_priv *priv;
struct rtc_device *rtc;
int error;
+ struct nvmem_config nvmem_cfg = {
+ .name = "rp5c01_nvram",
+ .word_size = 1,
+ .stride = 1,
+ .size = RP5C01_MODE,
+ .reg_read = rp5c01_nvram_read,
+ .reg_write = rp5c01_nvram_write,
+ };
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!res)
@@ -238,43 +241,31 @@ static int __init rp5c01_rtc_probe(struct platform_device *dev)
if (!priv->regs)
return -ENOMEM;
- sysfs_bin_attr_init(&priv->nvram_attr);
- priv->nvram_attr.attr.name = "nvram";
- priv->nvram_attr.attr.mode = S_IRUGO | S_IWUSR;
- priv->nvram_attr.read = rp5c01_nvram_read;
- priv->nvram_attr.write = rp5c01_nvram_write;
- priv->nvram_attr.size = RP5C01_MODE;
-
spin_lock_init(&priv->lock);
platform_set_drvdata(dev, priv);
- rtc = devm_rtc_device_register(&dev->dev, "rtc-rp5c01", &rp5c01_rtc_ops,
- THIS_MODULE);
+ rtc = devm_rtc_allocate_device(&dev->dev);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
+
+ rtc->ops = &rp5c01_rtc_ops;
+ rtc->nvram_old_abi = true;
+
priv->rtc = rtc;
- error = sysfs_create_bin_file(&dev->dev.kobj, &priv->nvram_attr);
+ nvmem_cfg.priv = priv;
+ error = rtc_nvmem_register(rtc, &nvmem_cfg);
if (error)
return error;
- return 0;
-}
-
-static int __exit rp5c01_rtc_remove(struct platform_device *dev)
-{
- struct rp5c01_priv *priv = platform_get_drvdata(dev);
-
- sysfs_remove_bin_file(&dev->dev.kobj, &priv->nvram_attr);
- return 0;
+ return rtc_register_device(rtc);
}
static struct platform_driver rp5c01_rtc_driver = {
.driver = {
.name = "rtc-rp5c01",
},
- .remove = __exit_p(rp5c01_rtc_remove),
};
module_platform_driver_probe(rp5c01_rtc_driver, rp5c01_rtc_probe);
diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c
index 9a30698..f2de8b1 100644
--- a/drivers/rtc/rtc-rs5c348.c
+++ b/drivers/rtc/rtc-rs5c348.c
@@ -135,11 +135,6 @@ rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_year = bcd2bin(rxbuf[RS5C348_REG_YEAR]) +
((rxbuf[RS5C348_REG_MONTH] & RS5C348_BIT_Y2K) ? 100 : 0);
- if (rtc_valid_tm(tm) < 0) {
- dev_err(&spi->dev, "retrieved date/time is not valid.\n");
- rtc_time_to_tm(0, tm);
- }
-
return 0;
}
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index d4eff8d..c503832 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -207,8 +207,9 @@ static unsigned rs5c_hr2reg(struct rs5c372 *rs5c, unsigned hour)
return bin2bcd(hour);
}
-static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm)
+static int rs5c372_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct rs5c372 *rs5c = i2c_get_clientdata(client);
int status = rs5c_get_regs(rs5c);
@@ -234,12 +235,12 @@ static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm)
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
- /* rtc might need initialization */
- return rtc_valid_tm(tm);
+ return 0;
}
-static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm)
+static int rs5c372_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct rs5c372 *rs5c = i2c_get_clientdata(client);
unsigned char buf[7];
int addr;
@@ -305,17 +306,6 @@ static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim)
}
#endif
-static int rs5c372_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- return rs5c372_get_datetime(to_i2c_client(dev), tm);
-}
-
-static int rs5c372_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- return rs5c372_set_datetime(to_i2c_client(dev), tm);
-}
-
-
static int rs5c_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -581,7 +571,6 @@ static int rs5c372_probe(struct i2c_client *client,
int err = 0;
int smbus_mode = 0;
struct rs5c372 *rs5c372;
- struct rtc_time tm;
dev_dbg(&client->dev, "%s\n", __func__);
@@ -662,9 +651,6 @@ static int rs5c372_probe(struct i2c_client *client,
goto exit;
}
- if (rs5c372_get_datetime(client, &tm) < 0)
- dev_warn(&client->dev, "clock needs to be set\n");
-
dev_info(&client->dev, "%s found, %s\n",
({ char *s; switch (rs5c372->type) {
case rtc_r2025sd: s = "r2025sd"; break;
diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c
index aae2576..29fc3d2 100644
--- a/drivers/rtc/rtc-rv8803.c
+++ b/drivers/rtc/rtc-rv8803.c
@@ -68,7 +68,6 @@ struct rv8803_data {
struct mutex flags_lock;
u8 ctrl;
enum rv8803_type type;
- struct nvmem_config nvmem_cfg;
};
static int rv8803_read_reg(const struct i2c_client *client, u8 reg)
@@ -528,6 +527,15 @@ static int rv8803_probe(struct i2c_client *client,
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct rv8803_data *rv8803;
int err, flags;
+ struct nvmem_config nvmem_cfg = {
+ .name = "rv8803_nvram",
+ .word_size = 1,
+ .stride = 1,
+ .size = 1,
+ .reg_read = rv8803_nvram_read,
+ .reg_write = rv8803_nvram_write,
+ .priv = client,
+ };
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_I2C_BLOCK)) {
@@ -582,21 +590,6 @@ static int rv8803_probe(struct i2c_client *client,
}
}
- rv8803->nvmem_cfg.name = "rv8803_nvram",
- rv8803->nvmem_cfg.word_size = 1,
- rv8803->nvmem_cfg.stride = 1,
- rv8803->nvmem_cfg.size = 1,
- rv8803->nvmem_cfg.reg_read = rv8803_nvram_read,
- rv8803->nvmem_cfg.reg_write = rv8803_nvram_write,
- rv8803->nvmem_cfg.priv = client;
-
- rv8803->rtc->ops = &rv8803_rtc_ops;
- rv8803->rtc->nvmem_config = &rv8803->nvmem_cfg;
- rv8803->rtc->nvram_old_abi = true;
- err = rtc_register_device(rv8803->rtc);
- if (err)
- return err;
-
err = rv8803_write_reg(rv8803->client, RV8803_EXT, RV8803_EXT_WADA);
if (err)
return err;
@@ -607,6 +600,14 @@ static int rv8803_probe(struct i2c_client *client,
return err;
}
+ rv8803->rtc->ops = &rv8803_rtc_ops;
+ rv8803->rtc->nvram_old_abi = true;
+ err = rtc_register_device(rv8803->rtc);
+ if (err)
+ return err;
+
+ rtc_nvmem_register(rv8803->rtc, &nvmem_cfg);
+
rv8803->rtc->max_user_freq = 1;
return 0;
diff --git a/drivers/rtc/rtc-rx4581.c b/drivers/rtc/rtc-rx4581.c
index de3fe4f8..c59a218 100644
--- a/drivers/rtc/rtc-rx4581.c
+++ b/drivers/rtc/rtc-rx4581.c
@@ -172,11 +172,7 @@ static int rx4581_get_datetime(struct device *dev, struct rtc_time *tm)
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
- err = rtc_valid_tm(tm);
- if (err < 0)
- dev_err(dev, "retrieved date/time is not valid.\n");
-
- return err;
+ return 0;
}
static int rx4581_set_datetime(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-rx6110.c b/drivers/rtc/rtc-rx6110.c
index 7c9c08e..8e322d8 100644
--- a/drivers/rtc/rtc-rx6110.c
+++ b/drivers/rtc/rtc-rx6110.c
@@ -252,7 +252,7 @@ static int rx6110_get_time(struct device *dev, struct rtc_time *tm)
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year);
- return rtc_valid_tm(tm);
+ return 0;
}
static const struct reg_sequence rx6110_default_regs[] = {
diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c
index 5c5938a..7ddc22e 100644
--- a/drivers/rtc/rtc-rx8010.c
+++ b/drivers/rtc/rtc-rx8010.c
@@ -138,7 +138,7 @@ static int rx8010_get_time(struct device *dev, struct rtc_time *dt)
dt->tm_year = bcd2bin(date[RX8010_YEAR - RX8010_SEC]) + 100;
dt->tm_wday = ffs(date[RX8010_WDAY - RX8010_SEC] & 0x7f);
- return rtc_valid_tm(dt);
+ return 0;
}
static int rx8010_set_time(struct device *dev, struct rtc_time *dt)
diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c
index 91857d8..41127ad 100644
--- a/drivers/rtc/rtc-rx8025.c
+++ b/drivers/rtc/rtc-rx8025.c
@@ -214,7 +214,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
dt->tm_sec, dt->tm_min, dt->tm_hour,
dt->tm_mday, dt->tm_mon, dt->tm_year);
- return rtc_valid_tm(dt);
+ return 0;
}
static int rx8025_set_time(struct device *dev, struct rtc_time *dt)
diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c
index 9998d79..32caadf9 100644
--- a/drivers/rtc/rtc-rx8581.c
+++ b/drivers/rtc/rtc-rx8581.c
@@ -164,11 +164,7 @@ static int rx8581_get_datetime(struct i2c_client *client, struct rtc_time *tm)
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
- err = rtc_valid_tm(tm);
- if (err < 0)
- dev_err(&client->dev, "retrieved date/time is not valid.\n");
-
- return err;
+ return 0;
}
static int rx8581_set_datetime(struct i2c_client *client, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
index 7067bca..77feb60 100644
--- a/drivers/rtc/rtc-s35390a.c
+++ b/drivers/rtc/rtc-s35390a.c
@@ -210,8 +210,9 @@ static int s35390a_reg2hr(struct s35390a *s35390a, char reg)
return hour;
}
-static int s35390a_set_datetime(struct i2c_client *client, struct rtc_time *tm)
+static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct s35390a *s35390a = i2c_get_clientdata(client);
int i, err;
char buf[7], status;
@@ -241,8 +242,9 @@ static int s35390a_set_datetime(struct i2c_client *client, struct rtc_time *tm)
return err;
}
-static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm)
+static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct s35390a *s35390a = i2c_get_clientdata(client);
char buf[7], status;
int i, err;
@@ -271,11 +273,12 @@ static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm)
tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year,
tm->tm_wday);
- return rtc_valid_tm(tm);
+ return 0;
}
-static int s35390a_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alm)
+static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct s35390a *s35390a = i2c_get_clientdata(client);
char buf[3], sts = 0;
int err, i;
@@ -329,8 +332,9 @@ static int s35390a_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alm)
return err;
}
-static int s35390a_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alm)
+static int s35390a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct s35390a *s35390a = i2c_get_clientdata(client);
char buf[3], sts;
int i, err;
@@ -384,26 +388,6 @@ static int s35390a_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alm)
return 0;
}
-static int s35390a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
-{
- return s35390a_read_alarm(to_i2c_client(dev), alm);
-}
-
-static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
-{
- return s35390a_set_alarm(to_i2c_client(dev), alm);
-}
-
-static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- return s35390a_get_datetime(to_i2c_client(dev), tm);
-}
-
-static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- return s35390a_set_datetime(to_i2c_client(dev), tm);
-}
-
static int s35390a_rtc_ioctl(struct device *dev, unsigned int cmd,
unsigned long arg)
{
@@ -450,7 +434,6 @@ static int s35390a_probe(struct i2c_client *client,
int err, err_read;
unsigned int i;
struct s35390a *s35390a;
- struct rtc_time tm;
char buf, status1;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
@@ -508,9 +491,6 @@ static int s35390a_probe(struct i2c_client *client,
}
}
- if (err_read > 0 || s35390a_get_datetime(client, &tm) < 0)
- dev_warn(&client->dev, "clock needs to be set\n");
-
device_set_wakeup_capable(&client->dev, 1);
s35390a->rtc = devm_rtc_device_register(&client->dev,
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index a8992c2..75c8c50 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -232,7 +232,7 @@ retry_get_time:
rtc_tm->tm_mon -= 1;
- return rtc_valid_tm(rtc_tm);
+ return 0;
}
static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c
index 0477678..8428455 100644
--- a/drivers/rtc/rtc-s5m.c
+++ b/drivers/rtc/rtc-s5m.c
@@ -38,6 +38,19 @@
*/
#define UDR_READ_RETRY_CNT 5
+enum {
+ RTC_SEC = 0,
+ RTC_MIN,
+ RTC_HOUR,
+ RTC_WEEKDAY,
+ RTC_DATE,
+ RTC_MONTH,
+ RTC_YEAR1,
+ RTC_YEAR2,
+ /* Make sure this is always the last enum name. */
+ RTC_MAX_NUM_TIME_REGS
+};
+
/*
* Registers used by the driver which are different between chipsets.
*
@@ -367,7 +380,7 @@ static void s5m8763_tm_to_data(struct rtc_time *tm, u8 *data)
static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct s5m_rtc_info *info = dev_get_drvdata(dev);
- u8 data[info->regs->regs_count];
+ u8 data[RTC_MAX_NUM_TIME_REGS];
int ret;
if (info->regs->read_time_udr_mask) {
@@ -407,13 +420,13 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
- return rtc_valid_tm(tm);
+ return 0;
}
static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct s5m_rtc_info *info = dev_get_drvdata(dev);
- u8 data[info->regs->regs_count];
+ u8 data[RTC_MAX_NUM_TIME_REGS];
int ret = 0;
switch (info->device_type) {
@@ -450,7 +463,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct s5m_rtc_info *info = dev_get_drvdata(dev);
- u8 data[info->regs->regs_count];
+ u8 data[RTC_MAX_NUM_TIME_REGS];
unsigned int val;
int ret, i;
@@ -500,7 +513,7 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
{
- u8 data[info->regs->regs_count];
+ u8 data[RTC_MAX_NUM_TIME_REGS];
int ret, i;
struct rtc_time tm;
@@ -545,7 +558,7 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
{
int ret;
- u8 data[info->regs->regs_count];
+ u8 data[RTC_MAX_NUM_TIME_REGS];
u8 alarm0_conf;
struct rtc_time tm;
@@ -598,7 +611,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct s5m_rtc_info *info = dev_get_drvdata(dev);
- u8 data[info->regs->regs_count];
+ u8 data[RTC_MAX_NUM_TIME_REGS];
int ret;
switch (info->device_type) {
diff --git a/drivers/rtc/rtc-sc27xx.c b/drivers/rtc/rtc-sc27xx.c
index d544d52..00d87d1 100644
--- a/drivers/rtc/rtc-sc27xx.c
+++ b/drivers/rtc/rtc-sc27xx.c
@@ -376,7 +376,7 @@ static int sprd_rtc_read_time(struct device *dev, struct rtc_time *tm)
return ret;
rtc_time64_to_tm(secs, tm);
- return rtc_valid_tm(tm);
+ return 0;
}
static int sprd_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 6c2d398..4e8ab37 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -414,7 +414,7 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
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);
+ return 0;
}
static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c
index 7367f61..2a9e151 100644
--- a/drivers/rtc/rtc-sirfsoc.c
+++ b/drivers/rtc/rtc-sirfsoc.c
@@ -204,23 +204,6 @@ static int sirfsoc_rtc_set_time(struct device *dev,
return 0;
}
-static int sirfsoc_rtc_ioctl(struct device *dev, unsigned int cmd,
- unsigned long arg)
-{
- switch (cmd) {
- case RTC_PIE_ON:
- case RTC_PIE_OFF:
- case RTC_UIE_ON:
- case RTC_UIE_OFF:
- case RTC_AIE_ON:
- case RTC_AIE_OFF:
- return 0;
-
- default:
- return -ENOIOCTLCMD;
- }
-}
-
static int sirfsoc_rtc_alarm_irq_enable(struct device *dev,
unsigned int enabled)
{
@@ -250,7 +233,6 @@ static const struct rtc_class_ops sirfsoc_rtc_ops = {
.set_time = sirfsoc_rtc_set_time,
.read_alarm = sirfsoc_rtc_read_alarm,
.set_alarm = sirfsoc_rtc_set_alarm,
- .ioctl = sirfsoc_rtc_ioctl,
.alarm_irq_enable = sirfsoc_rtc_alarm_irq_enable
};
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c
index d8ef9e0..9af591d 100644
--- a/drivers/rtc/rtc-snvs.c
+++ b/drivers/rtc/rtc-snvs.c
@@ -132,20 +132,23 @@ static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct snvs_rtc_data *data = dev_get_drvdata(dev);
unsigned long time;
+ int ret;
rtc_tm_to_time(tm, &time);
/* Disable RTC first */
- snvs_rtc_enable(data, false);
+ ret = snvs_rtc_enable(data, false);
+ if (ret)
+ return ret;
/* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */
regmap_write(data->regmap, data->offset + SNVS_LPSRTCLR, time << CNTR_TO_SECS_SH);
regmap_write(data->regmap, data->offset + SNVS_LPSRTCMR, time >> (32 - CNTR_TO_SECS_SH));
/* Enable RTC again */
- snvs_rtc_enable(data, true);
+ ret = snvs_rtc_enable(data, true);
- return 0;
+ return ret;
}
static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
@@ -288,7 +291,11 @@ static int snvs_rtc_probe(struct platform_device *pdev)
regmap_write(data->regmap, data->offset + SNVS_LPSR, 0xffffffff);
/* Enable RTC */
- snvs_rtc_enable(data, true);
+ ret = snvs_rtc_enable(data, true);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to enable rtc %d\n", ret);
+ goto error_rtc_device_register;
+ }
device_init_wakeup(&pdev->dev, true);
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c
index e377f42..0567944 100644
--- a/drivers/rtc/rtc-spear.c
+++ b/drivers/rtc/rtc-spear.c
@@ -170,18 +170,14 @@ static irqreturn_t spear_rtc_irq(int irq, void *dev_id)
}
-static int tm2bcd(struct rtc_time *tm)
+static void tm2bcd(struct rtc_time *tm)
{
- if (rtc_valid_tm(tm) != 0)
- return -EINVAL;
tm->tm_sec = bin2bcd(tm->tm_sec);
tm->tm_min = bin2bcd(tm->tm_min);
tm->tm_hour = bin2bcd(tm->tm_hour);
tm->tm_mday = bin2bcd(tm->tm_mday);
tm->tm_mon = bin2bcd(tm->tm_mon + 1);
tm->tm_year = bin2bcd(tm->tm_year);
-
- return 0;
}
static void bcd2tm(struct rtc_time *tm)
@@ -237,8 +233,7 @@ static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm)
struct spear_rtc_config *config = dev_get_drvdata(dev);
unsigned int time, date;
- if (tm2bcd(tm) < 0)
- return -EINVAL;
+ tm2bcd(tm);
rtc_wait_not_busy(config);
time = (tm->tm_sec << SECOND_SHIFT) | (tm->tm_min << MINUTE_SHIFT) |
@@ -295,8 +290,7 @@ static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
unsigned int time, date;
int err;
- if (tm2bcd(&alm->time) < 0)
- return -EINVAL;
+ tm2bcd(&alm->time);
rtc_wait_not_busy(config);
diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
index 82b0af1..d522266 100644
--- a/drivers/rtc/rtc-st-lpc.c
+++ b/drivers/rtc/rtc-st-lpc.c
@@ -195,7 +195,6 @@ static int st_rtc_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
struct st_rtc *rtc;
struct resource *res;
- struct rtc_time tm_check;
uint32_t mode;
int ret = 0;
@@ -254,21 +253,6 @@ static int st_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rtc);
- /*
- * The RTC-LPC is able to manage date.year > 2038
- * but currently the kernel can not manage this date!
- * If the RTC-LPC has a date.year > 2038 then
- * it's set to the epoch "Jan 1st 2000"
- */
- st_rtc_read_time(&pdev->dev, &tm_check);
-
- if (tm_check.tm_year >= (2038 - 1900)) {
- memset(&tm_check, 0, sizeof(tm_check));
- tm_check.tm_year = 100;
- tm_check.tm_mday = 1;
- st_rtc_set_time(&pdev->dev, &tm_check);
- }
-
rtc->rtc_dev = rtc_device_register("st-lpc-rtc", &pdev->dev,
&st_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc_dev)) {
diff --git a/drivers/rtc/rtc-starfire.c b/drivers/rtc/rtc-starfire.c
index 7fc3697..a7d4932 100644
--- a/drivers/rtc/rtc-starfire.c
+++ b/drivers/rtc/rtc-starfire.c
@@ -28,7 +28,7 @@ static u32 starfire_get_time(void)
static int starfire_read_time(struct device *dev, struct rtc_time *tm)
{
rtc_time_to_tm(starfire_get_time(), tm);
- return rtc_valid_tm(tm);
+ return 0;
}
static const struct rtc_class_ops starfire_rtc_ops = {
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c
index a456cb6..e70b78d 100644
--- a/drivers/rtc/rtc-stk17ta8.c
+++ b/drivers/rtc/rtc-stk17ta8.c
@@ -129,10 +129,6 @@ static int stk17ta8_rtc_read_time(struct device *dev, struct rtc_time *tm)
/* year is 1900 + tm->tm_year */
tm->tm_year = bcd2bin(year) + bcd2bin(century) * 100 - 1900;
- if (rtc_valid_tm(tm) < 0) {
- dev_err(dev, "retrieved date/time is not valid.\n");
- rtc_time_to_tm(0, tm);
- }
return 0;
}
@@ -242,46 +238,30 @@ static const struct rtc_class_ops stk17ta8_rtc_ops = {
.alarm_irq_enable = stk17ta8_rtc_alarm_irq_enable,
};
-static ssize_t stk17ta8_nvram_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t pos, size_t size)
+static int stk17ta8_nvram_read(void *priv, unsigned int pos, void *val,
+ size_t bytes)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct platform_device *pdev = to_platform_device(dev);
- struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+ struct rtc_plat_data *pdata = priv;
void __iomem *ioaddr = pdata->ioaddr;
- ssize_t count;
+ u8 *buf = val;
- for (count = 0; count < size; count++)
+ for (; bytes; bytes--)
*buf++ = readb(ioaddr + pos++);
- return count;
+ return 0;
}
-static ssize_t stk17ta8_nvram_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t pos, size_t size)
+static int stk17ta8_nvram_write(void *priv, unsigned int pos, void *val,
+ size_t bytes)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct platform_device *pdev = to_platform_device(dev);
- struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+ struct rtc_plat_data *pdata = priv;
void __iomem *ioaddr = pdata->ioaddr;
- ssize_t count;
+ u8 *buf = val;
- for (count = 0; count < size; count++)
+ for (; bytes; bytes--)
writeb(*buf++, ioaddr + pos++);
- return count;
+ return 0;
}
-static struct bin_attribute stk17ta8_nvram_attr = {
- .attr = {
- .name = "nvram",
- .mode = S_IRUGO | S_IWUSR,
- },
- .size = RTC_OFFSET,
- .read = stk17ta8_nvram_read,
- .write = stk17ta8_nvram_write,
-};
-
static int stk17ta8_rtc_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -290,6 +270,14 @@ static int stk17ta8_rtc_probe(struct platform_device *pdev)
struct rtc_plat_data *pdata;
void __iomem *ioaddr;
int ret = 0;
+ struct nvmem_config nvmem_cfg = {
+ .name = "stk17ta8_nvram",
+ .word_size = 1,
+ .stride = 1,
+ .size = RTC_OFFSET,
+ .reg_read = stk17ta8_nvram_read,
+ .reg_write = stk17ta8_nvram_write,
+ };
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@@ -328,24 +316,19 @@ static int stk17ta8_rtc_probe(struct platform_device *pdev)
}
}
- pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
- &stk17ta8_rtc_ops, THIS_MODULE);
+ pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(pdata->rtc))
return PTR_ERR(pdata->rtc);
- ret = sysfs_create_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr);
+ pdata->rtc->ops = &stk17ta8_rtc_ops;
+ pdata->rtc->nvram_old_abi = true;
- return ret;
-}
+ nvmem_cfg.priv = pdata;
+ ret = rtc_nvmem_register(pdata->rtc, &nvmem_cfg);
+ if (ret)
+ return ret;
-static int stk17ta8_rtc_remove(struct platform_device *pdev)
-{
- struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
-
- sysfs_remove_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr);
- if (pdata->irq > 0)
- writeb(0, pdata->ioaddr + RTC_INTERRUPTS);
- return 0;
+ return rtc_register_device(pdata->rtc);
}
/* work with hotplug and coldplug */
@@ -353,7 +336,6 @@ MODULE_ALIAS("platform:stk17ta8");
static struct platform_driver stk17ta8_rtc_driver = {
.probe = stk17ta8_rtc_probe,
- .remove = stk17ta8_rtc_remove,
.driver = {
.name = "stk17ta8",
},
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 5bc28ee..2e6fb27 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -349,7 +349,7 @@ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
*/
rtc_tm->tm_year += SUN6I_YEAR_OFF;
- return rtc_valid_tm(rtc_tm);
+ return 0;
}
static int sun6i_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
diff --git a/drivers/rtc/rtc-sunxi.c b/drivers/rtc/rtc-sunxi.c
index abada60..dadbf8b 100644
--- a/drivers/rtc/rtc-sunxi.c
+++ b/drivers/rtc/rtc-sunxi.c
@@ -261,7 +261,7 @@ static int sunxi_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
*/
rtc_tm->tm_year += SUNXI_YEAR_OFF(chip->data_year);
- return rtc_valid_tm(rtc_tm);
+ return 0;
}
static int sunxi_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index 92ff2ed..454da38 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -248,6 +248,14 @@ offset_store(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RW(offset);
+static ssize_t
+range_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "[%lld,%llu]\n", to_rtc_device(dev)->range_min,
+ to_rtc_device(dev)->range_max);
+}
+static DEVICE_ATTR_RO(range);
+
static struct attribute *rtc_attrs[] = {
&dev_attr_name.attr,
&dev_attr_date.attr,
@@ -257,6 +265,7 @@ static struct attribute *rtc_attrs[] = {
&dev_attr_hctosys.attr,
&dev_attr_wakealarm.attr,
&dev_attr_offset.attr,
+ &dev_attr_range.attr,
NULL,
};
@@ -286,6 +295,9 @@ static umode_t rtc_attr_is_visible(struct kobject *kobj,
} else if (attr == &dev_attr_offset.attr) {
if (!rtc->ops->set_offset)
mode = 0;
+ } else if (attr == &dev_attr_range.attr) {
+ if (!(rtc->range_max - rtc->range_min))
+ mode = 0;
}
return mode;
diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c
index d30d57b..66efff6 100644
--- a/drivers/rtc/rtc-tegra.c
+++ b/drivers/rtc/rtc-tegra.c
@@ -144,10 +144,6 @@ static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm)
int ret;
/* convert tm to seconds. */
- ret = rtc_valid_tm(tm);
- if (ret)
- return ret;
-
rtc_tm_to_time(tm, &sec);
dev_vdbg(dev, "time set to %lu. %d/%d/%d %d:%02u:%02u\n",
diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c
index a3418a8..d7785ae 100644
--- a/drivers/rtc/rtc-tps6586x.c
+++ b/drivers/rtc/rtc-tps6586x.c
@@ -90,7 +90,7 @@ static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm)
seconds = ticks >> 10;
seconds += rtc->epoch_start;
rtc_time_to_tm(seconds, tm);
- return rtc_valid_tm(tm);
+ return 0;
}
static int tps6586x_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c
index 560d9a5..08dbefc 100644
--- a/drivers/rtc/rtc-tx4939.c
+++ b/drivers/rtc/rtc-tx4939.c
@@ -14,7 +14,30 @@
#include <linux/module.h>
#include <linux/io.h>
#include <linux/gfp.h>
-#include <asm/txx9/tx4939.h>
+
+#define TX4939_RTCCTL_ALME 0x00000080
+#define TX4939_RTCCTL_ALMD 0x00000040
+#define TX4939_RTCCTL_BUSY 0x00000020
+
+#define TX4939_RTCCTL_COMMAND 0x00000007
+#define TX4939_RTCCTL_COMMAND_NOP 0x00000000
+#define TX4939_RTCCTL_COMMAND_GETTIME 0x00000001
+#define TX4939_RTCCTL_COMMAND_SETTIME 0x00000002
+#define TX4939_RTCCTL_COMMAND_GETALARM 0x00000003
+#define TX4939_RTCCTL_COMMAND_SETALARM 0x00000004
+
+#define TX4939_RTCTBC_PM 0x00000080
+#define TX4939_RTCTBC_COMP 0x0000007f
+
+#define TX4939_RTC_REG_RAMSIZE 0x00000100
+#define TX4939_RTC_REG_RWBSIZE 0x00000006
+
+struct tx4939_rtc_reg {
+ __u32 ctl;
+ __u32 adr;
+ __u32 dat;
+ __u32 tbc;
+};
struct tx4939rtc_plat_data {
struct rtc_device *rtc;
@@ -86,9 +109,10 @@ static int tx4939_rtc_read_time(struct device *dev, struct rtc_time *tm)
for (i = 2; i < 6; i++)
buf[i] = __raw_readl(&rtcreg->dat);
spin_unlock_irq(&pdata->lock);
- sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2];
+ sec = ((unsigned long)buf[5] << 24) | (buf[4] << 16) |
+ (buf[3] << 8) | buf[2];
rtc_time_to_tm(sec, tm);
- return rtc_valid_tm(tm);
+ return 0;
}
static int tx4939_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
@@ -147,7 +171,8 @@ static int tx4939_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
alrm->enabled = (ctl & TX4939_RTCCTL_ALME) ? 1 : 0;
alrm->pending = (ctl & TX4939_RTCCTL_ALMD) ? 1 : 0;
spin_unlock_irq(&pdata->lock);
- sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2];
+ sec = ((unsigned long)buf[5] << 24) | (buf[4] << 16) |
+ (buf[3] << 8) | buf[2];
rtc_time_to_tm(sec, &alrm->time);
return rtc_valid_tm(&alrm->time);
}
@@ -189,58 +214,52 @@ static const struct rtc_class_ops tx4939_rtc_ops = {
.alarm_irq_enable = tx4939_rtc_alarm_irq_enable,
};
-static ssize_t tx4939_rtc_nvram_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t pos, size_t size)
+static int tx4939_nvram_read(void *priv, unsigned int pos, void *val,
+ size_t bytes)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev);
+ struct tx4939rtc_plat_data *pdata = priv;
struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
- ssize_t count;
+ u8 *buf = val;
spin_lock_irq(&pdata->lock);
- for (count = 0; count < size; count++) {
+ for (; bytes; bytes--) {
__raw_writel(pos++, &rtcreg->adr);
*buf++ = __raw_readl(&rtcreg->dat);
}
spin_unlock_irq(&pdata->lock);
- return count;
+ return 0;
}
-static ssize_t tx4939_rtc_nvram_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t pos, size_t size)
+static int tx4939_nvram_write(void *priv, unsigned int pos, void *val,
+ size_t bytes)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev);
+ struct tx4939rtc_plat_data *pdata = priv;
struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
- ssize_t count;
+ u8 *buf = val;
spin_lock_irq(&pdata->lock);
- for (count = 0; count < size; count++) {
+ for (; bytes; bytes--) {
__raw_writel(pos++, &rtcreg->adr);
__raw_writel(*buf++, &rtcreg->dat);
}
spin_unlock_irq(&pdata->lock);
- return count;
+ return 0;
}
-static struct bin_attribute tx4939_rtc_nvram_attr = {
- .attr = {
- .name = "nvram",
- .mode = S_IRUGO | S_IWUSR,
- },
- .size = TX4939_RTC_REG_RAMSIZE,
- .read = tx4939_rtc_nvram_read,
- .write = tx4939_rtc_nvram_write,
-};
-
static int __init tx4939_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
struct tx4939rtc_plat_data *pdata;
struct resource *res;
int irq, ret;
+ struct nvmem_config nvmem_cfg = {
+ .name = "rv8803_nvram",
+ .word_size = 4,
+ .stride = 4,
+ .size = TX4939_RTC_REG_RAMSIZE,
+ .reg_read = tx4939_nvram_read,
+ .reg_write = tx4939_nvram_write,
+ };
irq = platform_get_irq(pdev, 0);
if (irq < 0)
@@ -260,21 +279,27 @@ static int __init tx4939_rtc_probe(struct platform_device *pdev)
if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt,
0, pdev->name, &pdev->dev) < 0)
return -EBUSY;
- rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
- &tx4939_rtc_ops, THIS_MODULE);
+ rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
+
+ rtc->ops = &tx4939_rtc_ops;
+ rtc->nvram_old_abi = true;
+
pdata->rtc = rtc;
- ret = sysfs_create_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr);
- return ret;
+ nvmem_cfg.priv = pdata;
+ ret = rtc_nvmem_register(rtc, &nvmem_cfg);
+ if (ret)
+ return ret;
+
+ return rtc_register_device(rtc);
}
static int __exit tx4939_rtc_remove(struct platform_device *pdev)
{
struct tx4939rtc_plat_data *pdata = platform_get_drvdata(pdev);
- sysfs_remove_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr);
spin_lock_irq(&pdata->lock);
tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP);
spin_unlock_irq(&pdata->lock);
diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c
index 75aea4c..7b824da 100644
--- a/drivers/rtc/rtc-wm831x.c
+++ b/drivers/rtc/rtc-wm831x.c
@@ -156,7 +156,7 @@ static int wm831x_rtc_readtime(struct device *dev, struct rtc_time *tm)
u32 time = (time1[0] << 16) | time1[1];
rtc_time_to_tm(time, tm);
- return rtc_valid_tm(tm);
+ return 0;
}
} while (++count < WM831X_GET_TIME_RETRIES);
diff --git a/drivers/rtc/rtc-xgene.c b/drivers/rtc/rtc-xgene.c
index 0c34d3b..1538208 100644
--- a/drivers/rtc/rtc-xgene.c
+++ b/drivers/rtc/rtc-xgene.c
@@ -60,7 +60,7 @@ static int xgene_rtc_read_time(struct device *dev, struct rtc_time *tm)
struct xgene_rtc_dev *pdata = dev_get_drvdata(dev);
rtc_time_to_tm(readl(pdata->csr_base + RTC_CCVR), tm);
- return rtc_valid_tm(tm);
+ return 0;
}
static int xgene_rtc_set_mmss(struct device *dev, unsigned long secs)
diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
index da18a8a..fba994d 100644
--- a/drivers/rtc/rtc-zynqmp.c
+++ b/drivers/rtc/rtc-zynqmp.c
@@ -122,7 +122,7 @@ static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
rtc_time64_to_tm(read_time, tm);
}
- return rtc_valid_tm(tm);
+ return 0;
}
static int xlnx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c
index 0c17764..718293d 100644
--- a/drivers/rtc/systohc.c
+++ b/drivers/rtc/systohc.c
@@ -20,7 +20,7 @@
* cases.
*
* -EPROTO is returned if now.tv_nsec is not close enough to *target_nsec.
- (
+ *
* If temporary failure is indicated the caller should try again 'soon'
*/
int rtc_set_ntp_time(struct timespec64 now, unsigned long *target_nsec)
diff --git a/include/linux/mfd/samsung/rtc.h b/include/linux/mfd/samsung/rtc.h
index 48c3c5b..9ed2871 100644
--- a/include/linux/mfd/samsung/rtc.h
+++ b/include/linux/mfd/samsung/rtc.h
@@ -141,15 +141,4 @@ enum s2mps_rtc_reg {
#define WTSR_ENABLE_SHIFT 6
#define WTSR_ENABLE_MASK (1 << WTSR_ENABLE_SHIFT)
-enum {
- RTC_SEC = 0,
- RTC_MIN,
- RTC_HOUR,
- RTC_WEEKDAY,
- RTC_DATE,
- RTC_MONTH,
- RTC_YEAR1,
- RTC_YEAR2,
-};
-
#endif /* __LINUX_MFD_SEC_RTC_H */
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index fc6c90b..4c007f6 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -145,12 +145,17 @@ struct rtc_device {
bool registered;
- struct nvmem_config *nvmem_config;
struct nvmem_device *nvmem;
/* Old ABI support */
bool nvram_old_abi;
struct bin_attribute *nvram;
+ time64_t range_min;
+ timeu64_t range_max;
+ time64_t start_secs;
+ time64_t offset_secs;
+ bool set_start_time;
+
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
struct work_struct uie_task;
struct timer_list uie_timer;
@@ -164,6 +169,11 @@ struct rtc_device {
};
#define to_rtc_device(d) container_of(d, struct rtc_device, dev)
+/* useful timestamps */
+#define RTC_TIMESTAMP_BEGIN_1900 -2208989361LL /* 1900-01-01 00:00:00 */
+#define RTC_TIMESTAMP_BEGIN_2000 946684800LL /* 2000-01-01 00:00:00 */
+#define RTC_TIMESTAMP_END_2099 4102444799LL /* 2099-12-31 23:59:59 */
+
extern struct rtc_device *rtc_device_register(const char *name,
struct device *dev,
const struct rtc_class_ops *ops,
@@ -212,10 +222,6 @@ void rtc_aie_update_irq(void *private);
void rtc_uie_update_irq(void *private);
enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer);
-int rtc_register(rtc_task_t *task);
-int rtc_unregister(rtc_task_t *task);
-int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg);
-
void rtc_timer_init(struct rtc_timer *timer, void (*f)(void *p), void *data);
int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer *timer,
ktime_t expires, ktime_t period);
@@ -271,4 +277,17 @@ extern int rtc_hctosys_ret;
#define rtc_hctosys_ret -ENODEV
#endif
+#ifdef CONFIG_RTC_NVMEM
+int rtc_nvmem_register(struct rtc_device *rtc,
+ struct nvmem_config *nvmem_config);
+void rtc_nvmem_unregister(struct rtc_device *rtc);
+#else
+static inline int rtc_nvmem_register(struct rtc_device *rtc,
+ struct nvmem_config *nvmem_config)
+{
+ return -ENODEV;
+}
+static inline void rtc_nvmem_unregister(struct rtc_device *rtc) {}
+#endif
+
#endif /* _LINUX_RTC_H_ */
diff --git a/include/trace/events/rtc.h b/include/trace/events/rtc.h
new file mode 100644
index 0000000..621333f
--- /dev/null
+++ b/include/trace/events/rtc.h
@@ -0,0 +1,206 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM rtc
+
+#if !defined(_TRACE_RTC_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_RTC_H
+
+#include <linux/rtc.h>
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(rtc_time_alarm_class,
+
+ TP_PROTO(time64_t secs, int err),
+
+ TP_ARGS(secs, err),
+
+ TP_STRUCT__entry(
+ __field(time64_t, secs)
+ __field(int, err)
+ ),
+
+ TP_fast_assign(
+ __entry->secs = secs;
+ __entry->err = err;
+ ),
+
+ TP_printk("UTC (%lld) (%d)",
+ __entry->secs, __entry->err
+ )
+);
+
+DEFINE_EVENT(rtc_time_alarm_class, rtc_set_time,
+
+ TP_PROTO(time64_t secs, int err),
+
+ TP_ARGS(secs, err)
+);
+
+DEFINE_EVENT(rtc_time_alarm_class, rtc_read_time,
+
+ TP_PROTO(time64_t secs, int err),
+
+ TP_ARGS(secs, err)
+);
+
+DEFINE_EVENT(rtc_time_alarm_class, rtc_set_alarm,
+
+ TP_PROTO(time64_t secs, int err),
+
+ TP_ARGS(secs, err)
+);
+
+DEFINE_EVENT(rtc_time_alarm_class, rtc_read_alarm,
+
+ TP_PROTO(time64_t secs, int err),
+
+ TP_ARGS(secs, err)
+);
+
+TRACE_EVENT(rtc_irq_set_freq,
+
+ TP_PROTO(int freq, int err),
+
+ TP_ARGS(freq, err),
+
+ TP_STRUCT__entry(
+ __field(int, freq)
+ __field(int, err)
+ ),
+
+ TP_fast_assign(
+ __entry->freq = freq;
+ __entry->err = err;
+ ),
+
+ TP_printk("set RTC periodic IRQ frequency:%u (%d)",
+ __entry->freq, __entry->err
+ )
+);
+
+TRACE_EVENT(rtc_irq_set_state,
+
+ TP_PROTO(int enabled, int err),
+
+ TP_ARGS(enabled, err),
+
+ TP_STRUCT__entry(
+ __field(int, enabled)
+ __field(int, err)
+ ),
+
+ TP_fast_assign(
+ __entry->enabled = enabled;
+ __entry->err = err;
+ ),
+
+ TP_printk("%s RTC 2^N Hz periodic IRQs (%d)",
+ __entry->enabled ? "enable" : "disable",
+ __entry->err
+ )
+);
+
+TRACE_EVENT(rtc_alarm_irq_enable,
+
+ TP_PROTO(unsigned int enabled, int err),
+
+ TP_ARGS(enabled, err),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, enabled)
+ __field(int, err)
+ ),
+
+ TP_fast_assign(
+ __entry->enabled = enabled;
+ __entry->err = err;
+ ),
+
+ TP_printk("%s RTC alarm IRQ (%d)",
+ __entry->enabled ? "enable" : "disable",
+ __entry->err
+ )
+);
+
+DECLARE_EVENT_CLASS(rtc_offset_class,
+
+ TP_PROTO(long offset, int err),
+
+ TP_ARGS(offset, err),
+
+ TP_STRUCT__entry(
+ __field(long, offset)
+ __field(int, err)
+ ),
+
+ TP_fast_assign(
+ __entry->offset = offset;
+ __entry->err = err;
+ ),
+
+ TP_printk("RTC offset: %ld (%d)",
+ __entry->offset, __entry->err
+ )
+);
+
+DEFINE_EVENT(rtc_offset_class, rtc_set_offset,
+
+ TP_PROTO(long offset, int err),
+
+ TP_ARGS(offset, err)
+);
+
+DEFINE_EVENT(rtc_offset_class, rtc_read_offset,
+
+ TP_PROTO(long offset, int err),
+
+ TP_ARGS(offset, err)
+);
+
+DECLARE_EVENT_CLASS(rtc_timer_class,
+
+ TP_PROTO(struct rtc_timer *timer),
+
+ TP_ARGS(timer),
+
+ TP_STRUCT__entry(
+ __field(struct rtc_timer *, timer)
+ __field(ktime_t, expires)
+ __field(ktime_t, period)
+ ),
+
+ TP_fast_assign(
+ __entry->timer = timer;
+ __entry->expires = timer->node.expires;
+ __entry->period = timer->period;
+ ),
+
+ TP_printk("RTC timer:(%p) expires:%lld period:%lld",
+ __entry->timer, __entry->expires, __entry->period
+ )
+);
+
+DEFINE_EVENT(rtc_timer_class, rtc_timer_enqueue,
+
+ TP_PROTO(struct rtc_timer *timer),
+
+ TP_ARGS(timer)
+);
+
+DEFINE_EVENT(rtc_timer_class, rtc_timer_dequeue,
+
+ TP_PROTO(struct rtc_timer *timer),
+
+ TP_ARGS(timer)
+);
+
+DEFINE_EVENT(rtc_timer_class, rtc_timer_fired,
+
+ TP_PROTO(struct rtc_timer *timer),
+
+ TP_ARGS(timer)
+);
+
+#endif /* _TRACE_RTC_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
OpenPOWER on IntegriCloud