Merge tag 'rtc-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 10 Apr 2018 17:22:27 +0000 (10:22 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 10 Apr 2018 17:22:27 +0000 (10:22 -0700)
Pull RTC updates from Alexandre Belloni:
 "This contains a few series that have been in preparation for a while
  and that will help systems with RTCs that will fail in 2038, 2069 or
  2100.

  Subsystem:
   - Add tracepoints
   - Rework of the RTC/nvmem API to allow drivers to discard struct
     nvmem_config after registration
   - New range API, drivers can now expose the useful range of the RTC
   - New offset API the core is now able to add an offset to the RTC
     time, modifying the supported range.
   - Multiple rtc_time64_to_tm fixes
   - Handle time_t overflow on 32 bit platforms in the core instead of
     letting drivers do crazy things.
   - remove rtc_control API

  New driver:
   - Intersil ISL12026

  Drivers:
   - Drivers exposing the RTC non volatile memory have been converted to
     use nvmem
   - Removed useless time and date validation
   - Removed an indirection pattern that was a cargo cult from ancient
     drivers
   - Removed VLA usage
   - Fixed a possible race condition in probe functions
   - AB8540 support is dropped from ab8500
   - pcf85363 now has alarm support"

* tag 'rtc-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (128 commits)
  rtc: snvs: Fix usage of snvs_rtc_enable
  rtc: mt7622: fix module autoloading for OF platform drivers
  rtc: isl12022: use true and false for boolean values
  rtc: ab8500: Drop AB8540 support
  rtc: remove a warning during scripts/kernel-doc step
  rtc: 88pm860x: remove artificial limitation
  rtc: 88pm80x: remove artificial limitation
  rtc: st-lpc: remove artificial limitation
  rtc: mrst: remove artificial limitation
  rtc: mv: remove artificial limitation
  rtc: hctosys: Ensure system time doesn't overflow time_t
  parisc: time: stop validating rtc_time in .read_time
  rtc: pcf85063: fix clearing bits in pcf85063_start_clock
  rtc: at91sam9: Set name of regmap_config
  rtc: s5m: Remove VLA usage
  rtc: s5m: Move enum from rtc.h to rtc-s5m.c
  rtc: remove VLA usage
  rtc: Add useful timestamp definitions
  rtc: Add one offset seconds to expand RTC range
  rtc: Factor out the RTC range validation into rtc_valid_range()
  ...

123 files changed:
Documentation/ABI/testing/sysfs-class-rtc
Documentation/devicetree/bindings/rtc/isil,isl12026.txt [new file with mode: 0644]
MAINTAINERS
arch/parisc/kernel/time.c
drivers/char/rtc.c
drivers/rtc/Kconfig
drivers/rtc/Makefile
drivers/rtc/class.c
drivers/rtc/hctosys.c
drivers/rtc/interface.c
drivers/rtc/nvmem.c
drivers/rtc/rtc-88pm80x.c
drivers/rtc/rtc-88pm860x.c
drivers/rtc/rtc-ab-b5ze-s3.c
drivers/rtc/rtc-ab3100.c
drivers/rtc/rtc-ab8500.c
drivers/rtc/rtc-abx80x.c
drivers/rtc/rtc-ac100.c
drivers/rtc/rtc-at91sam9.c
drivers/rtc/rtc-au1xxx.c
drivers/rtc/rtc-bq32k.c
drivers/rtc/rtc-brcmstb-waketimer.c
drivers/rtc/rtc-cmos.c
drivers/rtc/rtc-coh901331.c
drivers/rtc/rtc-core.h
drivers/rtc/rtc-cpcap.c
drivers/rtc/rtc-cros-ec.c
drivers/rtc/rtc-da9052.c
drivers/rtc/rtc-da9055.c
drivers/rtc/rtc-da9063.c
drivers/rtc/rtc-ds1216.c
drivers/rtc/rtc-ds1286.c
drivers/rtc/rtc-ds1302.c
drivers/rtc/rtc-ds1305.c
drivers/rtc/rtc-ds1307.c
drivers/rtc/rtc-ds1343.c
drivers/rtc/rtc-ds1347.c
drivers/rtc/rtc-ds1390.c
drivers/rtc/rtc-ds1511.c
drivers/rtc/rtc-ds1553.c
drivers/rtc/rtc-ds1685.c
drivers/rtc/rtc-ds1742.c
drivers/rtc/rtc-ds2404.c
drivers/rtc/rtc-ds3232.c
drivers/rtc/rtc-efi.c
drivers/rtc/rtc-fm3130.c
drivers/rtc/rtc-goldfish.c
drivers/rtc/rtc-isl12022.c
drivers/rtc/rtc-isl12026.c [new file with mode: 0644]
drivers/rtc/rtc-isl1208.c
drivers/rtc/rtc-jz4740.c
drivers/rtc/rtc-lib.c
drivers/rtc/rtc-lpc24xx.c
drivers/rtc/rtc-lpc32xx.c
drivers/rtc/rtc-ls1x.c
drivers/rtc/rtc-m41t80.c
drivers/rtc/rtc-m41t93.c
drivers/rtc/rtc-m41t94.c
drivers/rtc/rtc-m48t35.c
drivers/rtc/rtc-m48t59.c
drivers/rtc/rtc-m48t86.c
drivers/rtc/rtc-max6900.c
drivers/rtc/rtc-max6902.c
drivers/rtc/rtc-max6916.c
drivers/rtc/rtc-max77686.c
drivers/rtc/rtc-max8997.c
drivers/rtc/rtc-max8998.c
drivers/rtc/rtc-mc13xxx.c
drivers/rtc/rtc-mcp795.c
drivers/rtc/rtc-mpc5121.c
drivers/rtc/rtc-mrst.c
drivers/rtc/rtc-msm6242.c
drivers/rtc/rtc-mt7622.c
drivers/rtc/rtc-mv.c
drivers/rtc/rtc-mxc_v2.c
drivers/rtc/rtc-nuc900.c
drivers/rtc/rtc-omap.c
drivers/rtc/rtc-pcap.c
drivers/rtc/rtc-pcf2123.c
drivers/rtc/rtc-pcf2127.c
drivers/rtc/rtc-pcf50633.c
drivers/rtc/rtc-pcf85063.c
drivers/rtc/rtc-pcf8523.c
drivers/rtc/rtc-pcf85363.c
drivers/rtc/rtc-pic32.c
drivers/rtc/rtc-pm8xxx.c
drivers/rtc/rtc-ps3.c
drivers/rtc/rtc-r7301.c
drivers/rtc/rtc-r9701.c
drivers/rtc/rtc-rk808.c
drivers/rtc/rtc-rp5c01.c
drivers/rtc/rtc-rs5c348.c
drivers/rtc/rtc-rs5c372.c
drivers/rtc/rtc-rv8803.c
drivers/rtc/rtc-rx4581.c
drivers/rtc/rtc-rx6110.c
drivers/rtc/rtc-rx8010.c
drivers/rtc/rtc-rx8025.c
drivers/rtc/rtc-rx8581.c
drivers/rtc/rtc-s35390a.c
drivers/rtc/rtc-s3c.c
drivers/rtc/rtc-s5m.c
drivers/rtc/rtc-sc27xx.c
drivers/rtc/rtc-sh.c
drivers/rtc/rtc-sirfsoc.c
drivers/rtc/rtc-snvs.c
drivers/rtc/rtc-spear.c
drivers/rtc/rtc-st-lpc.c
drivers/rtc/rtc-starfire.c
drivers/rtc/rtc-stk17ta8.c
drivers/rtc/rtc-sun6i.c
drivers/rtc/rtc-sunxi.c
drivers/rtc/rtc-sysfs.c
drivers/rtc/rtc-tegra.c
drivers/rtc/rtc-tps6586x.c
drivers/rtc/rtc-tx4939.c
drivers/rtc/rtc-wm831x.c
drivers/rtc/rtc-xgene.c
drivers/rtc/rtc-zynqmp.c
drivers/rtc/systohc.c
include/linux/mfd/samsung/rtc.h
include/linux/rtc.h
include/trace/events/rtc.h [new file with mode: 0644]

index cf60412882f0ded5c3cdc577f18cb36b05b1866b..95984289a4ee69fd9990e3d2d05a0d59e8785ac9 100644 (file)
@@ -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 (file)
index 0000000..2e0be45
--- /dev/null
@@ -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>;
+       }
index 6d296bdce3280d29946c106df1941a50f809911b..dd7ce9171ac04d780db5e7da055ef2ad8d522341 100644 (file)
@@ -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
index f7e684560186f9c3d5db133b8e66281c0f3c0e12..c3830400ca28ef1c37f7e9909b1bd7cc011c27af 100644 (file)
@@ -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)
index 0c858d027bf3d606790900190415c78bf3db07be..57dc546628b54d0659d65f4d6f00bb38a8be0efd 100644 (file)
@@ -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.
  */
index 319e3c8976d56055cf69b66287ea669767b8caf0..59e6dede3db36ad0f9891cd1a290f32702709d7f 100644 (file)
@@ -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.
index ee0206becd9fc36f31ed28c8f884089cc5b2ed5f..5ff2fc0c361a84bcabe19642c9232b42cf0c25dd 100644 (file)
@@ -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
index 722d683e0b0f5fd3f024d1da7b65ac61e42320b0..d37588f080556d16af315862b99370ef4a948ea5 100644 (file)
@@ -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));
index e1cfa06810ef275704ab887935b39ca438ae5c3a..e79f2a181ad24217a3e3bc232593184b82d494fd 100644 (file)
@@ -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,
index 672b192f8153aa00665daaefc541ebaf601cfe74..7cbdc9228dd500554ff40fb770b60abf48df6e4f 100644 (file)
 #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;
 }
index 8567b4ed9ac62e9c652ed1b008748219080747a5..17ec4c8d0fad7df6371be15dda833bf6d3e332ea 100644 (file)
@@ -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)
 {
index 466bf7f9a285a5c455a26d199083384d93a4e121..6cbafefa80a2e4cde530895f448daa73969c4f5e 100644 (file)
@@ -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;
        }
index 19e53b3b8e005a430f2c1b96c8565c2a5ddf4c85..01ffc0ef8033f850b864bbc2b9b499b279426303 100644 (file)
@@ -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;
        }
index ef5c16dfabfa489a0464dcf12dd519feb7a4216d..8dc45193244614b1f58fad4ad608bbf9271f6e67 100644 (file)
@@ -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;
 }
index 9b725c55305859b48f5e6f2ffe45088d4b6f0659..821ff52a2222e03f02c7ecc34e8d1bc6de5d18b0 100644 (file)
@@ -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)
index 24a0af650a1bcf6b0c514a3cd186fb5e079ef278..e28f4401fd35a8fe3b4964254d824aaf06e30749 100644 (file)
 #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);
index b033bc556f5d29b4d803ff6506685c3dc940aee1..2cefa67a1132d171404a13b365f0fcffa19aac37 100644 (file)
@@ -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)
index 8ff9dc3fe5bf06ea15a2321df4a4383d32414527..3fe576fdd45e0782a1ecead2931ddf95d76d8a8d 100644 (file)
@@ -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)
index 7418a763ce5202b37f96b0cf26863400aa953982..ee71e647fd4338fe307b84b2c56701f6b64b5478 100644 (file)
@@ -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,
index 2ba44ccb9c3a3fe00e3e9bf2c740845001011b79..7c5530c71285bd05e429ca51c820bd21a54053c4 100644 (file)
@@ -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)
index 98ac8d5c7901a59f438cb2ec83670caa54ce80fe..ef52741000a86e694c2c0ab7e8d25d4f5edc80ed 100644 (file)
 #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)
index 6cee61201c30cb4a15eef3fbd72a7df57313e04b..bdd6674a1054858eefcfea54d445d68d9d1ebec6 100644 (file)
@@ -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);
 }
 
index f7c0f72abb56f98f942cf3e65ac4401305371358..1b3738a11702465f4728a08d14d07e4902970b2e 100644 (file)
@@ -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) {}
index cfc4141d99cde18def976813feba11113111a378..2fc517498a5d85688bce3b28268670508ea176f6 100644 (file)
@@ -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;
index 513b9bedd2c823f617c769ab1581d9aa33649702..0abf98983e13f6353e75e7d732d78a361b189dd7 100644 (file)
@@ -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
index 3a0333e1f21a490a35d64c4e225d7536c7a758b8..a8856f2b9bc22a0409ad2ed95144335113e70894 100644 (file)
@@ -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)
index f0ea6899c7319997772ae275c0adcfdcf4f54f50..bf7ced095c94c7726c0ecebe90d4d9f15ba23c7c 100644 (file)
@@ -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);
index 4273377562ec64dcdf640506fe4b4dd83b413de0..03044e1bc4974ff7e28957413dc4a8d99a0e95ef 100644 (file)
@@ -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);
index 678af8648c45316f22ec7e4d124d1758436022d6..e08cd8130c23013b3d7ab2586b638bc5434c0dce 100644 (file)
@@ -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)
index f85cae240f123eafde246ba1c084c8b6943d171e..b4e054c64bad9e54d23adb3a47da1008224906b3 100644 (file)
@@ -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)
index 9c82b1da2d4593a592f2ddff286556bd6da15ef5..5f158715fb4c96e16d62d7f8eee4e200fdb267f7 100644 (file)
@@ -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)
index ef75c349dff9cf3da5a5c2c692dc4e61b3fe79bf..0744916b79c505836abac02ad556bf5a5a39cf05 100644 (file)
@@ -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)
index 0ec4be62322bfaf7695eb99aa6efd428264a3771..2a881150d51c282802fc168b992448f37b0af66e 100644 (file)
@@ -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
index d8df2e9e14adb94e45a01655ee773cb76f10e28a..2d502fc85698e6203db082327b0cfac806d208be 100644 (file)
@@ -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
index 923dde912f604094219c5860794080888308df1f..a13e59edff530d147a44574f06b351e72d3621f5 100644 (file)
@@ -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);
 
index 895fbeeb47fe1bc78fc79350e6e58b23c50ab64e..5208da4cf94ab2b0e69d374836acb63e83916ca6 100644 (file)
@@ -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;
 
index ccfc9d43eb1e680956d32892e9bacfaddefafd1a..938512c676eed4247bc0e1e15f67f6d36ad54937 100644 (file)
@@ -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)
index 4d5b007d7fc68cfbe71cc6f4c577b5bc4cc357e3..3b095401f848906184ecfd6ef75644ca73eaead2 100644 (file)
@@ -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)
index 1e95312a6f2eecdce510a7cdd79a2b59fa37f037..a7d5ca428d6828692e5dc79c67c76821ea440315 100644 (file)
@@ -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
index 9961ec646fd2f0c2766cf809e7eecd9202085d51..2441b9a2b3662605183263507e75ce071dddf6ae 100644 (file)
@@ -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",
        },
index ed43b431166064770c7486498f75a55a10fe5689..1a39829d2b40358b9313b5e79d1da10f2da5a105 100644 (file)
@@ -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;
 }
 
 /**
index 3abf1cbfb8cee2f57e19f167f2adaf1df1cade17..2d781180e968a12950a2c5fcf9f2f7fa123aa13d 100644 (file)
@@ -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),
index 9a1582ed7070a0ffc9d75d86f353d8383b7594ab..b886b6a5c1785835f3d934500e31e0e2d61a15fc 100644 (file)
@@ -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)
index 0550f7ba464f414d068985d1c58b2d0029754d26..7184e5145f12da07e01a837cef7bf1376cff75fa 100644 (file)
@@ -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)
index 0130afd7fe889e5767660292c2d2f87d58ad2725..3454e7814524a3defaa3ef1c25da4132fa825bb7 100644 (file)
@@ -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)
index 576eadbba296799eca4bc2ad45d13769799a7cf1..e1137670d4d27e846e4ecaecb020275205977230 100644 (file)
@@ -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;
 }
 
 
index d67769265185929c53a48eba64100491f5622cce..a1c44d0c855780f8ba109e79c6bd62cb96dbb40d 100644 (file)
@@ -235,3 +235,5 @@ static struct platform_driver goldfish_rtc = {
 };
 
 module_platform_driver(goldfish_rtc);
+
+MODULE_LICENSE("GPL v2");
index 38586a024ee86f0e3854d534d875d071388a71a6..890ccfc9e5aabe6cd24f08ccacfb3496a054dfb3 100644 (file)
@@ -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 (file)
index 0000000..97f594f
--- /dev/null
@@ -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");
index 8dd299c6a1f338b522f524ee519e5892bf90fe46..1a2c38cc01785c573c5bfeccbf332290020296a9 100644 (file)
@@ -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
index ff65a7d2b9c9366c689d2efa09b5cc99ec3b5735..d0a891777f442b41981e22de3d1021ce5d7a66a9 100644 (file)
@@ -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)
index 1ae7da5cfc608f6c4bcb3764b00683e2a54b7919..4a3c0f3aab1490feef3111c667d21dcfee4e5e62 100644 (file)
@@ -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);
        }
index 59d99596fdebc83981cb23cbad13a9881ab5cb3e..14dc7b04fae04cd5d38933675493529b36b1ef25 100644 (file)
@@ -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)
index 887871c3d5261432e745c61c1fbfe8b50d95ff80..3ba87239aacced31f0fd5f5ac0a2f63ce01bdd0b 100644 (file)
@@ -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)
index e04ca54f21e20791fbf393de0154f4168b3c6026..045af1135e48a4049992ce7e8c176a116fb0f478 100644 (file)
@@ -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)
index c90fba3ed861881c0c813361dfaece9efac60938..ad03e2f12f5d3abacb16174e9dbffc2ad34d8fc4 100644 (file)
@@ -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;
 }
 
index 5ac45fc1a7873f2a7a44560980b8c47152ff146a..4a08a9dabc82d2ec1de0c601bd5e704b08426abc 100644 (file)
@@ -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;
 }
 
 
index 1f0eb79e69f90e279c33be8efc771a357c7ede91..bab82b4be35681ba23463e8112cccd5230428dd2 100644 (file)
@@ -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 = {
index 810f4ea481e4dc4c8f0be4123656f1c5700a13fe..0cf6507de3c728868329d89d52c523b30ae8d36b 100644 (file)
@@ -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)
index d99a705bec07ac28103bc1d19ce52b97ffd25385..216fac62c888e94da57c1b5aa9e97e30237a350f 100644 (file)
@@ -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);
index d9aea9b6d9cd9189767e8ff074d1c78ffabf9ade..a9533535c3b7d0d97140f30863147e97bb55cde0 100644 (file)
@@ -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",
index cbdc86a560bafd6b35eeb94aef65e5aa2f00f01e..ab60f13fa3efdc4105f59c248af39985d26b49fb 100644 (file)
@@ -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,
index 315d09e0f2c1b930bfcf7c1ecc5c5f0181be322c..745827463367a7d845500cd61d7fae09b7502890 100644 (file)
@@ -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)
index 623ab27b2757cda88eb75486a88e87369f0034bc..7e908a490cf691e5deb6b8ac6182eb65d39661f5 100644 (file)
@@ -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)
index 182fdd00e290d3f2ce79b32a99ee99f2ff382f81..cefde273fae6e36494f3e79a7625424ea52422aa 100644 (file)
@@ -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)
index db984d4bf9526bbc78e501ff8da6a7036801872b..e8cee123e8aae3b1c08774d6d01796dd34ef71be 100644 (file)
@@ -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)
index 30804b00985e5f84770189a68eacad9854bea335..d8c0f9b3f87d5e330c943a575eaca6b16b7345f7 100644 (file)
@@ -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)
index 30b8ef6a3676b73973a3fcbe427f1e752f29124c..1f892b238ddbc05094c1ec8da784e22a37a1d4fa 100644 (file)
@@ -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)
index 77f21331ae21c5f098cb7d3f307c294f1a62e889..00e11c1b2186c7e61eb585ec7f97b209e231d0aa 100644 (file)
@@ -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)
index 4ca4daa0b8f32ae3761f759245332d1baccaf8c0..dd0364293bc068cc5dae1ddf064d499d6b98e2f8 100644 (file)
@@ -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)
index 7334c44fa7c3553d61db84570e2a78733d2e24e6..fcb9de5218b20c3842e00781219ce09f95b1f853 100644 (file)
@@ -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;
 
index c1c5c4e3b3b4715ea250a5b16bfaa49e2ebd688b..0c72a2e8ec67d27f5bfd296a7772210371c3d88f 100644 (file)
@@ -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)
index d79b9ae4d237fb4167c9f2e7c1b8b1c395d31202..fd0cea722286bab19d3259e8e037c2d89fe576e2 100644 (file)
@@ -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)
 {
index 79bb28617d458ec99f77518472f2f1505960d2b0..bc52dbb0c0e2c0f04f9239e3a998185239c513f8 100644 (file)
@@ -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);
index 784221dfc9c7ad1634fca0d8829e8f603ddf7bb5..9e14efb990b24d6873d3499ed582116b60092c5a 100644 (file)
@@ -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;
 
index 4ed81117cf5f346d663d11f0a799df4bd3801926..7da664a771817a164c752579c5e4f1647263f839 100644 (file)
@@ -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)
index 09ef802d6e544146fa5ccc1dcf969a1fc378d72d..39086398833e0f8ea95d272f91e4f09fec7cf68f 100644 (file)
@@ -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:
index c4433240d8a91180f8ad9bafc4c14456cd426213..c05f524ba9afa880e221b756c2ca44e6ecec573f 100644 (file)
@@ -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)
index 8895f77726e8da5444afcd602dceff8f25a9b3fd..e5222c5d822389b25d746607a45ccfbcfe3493ce 100644 (file)
@@ -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)
index f33447c5db85e395ac540f43c1bf7ec69f48efcf..e83be1852c2fb276b25f1ff112e2be240e5aae0c 100644 (file)
@@ -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)
index 00c31c91b245fb080b5312cc2d7499268d3b1a4b..ef72b0c389d79ed01566550f2d67094e2c89a448 100644 (file)
@@ -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)
index a06dff994c8316c0062b39d3704055a1305584a8..49bcbb3d4a696160798a3bbaa36a2be8e8e81db2 100644 (file)
@@ -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
index c312af0db72957af5ed4980663fce838ab7cec1c..453615f8ac9a012ea0022227f947f5778c477fdf 100644 (file)
@@ -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)
index ea04e9f0930b697440af845abd7f413aea65093d..c04a1edcd571630f49ccfd26b558e2aba06516f9 100644 (file)
 #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[] = {
index 5cfb6df5c43032e294ccc5a610637ba6e049b27f..3c08eab4f1a81838f49e83df13eddd1a0bafff7b 100644 (file)
@@ -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)
index fac835530671ff003657a5807f750a73586be87e..29358a04592581c537d4d30fed775ecb81222175 100644 (file)
@@ -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);
index 6a8f5d758eac658f883378f3cee8b4fee2124486..347288bff43896c7dcc11eee61d311e8cf13040a 100644 (file)
@@ -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)
index 500e8c8a2605aa83c3e068e1ee2513d3704f4e30..169704b2ce1332923bd7a623846c7031bc597c28 100644 (file)
@@ -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)
index b6c5eb97051c4443913a3fde38380441a7f6e18f..a39ccd1cf6e8f5f50d2a73bf9028c390f5c21d26 100644 (file)
@@ -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)
index 35c9aada07c8ef3a19f44cf8d4a3e8811f484e3f..739c0d42e835321a8273d1371df361012281e7cb 100644 (file)
@@ -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 = {
index 026035373ae65a446122c6ebf39df9364b58718a..f1c160fe7d37e55a566a782498928a90431baed6 100644 (file)
@@ -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);
index 9a306983aabaecefe0633aaaf7fb563606691fdd..f2de8b17e7e36541dcf52653d37188eb4cec9de2 100644 (file)
@@ -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;
 }
 
index d4eff8d7131fd171769cc4238e8f550758e30b53..c5038329058c098487c1f77f7272b6ccfaaaab85 100644 (file)
@@ -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;
index aae2576741a61585a9624217fa2a6cd1d26510e1..29fc3d210392387ec27814500fcc215a3c838682 100644 (file)
@@ -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;
index de3fe4f8d133d6924dccc6f39b81483b71ff0847..c59a218bdd872687c0271d2491564db7a033b070 100644 (file)
@@ -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)
index 7c9c08eab5e5b6baf52d0bafcf86d3d92698c693..8e322d884cc27fe6c711305ef6b6bc6571a7d820 100644 (file)
@@ -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[] = {
index 5c5938ab3d86bcb0bef62e9425553cce800b9d2b..7ddc22eb5b0fad3216dff4981541e1c4c419b24b 100644 (file)
@@ -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)
index 91857d8d2df8707a75a0f931d5ba6afb6ed45afe..41127adf57655083f3e85eb773517725dab00bf0 100644 (file)
@@ -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)
index 9998d7937688c6e27d351c846cdfe16b978b48ef..32caadf912ca2db422af86cd15847c28c2c71e04 100644 (file)
@@ -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)
index 7067bca5c20d9d2c57777f40714db95b0c9a2fa0..77feb603cd4c0b363cf57abad36fb03b30f61cb7 100644 (file)
@@ -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,
index a8992c227f611807c998bbe81c434d9388cfd33f..75c8c5033e0877bc313527491df9a2e9edf21d3c 100644 (file)
@@ -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)
index 0477678d968fd1ccdec8e36784e57e05910364dc..8428455432ca77c89790256cab801ab055c3fdd0 100644 (file)
  */
 #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) {
index d544d5268757b5b1c429cabb8e2b37ad5c59e7e1..00d87d138984b230623bd16cf31184e33d178ee9 100644 (file)
@@ -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)
index 6c2d3989f967baff96625ab39d0d19336b002def..4e8ab370ce63bb4ca097e35c21f7f99513073770 100644 (file)
@@ -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)
index 7367f617145cdeb4694d319ae0a1fb543a94f6b8..2a9e151cae992ae321b9ec384386fd9ff8b58ace 100644 (file)
@@ -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
 };
 
index d8ef9e052c4fc71f38a871a8293271cb469d495b..9af591d5223c3af8c6293a5f20704dc1da20d76e 100644 (file)
@@ -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);
 
index e377f42abae7ae952e2651aaa4805057d1d230c0..0567944fd4f89ada811158b0315e2eb473ce4f48 100644 (file)
@@ -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);
 
index 82b0af159a28221cff367964b27206e8b402385d..d5222667f892ba892f2dec0074fe4be96e3a518d 100644 (file)
@@ -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)) {
index 7fc36973fa330e4845b84f688800d6903556de38..a7d49329d62668c271cacbfa3d15cee18bedbf7f 100644 (file)
@@ -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 = {
index a456cb6177ea46120c96d07fb0fcf77ad38d5226..e70b78d17a98b01c83521c2a13fe2e4594fb87a6 100644 (file)
@@ -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",
        },
index 5bc28eed1adf591a5c32f35e23968bf7b31f2ed5..2e6fb275acc82733de30da185cba99f83368acbb 100644 (file)
@@ -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)
index abada609ddc736c8fdb7af2b1009e44aafa544b4..dadbf8b324ad24366c1f38db5195de03ab344e42 100644 (file)
@@ -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)
index 92ff2edb86a653afecda26f6ec9422715fb78e79..454da38c60122d3a91ffb3fef3369b7de3f6e203 100644 (file)
@@ -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;
index d30d57b048d36ccb5c9ab3285e196d4e168207fc..66efff60c4d53d624834963bbd1a9dcd08c67a4a 100644 (file)
@@ -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",
index a3418a8a37965a909fc4a86cb1cd513d2c9f8c9a..d7785ae0a2b4e2e868d86c56631b557fa912f640 100644 (file)
@@ -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)
index 560d9a5e02253fe3ef5cf159c71d94198498b45c..08dbefc79520e57093cc3fefc9629e2f4200b95a 100644 (file)
 #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);
index 75aea4c4d334bbaef61d8325762b223fa8735e8b..7b824dabf104a2cdfe635d46a88a3ab7d0486da2 100644 (file)
@@ -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);
index 0c34d3b81279e535bbe027e77bce04443bd5b05a..153820876a820033cfebaf9cee45c5ae0162f8a6 100644 (file)
@@ -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)
index da18a8ae3c1ddbb6f56925005019a2bd9a0d75ea..fba994dc31eb406f00c25fc60ee47b1463cf1a5d 100644 (file)
@@ -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)
index 0c177647ea6c71c00d5df725beea9b83c7e4e79e..718293d7242630b409d797cab864f734694006f6 100644 (file)
@@ -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)
index 48c3c5be7eb1ffc90b5860b189b1d964b840dcd0..9ed2871ea335751a2aacf8be178ae3b76d59971a 100644 (file)
@@ -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 */
index fc6c90b57be0afd9f5441425378747635c430a61..4c007f69082f477e8e6a03669e84d61d5f694e35 100644 (file)
@@ -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 (file)
index 0000000..621333f
--- /dev/null
@@ -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>