Merge tag 'rtc-4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 27 Oct 2018 16:24:24 +0000 (09:24 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 27 Oct 2018 16:24:24 +0000 (09:24 -0700)
Pull RTC updates from Alexandre Belloni:
 "This cycle, there were mostly non urgent fixes in drivers. I also
  finally unexported the non managed registration.

  Subsystem:

   - non devm managed registration is now removed from the driver API

   - all the unnecessary rtc_valid_tm() calls have been removed

  Drivers:

   - abx80X: watchdog support

   - cmos: fix non ACPI support

   - sc27xx: fix alarm support

   - Remove a possible sysfs race condition for ab8500, ds1307, ds1685,
     isl1208

   - Fix a possible race condition where an irq handler may be called
     before the rtc_device struct is allocated for mt6397, pl030,
     menelaus, armada38x"

* tag 'rtc-4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (54 commits)
  rtc: sc27xx: Always read normal alarm when registering RTC device
  rtc: sc27xx: Add check to see if need to enable the alarm interrupt
  rtc: sc27xx: Remove interrupts disable and clear in probe()
  rtc: sc27xx: Clear SPG value update interrupt status
  rtc: sc27xx: Set wakeup capability before registering rtc device
  rtc: s35390a: Change buf's type to u8 in s35390a_init
  rtc: ds1307: fix ds1339 wakealarm support
  rtc: ds1685: simplify getting .driver_data
  rtc: m41t80: mark expected switch fall-through
  rtc: tegra: Propagate errors from platform_get_irq()
  rtc: cmos: Remove the `use_acpi_alarm' module parameter for !ACPI
  rtc: cmos: Fix non-ACPI undefined reference to `hpet_rtc_interrupt'
  rtc: mv: let the core handle invalid alarms
  rtc: vr41xx: switch to rtc_time64_to_tm/rtc_tm_to_time64
  rtc: ab8500: remove useless check
  rtc: ab8500: let the core handle range
  rtc: ab8500: use rtc_add_group
  rtc: rs5c348: report error when time is invalid
  rtc: rs5c348: remove forward declaration
  rtc: rs5c348: remove useless label
  ...

33 files changed:
arch/mips/Kconfig
drivers/char/Kconfig
drivers/rtc/Kconfig
drivers/rtc/Makefile
drivers/rtc/class.c
drivers/rtc/interface.c
drivers/rtc/rtc-ab8500.c
drivers/rtc/rtc-abx80x.c
drivers/rtc/rtc-armada38x.c
drivers/rtc/rtc-cmos.c
drivers/rtc/rtc-core.h
drivers/rtc/rtc-ds1307.c
drivers/rtc/rtc-ds1685.c
drivers/rtc/rtc-isl1208.c
drivers/rtc/rtc-lib.c
drivers/rtc/rtc-m41t80.c
drivers/rtc/rtc-mrst.c
drivers/rtc/rtc-mt6397.c
drivers/rtc/rtc-mv.c
drivers/rtc/rtc-omap.c
drivers/rtc/rtc-pl030.c
drivers/rtc/rtc-pl031.c
drivers/rtc/rtc-rs5c348.c
drivers/rtc/rtc-rv8803.c
drivers/rtc/rtc-s35390a.c
drivers/rtc/rtc-sc27xx.c
drivers/rtc/rtc-sun6i.c
drivers/rtc/rtc-sysfs.c
drivers/rtc/rtc-tegra.c
drivers/rtc/rtc-test.c
drivers/rtc/rtc-tx4939.c
drivers/rtc/rtc-vr41xx.c
include/linux/rtc.h

index 53e75dd..80778b4 100644 (file)
@@ -75,7 +75,7 @@ config MIPS
        select MODULES_USE_ELF_RELA if MODULES && 64BIT
        select MODULES_USE_ELF_REL if MODULES
        select PERF_USE_VMALLOC
-       select RTC_LIB if !MACH_LOONGSON64
+       select RTC_LIB
        select SYSCTL_EXCEPTION_TRACE
        select VIRT_TO_BUS
        select NO_BOOTMEM
index 4072849..9d03b2f 100644 (file)
@@ -268,7 +268,7 @@ if RTC_LIB=n
 
 config RTC
        tristate "Enhanced Real Time Clock Support (legacy PC RTC driver)"
-       depends on ALPHA || (MIPS && MACH_LOONGSON64)
+       depends on ALPHA
        ---help---
          If you say Y here and create a character special file /dev/rtc with
          major number 10 and minor number 135 using mknod ("man mknod"), you
index 7d7be60..a819ef0 100644 (file)
@@ -187,6 +187,7 @@ config RTC_DRV_ABB5ZES3
 
 config RTC_DRV_ABX80X
        tristate "Abracon ABx80x"
+       select WATCHDOG_CORE if WATCHDOG
        help
          If you say yes here you get support for Abracon AB080X and AB180X
          families of ultra-low-power  battery- and capacitor-backed real-time
@@ -1007,17 +1008,6 @@ config RTC_DRV_DS17885
 
 endchoice
 
-config RTC_DS1685_PROC_REGS
-       bool "Display register values in /proc"
-       depends on RTC_DRV_DS1685_FAMILY && PROC_FS
-       help
-         Enable this to display a readout of all of the RTC registers in
-         /proc/drivers/rtc.  Keep in mind that this can potentially lead
-         to lost interrupts, as reading Control Register C will clear
-         all pending IRQ flags.
-
-         Unless you are debugging this driver, choose N.
-
 config RTC_DRV_DS1742
        tristate "Maxim/Dallas DS1742/1743"
        depends on HAS_IOMEM
@@ -1587,7 +1577,7 @@ config RTC_DRV_MPC5121
 
 config RTC_DRV_JZ4740
        tristate "Ingenic JZ4740 SoC"
-       depends on MACH_INGENIC || COMPILE_TEST
+       depends on MIPS || COMPILE_TEST
        help
          If you say yes here you get support for the Ingenic JZ47xx SoCs RTC
          controllers.
index 5ff2fc0..290c173 100644 (file)
@@ -36,9 +36,9 @@ obj-$(CONFIG_RTC_DRV_ASM9260) += rtc-asm9260.o
 obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
 obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o
 obj-$(CONFIG_RTC_DRV_AU1XXX)   += rtc-au1xxx.o
-obj-$(CONFIG_RTC_DRV_BRCMSTB)  += rtc-brcmstb-waketimer.o
 obj-$(CONFIG_RTC_DRV_BQ32K)    += rtc-bq32k.o
 obj-$(CONFIG_RTC_DRV_BQ4802)   += rtc-bq4802.o
+obj-$(CONFIG_RTC_DRV_BRCMSTB)  += rtc-brcmstb-waketimer.o
 obj-$(CONFIG_RTC_DRV_CMOS)     += rtc-cmos.o
 obj-$(CONFIG_RTC_DRV_COH901331)        += rtc-coh901331.o
 obj-$(CONFIG_RTC_DRV_CPCAP)    += rtc-cpcap.o
@@ -71,6 +71,7 @@ obj-$(CONFIG_RTC_DRV_EP93XX)  += rtc-ep93xx.o
 obj-$(CONFIG_RTC_DRV_FM3130)   += rtc-fm3130.o
 obj-$(CONFIG_RTC_DRV_FTRTC010) += rtc-ftrtc010.o
 obj-$(CONFIG_RTC_DRV_GENERIC)  += rtc-generic.o
+obj-$(CONFIG_RTC_DRV_GOLDFISH) += rtc-goldfish.o
 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
@@ -78,10 +79,10 @@ 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_LOONGSON1)        += rtc-ls1x.o
 obj-$(CONFIG_RTC_DRV_LP8788)   += rtc-lp8788.o
 obj-$(CONFIG_RTC_DRV_LPC24XX)  += rtc-lpc24xx.o
 obj-$(CONFIG_RTC_DRV_LPC32XX)  += rtc-lpc32xx.o
-obj-$(CONFIG_RTC_DRV_LOONGSON1)        += rtc-ls1x.o
 obj-$(CONFIG_RTC_DRV_M41T80)   += rtc-m41t80.o
 obj-$(CONFIG_RTC_DRV_M41T93)   += rtc-m41t93.o
 obj-$(CONFIG_RTC_DRV_M41T94)   += rtc-m41t94.o
@@ -100,7 +101,6 @@ obj-$(CONFIG_RTC_DRV_MC13XXX)       += rtc-mc13xxx.o
 obj-$(CONFIG_RTC_DRV_MCP795)   += rtc-mcp795.o
 obj-$(CONFIG_RTC_DRV_MOXART)   += rtc-moxart.o
 obj-$(CONFIG_RTC_DRV_MPC5121)  += rtc-mpc5121.o
-obj-$(CONFIG_RTC_DRV_VRTC)     += rtc-mrst.o
 obj-$(CONFIG_RTC_DRV_MSM6242)  += rtc-msm6242.o
 obj-$(CONFIG_RTC_DRV_MT6397)   += rtc-mt6397.o
 obj-$(CONFIG_RTC_DRV_MT7622)   += rtc-mt7622.o
@@ -116,8 +116,8 @@ obj-$(CONFIG_RTC_DRV_PCF2123)       += rtc-pcf2123.o
 obj-$(CONFIG_RTC_DRV_PCF2127)  += rtc-pcf2127.o
 obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o
 obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o
-obj-$(CONFIG_RTC_DRV_PCF85363) += rtc-pcf85363.o
 obj-$(CONFIG_RTC_DRV_PCF8523)  += rtc-pcf8523.o
+obj-$(CONFIG_RTC_DRV_PCF85363) += rtc-pcf85363.o
 obj-$(CONFIG_RTC_DRV_PCF8563)  += rtc-pcf8563.o
 obj-$(CONFIG_RTC_DRV_PCF8583)  += rtc-pcf8583.o
 obj-$(CONFIG_RTC_DRV_PIC32)    += rtc-pic32.o
@@ -154,9 +154,9 @@ obj-$(CONFIG_RTC_DRV_SNVS)  += rtc-snvs.o
 obj-$(CONFIG_RTC_DRV_SPEAR)    += rtc-spear.o
 obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
 obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
+obj-$(CONFIG_RTC_DRV_ST_LPC)   += rtc-st-lpc.o
 obj-$(CONFIG_RTC_DRV_STM32)    += rtc-stm32.o
 obj-$(CONFIG_RTC_DRV_STMP)     += rtc-stmp3xxx.o
-obj-$(CONFIG_RTC_DRV_ST_LPC)   += rtc-st-lpc.o
 obj-$(CONFIG_RTC_DRV_SUN4V)    += rtc-sun4v.o
 obj-$(CONFIG_RTC_DRV_SUN6I)    += rtc-sun6i.o
 obj-$(CONFIG_RTC_DRV_SUNXI)    += rtc-sunxi.o
@@ -169,10 +169,10 @@ obj-$(CONFIG_RTC_DRV_TWL4030)     += rtc-twl.o
 obj-$(CONFIG_RTC_DRV_TX4939)   += rtc-tx4939.o
 obj-$(CONFIG_RTC_DRV_V3020)    += rtc-v3020.o
 obj-$(CONFIG_RTC_DRV_VR41XX)   += rtc-vr41xx.o
+obj-$(CONFIG_RTC_DRV_VRTC)     += rtc-mrst.o
 obj-$(CONFIG_RTC_DRV_VT8500)   += rtc-vt8500.o
 obj-$(CONFIG_RTC_DRV_WM831X)   += rtc-wm831x.o
 obj-$(CONFIG_RTC_DRV_WM8350)   += rtc-wm8350.o
 obj-$(CONFIG_RTC_DRV_X1205)    += rtc-x1205.o
 obj-$(CONFIG_RTC_DRV_XGENE)    += rtc-xgene.o
 obj-$(CONFIG_RTC_DRV_ZYNQMP)   += rtc-zynqmp.o
-obj-$(CONFIG_RTC_DRV_GOLDFISH) += rtc-goldfish.o
index 0fca4d7..3b43787 100644 (file)
@@ -286,9 +286,10 @@ static void rtc_device_get_offset(struct rtc_device *rtc)
  *
  * Returns the pointer to the new struct class device.
  */
-struct rtc_device *rtc_device_register(const char *name, struct device *dev,
-                                       const struct rtc_class_ops *ops,
-                                       struct module *owner)
+static struct rtc_device *rtc_device_register(const char *name,
+                                             struct device *dev,
+                                             const struct rtc_class_ops *ops,
+                                             struct module *owner)
 {
        struct rtc_device *rtc;
        struct rtc_wkalrm alrm;
@@ -351,15 +352,13 @@ exit:
                        name, err);
        return ERR_PTR(err);
 }
-EXPORT_SYMBOL_GPL(rtc_device_register);
-
 
 /**
  * rtc_device_unregister - removes the previously registered RTC class device
  *
  * @rtc: the RTC class device to destroy
  */
-void rtc_device_unregister(struct rtc_device *rtc)
+static void rtc_device_unregister(struct rtc_device *rtc)
 {
        mutex_lock(&rtc->ops_lock);
        /*
@@ -372,7 +371,6 @@ void rtc_device_unregister(struct rtc_device *rtc)
        mutex_unlock(&rtc->ops_lock);
        put_device(&rtc->dev);
 }
-EXPORT_SYMBOL_GPL(rtc_device_unregister);
 
 static void devm_rtc_device_release(struct device *dev, void *res)
 {
index 3d577e2..612a83d 100644 (file)
@@ -596,7 +596,6 @@ EXPORT_SYMBOL_GPL(rtc_update_irq_enable);
  * This function is called when an AIE, UIE or PIE mode interrupt
  * has occurred (or been emulated).
  *
- * Triggers the registered irq_task function callback.
  */
 void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode)
 {
@@ -741,7 +740,6 @@ static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled)
 /**
  * rtc_irq_set_state - enable/disable 2^N Hz periodic IRQs
  * @rtc: the rtc device
- * @task: currently registered with rtc_irq_register()
  * @enabled: true to enable periodic IRQs
  * Context: any
  *
@@ -764,7 +762,6 @@ int rtc_irq_set_state(struct rtc_device *rtc, int enabled)
 /**
  * rtc_irq_set_freq - set 2^N Hz periodic IRQ frequency for IRQ
  * @rtc: the rtc device
- * @task: currently registered with rtc_irq_register()
  * @freq: positive frequency
  * Context: any
  *
index e28f440..1f0cbd5 100644 (file)
@@ -46,7 +46,6 @@
 #define RTC_STATUS_DATA                        0x01
 
 #define COUNTS_PER_SEC                 (0xF000 / 60)
-#define AB8500_RTC_EPOCH               2000
 
 static const u8 ab8500_rtc_time_regs[] = {
        AB8500_RTC_WATCH_TMIN_HI_REG, AB8500_RTC_WATCH_TMIN_MID_REG,
@@ -59,23 +58,6 @@ static const u8 ab8500_rtc_alarm_regs[] = {
        AB8500_RTC_ALRM_MIN_LOW_REG
 };
 
-/* Calculate the seconds from 1970 to 01-01-2000 00:00:00 */
-static unsigned long get_elapsed_seconds(int year)
-{
-       unsigned long secs;
-       struct rtc_time tm = {
-               .tm_year = year - 1900,
-               .tm_mday = 1,
-       };
-
-       /*
-        * This function calculates secs from 1970 and not from
-        * 1900, even if we supply the offset from year 1900.
-        */
-       rtc_tm_to_time(&tm, &secs);
-       return secs;
-}
-
 static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
        unsigned long timeout = jiffies + HZ;
@@ -118,9 +100,6 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
        secs =  secs / COUNTS_PER_SEC;
        secs =  secs + (mins * 60);
 
-       /* Add back the initially subtracted number of seconds */
-       secs += get_elapsed_seconds(AB8500_RTC_EPOCH);
-
        rtc_time_to_tm(secs, tm);
        return 0;
 }
@@ -131,21 +110,8 @@ static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm)
        unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)];
        unsigned long no_secs, no_mins, secs = 0;
 
-       if (tm->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(tm, &secs);
 
-       /*
-        * Convert it to the number of seconds since 01-01-2000 00:00:00, since
-        * we only have a small counter in the RTC.
-        */
-       secs -= get_elapsed_seconds(AB8500_RTC_EPOCH);
-
        no_mins = secs / 60;
 
        no_secs = secs % 60;
@@ -202,12 +168,9 @@ static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
        mins = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
        secs = mins * 60;
 
-       /* Add back the initially subtracted number of seconds */
-       secs += get_elapsed_seconds(AB8500_RTC_EPOCH);
-
        rtc_time_to_tm(secs, &alarm->time);
 
-       return rtc_valid_tm(&alarm->time);
+       return 0;
 }
 
 static int ab8500_rtc_irq_enable(struct device *dev, unsigned int enabled)
@@ -224,12 +187,6 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
        unsigned long mins, secs = 0, cursec = 0;
        struct rtc_time curtm;
 
-       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);
 
@@ -245,12 +202,6 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
                return -EINVAL;
        }
 
-       /*
-        * Convert it to the number of seconds since 01-01-2000 00:00:00, since
-        * we only have a small counter in the RTC.
-        */
-       secs -= get_elapsed_seconds(AB8500_RTC_EPOCH);
-
        mins = secs / 60;
 
        buf[2] = mins & 0xFF;
@@ -360,15 +311,14 @@ static DEVICE_ATTR(rtc_calibration, S_IRUGO | S_IWUSR,
                   ab8500_sysfs_show_rtc_calibration,
                   ab8500_sysfs_store_rtc_calibration);
 
-static int ab8500_sysfs_rtc_register(struct device *dev)
-{
-       return device_create_file(dev, &dev_attr_rtc_calibration);
-}
+static struct attribute *ab8500_rtc_attrs[] = {
+       &dev_attr_rtc_calibration.attr,
+       NULL
+};
 
-static void ab8500_sysfs_rtc_unregister(struct device *dev)
-{
-       device_remove_file(dev, &dev_attr_rtc_calibration);
-}
+static const struct attribute_group ab8500_rtc_sysfs_files = {
+       .attrs  = ab8500_rtc_attrs,
+};
 
 static irqreturn_t rtc_alarm_handler(int irq, void *data)
 {
@@ -429,14 +379,11 @@ static int ab8500_rtc_probe(struct platform_device *pdev)
 
        device_init_wakeup(&pdev->dev, true);
 
-       rtc = devm_rtc_device_register(&pdev->dev, "ab8500-rtc",
-                               (struct rtc_class_ops *)platid->driver_data,
-                               THIS_MODULE);
-       if (IS_ERR(rtc)) {
-               dev_err(&pdev->dev, "Registration failed\n");
-               err = PTR_ERR(rtc);
-               return err;
-       }
+       rtc = devm_rtc_allocate_device(&pdev->dev);
+       if (IS_ERR(rtc))
+               return PTR_ERR(rtc);
+
+       rtc->ops = (struct rtc_class_ops *)platid->driver_data;
 
        err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
                        rtc_alarm_handler, IRQF_ONESHOT,
@@ -447,22 +394,23 @@ static int ab8500_rtc_probe(struct platform_device *pdev)
        dev_pm_set_wake_irq(&pdev->dev, irq);
        platform_set_drvdata(pdev, rtc);
 
-       err = ab8500_sysfs_rtc_register(&pdev->dev);
-       if (err) {
-               dev_err(&pdev->dev, "sysfs RTC failed to register\n");
-               return err;
-       }
-
        rtc->uie_unsupported = 1;
 
-       return 0;
+       rtc->range_max = (1ULL << 24) * 60 - 1; // 24-bit minutes + 59 secs
+       rtc->start_secs = RTC_TIMESTAMP_BEGIN_2000;
+       rtc->set_start_time = true;
+
+       err = rtc_add_group(rtc, &ab8500_rtc_sysfs_files);
+       if (err)
+               return err;
+
+       return rtc_register_device(rtc);
 }
 
 static int ab8500_rtc_remove(struct platform_device *pdev)
 {
        dev_pm_clear_wake_irq(&pdev->dev);
        device_init_wakeup(&pdev->dev, false);
-       ab8500_sysfs_rtc_unregister(&pdev->dev);
 
        return 0;
 }
index 2cefa67..d8e94ed 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/rtc.h>
+#include <linux/watchdog.h>
 
 #define ABX8XX_REG_HTH         0x00
 #define ABX8XX_REG_SC          0x01
@@ -37,6 +38,7 @@
 
 #define ABX8XX_REG_STATUS      0x0f
 #define ABX8XX_STATUS_AF       BIT(2)
+#define ABX8XX_STATUS_WDT      BIT(6)
 
 #define ABX8XX_REG_CTRL1       0x10
 #define ABX8XX_CTRL_WRITE      BIT(0)
 #define ABX8XX_OSS_OF          BIT(1)
 #define ABX8XX_OSS_OMODE       BIT(4)
 
+#define ABX8XX_REG_WDT         0x1b
+#define ABX8XX_WDT_WDS         BIT(7)
+#define ABX8XX_WDT_BMB_MASK    0x7c
+#define ABX8XX_WDT_BMB_SHIFT   2
+#define ABX8XX_WDT_MAX_TIME    (ABX8XX_WDT_BMB_MASK >> ABX8XX_WDT_BMB_SHIFT)
+#define ABX8XX_WDT_WRB_MASK    0x03
+#define ABX8XX_WDT_WRB_1HZ     0x02
+
 #define ABX8XX_REG_CFG_KEY     0x1f
 #define ABX8XX_CFG_KEY_OSC     0xa1
 #define ABX8XX_CFG_KEY_MISC    0x9d
@@ -80,20 +90,27 @@ enum abx80x_chip {AB0801, AB0803, AB0804, AB0805,
 struct abx80x_cap {
        u16 pn;
        bool has_tc;
+       bool has_wdog;
 };
 
 static struct abx80x_cap abx80x_caps[] = {
        [AB0801] = {.pn = 0x0801},
        [AB0803] = {.pn = 0x0803},
-       [AB0804] = {.pn = 0x0804, .has_tc = true},
-       [AB0805] = {.pn = 0x0805, .has_tc = true},
+       [AB0804] = {.pn = 0x0804, .has_tc = true, .has_wdog = true},
+       [AB0805] = {.pn = 0x0805, .has_tc = true, .has_wdog = true},
        [AB1801] = {.pn = 0x1801},
        [AB1803] = {.pn = 0x1803},
-       [AB1804] = {.pn = 0x1804, .has_tc = true},
-       [AB1805] = {.pn = 0x1805, .has_tc = true},
+       [AB1804] = {.pn = 0x1804, .has_tc = true, .has_wdog = true},
+       [AB1805] = {.pn = 0x1805, .has_tc = true, .has_wdog = true},
        [ABX80X] = {.pn = 0}
 };
 
+struct abx80x_priv {
+       struct rtc_device *rtc;
+       struct i2c_client *client;
+       struct watchdog_device wdog;
+};
+
 static int abx80x_is_rc_mode(struct i2c_client *client)
 {
        int flags = 0;
@@ -218,7 +235,8 @@ static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
 static irqreturn_t abx80x_handle_irq(int irq, void *dev_id)
 {
        struct i2c_client *client = dev_id;
-       struct rtc_device *rtc = i2c_get_clientdata(client);
+       struct abx80x_priv *priv = i2c_get_clientdata(client);
+       struct rtc_device *rtc = priv->rtc;
        int status;
 
        status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
@@ -228,6 +246,13 @@ static irqreturn_t abx80x_handle_irq(int irq, void *dev_id)
        if (status & ABX8XX_STATUS_AF)
                rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF);
 
+       /*
+        * It is unclear if we'll get an interrupt before the external
+        * reset kicks in.
+        */
+       if (status & ABX8XX_STATUS_WDT)
+               dev_alert(&client->dev, "watchdog timeout interrupt.\n");
+
        i2c_smbus_write_byte_data(client, ABX8XX_REG_STATUS, 0);
 
        return IRQ_HANDLED;
@@ -529,11 +554,94 @@ static void rtc_calib_remove_sysfs_group(void *_dev)
        sysfs_remove_group(&dev->kobj, &rtc_calib_attr_group);
 }
 
+#ifdef CONFIG_WATCHDOG
+
+static inline u8 timeout_bits(unsigned int timeout)
+{
+       return ((timeout << ABX8XX_WDT_BMB_SHIFT) & ABX8XX_WDT_BMB_MASK) |
+                ABX8XX_WDT_WRB_1HZ;
+}
+
+static int __abx80x_wdog_set_timeout(struct watchdog_device *wdog,
+                                    unsigned int timeout)
+{
+       struct abx80x_priv *priv = watchdog_get_drvdata(wdog);
+       u8 val = ABX8XX_WDT_WDS | timeout_bits(timeout);
+
+       /*
+        * Writing any timeout to the WDT register resets the watchdog timer.
+        * Writing 0 disables it.
+        */
+       return i2c_smbus_write_byte_data(priv->client, ABX8XX_REG_WDT, val);
+}
+
+static int abx80x_wdog_set_timeout(struct watchdog_device *wdog,
+                                  unsigned int new_timeout)
+{
+       int err = 0;
+
+       if (watchdog_hw_running(wdog))
+               err = __abx80x_wdog_set_timeout(wdog, new_timeout);
+
+       if (err == 0)
+               wdog->timeout = new_timeout;
+
+       return err;
+}
+
+static int abx80x_wdog_ping(struct watchdog_device *wdog)
+{
+       return __abx80x_wdog_set_timeout(wdog, wdog->timeout);
+}
+
+static int abx80x_wdog_start(struct watchdog_device *wdog)
+{
+       return __abx80x_wdog_set_timeout(wdog, wdog->timeout);
+}
+
+static int abx80x_wdog_stop(struct watchdog_device *wdog)
+{
+       return __abx80x_wdog_set_timeout(wdog, 0);
+}
+
+static const struct watchdog_info abx80x_wdog_info = {
+       .identity = "abx80x watchdog",
+       .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
+};
+
+static const struct watchdog_ops abx80x_wdog_ops = {
+       .owner = THIS_MODULE,
+       .start = abx80x_wdog_start,
+       .stop = abx80x_wdog_stop,
+       .ping = abx80x_wdog_ping,
+       .set_timeout = abx80x_wdog_set_timeout,
+};
+
+static int abx80x_setup_watchdog(struct abx80x_priv *priv)
+{
+       priv->wdog.parent = &priv->client->dev;
+       priv->wdog.ops = &abx80x_wdog_ops;
+       priv->wdog.info = &abx80x_wdog_info;
+       priv->wdog.min_timeout = 1;
+       priv->wdog.max_timeout = ABX8XX_WDT_MAX_TIME;
+       priv->wdog.timeout = ABX8XX_WDT_MAX_TIME;
+
+       watchdog_set_drvdata(&priv->wdog, priv);
+
+       return devm_watchdog_register_device(&priv->client->dev, &priv->wdog);
+}
+#else
+static int abx80x_setup_watchdog(struct abx80x_priv *priv)
+{
+       return 0;
+}
+#endif
+
 static int abx80x_probe(struct i2c_client *client,
                        const struct i2c_device_id *id)
 {
        struct device_node *np = client->dev.of_node;
-       struct rtc_device *rtc;
+       struct abx80x_priv *priv;
        int i, data, err, trickle_cfg = -EINVAL;
        char buf[7];
        unsigned int part = id->driver_data;
@@ -610,13 +718,24 @@ static int abx80x_probe(struct i2c_client *client,
        if (err)
                return err;
 
-       rtc = devm_rtc_allocate_device(&client->dev);
-       if (IS_ERR(rtc))
-               return PTR_ERR(rtc);
+       priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+       if (priv == NULL)
+               return -ENOMEM;
+
+       priv->rtc = devm_rtc_allocate_device(&client->dev);
+       if (IS_ERR(priv->rtc))
+               return PTR_ERR(priv->rtc);
+
+       priv->rtc->ops = &abx80x_rtc_ops;
+       priv->client = client;
 
-       rtc->ops = &abx80x_rtc_ops;
+       i2c_set_clientdata(client, priv);
 
-       i2c_set_clientdata(client, rtc);
+       if (abx80x_caps[part].has_wdog) {
+               err = abx80x_setup_watchdog(priv);
+               if (err)
+                       return err;
+       }
 
        if (client->irq > 0) {
                dev_info(&client->dev, "IRQ %d supplied\n", client->irq);
@@ -649,7 +768,7 @@ static int abx80x_probe(struct i2c_client *client,
                return err;
        }
 
-       err = rtc_register_device(rtc);
+       err = rtc_register_device(priv->rtc);
 
        return err;
 }
index bde53c8..9e78f00 100644 (file)
@@ -224,7 +224,7 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
        time = rtc->data->read_rtc_reg(rtc, RTC_TIME);
        spin_unlock_irqrestore(&rtc->lock, flags);
 
-       rtc_time_to_tm(time, tm);
+       rtc_time64_to_tm(time, tm);
 
        return 0;
 }
@@ -249,13 +249,9 @@ static void armada38x_rtc_reset(struct armada38x_rtc *rtc)
 static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
        struct armada38x_rtc *rtc = dev_get_drvdata(dev);
-       int ret = 0;
        unsigned long time, flags;
 
-       ret = rtc_tm_to_time(tm, &time);
-
-       if (ret)
-               goto out;
+       time = rtc_tm_to_time64(tm);
 
        if (!rtc->initialized)
                armada38x_rtc_reset(rtc);
@@ -264,8 +260,7 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
        rtc_delayed_write(time, rtc, RTC_TIME);
        spin_unlock_irqrestore(&rtc->lock, flags);
 
-out:
-       return ret;
+       return 0;
 }
 
 static int armada38x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
@@ -284,7 +279,7 @@ static int armada38x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
        spin_unlock_irqrestore(&rtc->lock, flags);
 
        alrm->enabled = val ? 1 : 0;
-       rtc_time_to_tm(time,  &alrm->time);
+       rtc_time64_to_tm(time,  &alrm->time);
 
        return 0;
 }
@@ -295,12 +290,8 @@ static int armada38x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
        u32 reg = ALARM_REG(RTC_ALARM1, rtc->data->alarm);
        u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm);
        unsigned long time, flags;
-       int ret = 0;
 
-       ret = rtc_tm_to_time(&alrm->time, &time);
-
-       if (ret)
-               goto out;
+       time = rtc_tm_to_time64(&alrm->time);
 
        spin_lock_irqsave(&rtc->lock, flags);
 
@@ -313,8 +304,7 @@ static int armada38x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 
        spin_unlock_irqrestore(&rtc->lock, flags);
 
-out:
-       return ret;
+       return 0;
 }
 
 static int armada38x_rtc_alarm_irq_enable(struct device *dev,
@@ -514,7 +504,6 @@ MODULE_DEVICE_TABLE(of, armada38x_rtc_of_match_table);
 
 static __init int armada38x_rtc_probe(struct platform_device *pdev)
 {
-       const struct rtc_class_ops *ops;
        struct resource *res;
        struct armada38x_rtc *rtc;
        const struct of_device_id *match;
@@ -551,6 +540,11 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "no irq\n");
                return rtc->irq;
        }
+
+       rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
+       if (IS_ERR(rtc->rtc_dev))
+               return PTR_ERR(rtc->rtc_dev);
+
        if (devm_request_irq(&pdev->dev, rtc->irq, armada38x_rtc_alarm_irq,
                                0, pdev->name, rtc) < 0) {
                dev_warn(&pdev->dev, "Interrupt not available.\n");
@@ -560,28 +554,26 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
 
        if (rtc->irq != -1) {
                device_init_wakeup(&pdev->dev, 1);
-               ops = &armada38x_rtc_ops;
+               rtc->rtc_dev->ops = &armada38x_rtc_ops;
        } else {
                /*
                 * If there is no interrupt available then we can't
                 * use the alarm
                 */
-               ops = &armada38x_rtc_ops_noirq;
+               rtc->rtc_dev->ops = &armada38x_rtc_ops_noirq;
        }
        rtc->data = (struct armada38x_rtc_data *)match->data;
 
-
        /* Update RTC-MBUS bridge timing parameters */
        rtc->data->update_mbus_timing(rtc);
 
-       rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
-                                               ops, THIS_MODULE);
-       if (IS_ERR(rtc->rtc_dev)) {
-               ret = PTR_ERR(rtc->rtc_dev);
+       rtc->rtc_dev->range_max = U32_MAX;
+
+       ret = rtc_register_device(rtc->rtc_dev);
+       if (ret)
                dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
-               return ret;
-       }
-       return 0;
+
+       return ret;
 }
 
 #ifdef CONFIG_PM_SLEEP
index cd3a241..df0c577 100644 (file)
@@ -50,6 +50,7 @@
 /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
 #include <linux/mc146818rtc.h>
 
+#ifdef CONFIG_ACPI
 /*
  * Use ACPI SCI to replace HPET interrupt for RTC Alarm event
  *
 static bool use_acpi_alarm;
 module_param(use_acpi_alarm, bool, 0444);
 
+static inline int cmos_use_acpi_alarm(void)
+{
+       return use_acpi_alarm;
+}
+#else /* !CONFIG_ACPI */
+
+static inline int cmos_use_acpi_alarm(void)
+{
+       return 0;
+}
+#endif
+
 struct cmos_rtc {
        struct rtc_device       *rtc;
        struct device           *dev;
@@ -167,9 +180,9 @@ static inline int hpet_unregister_irq_handler(irq_handler_t handler)
 #endif
 
 /* Don't use HPET for RTC Alarm event if ACPI Fixed event is used */
-static int use_hpet_alarm(void)
+static inline int use_hpet_alarm(void)
 {
-       return is_hpet_enabled() && !use_acpi_alarm;
+       return is_hpet_enabled() && !cmos_use_acpi_alarm();
 }
 
 /*----------------------------------------------------------------*/
@@ -340,7 +353,7 @@ static void cmos_irq_enable(struct cmos_rtc *cmos, unsigned char mask)
        if (use_hpet_alarm())
                hpet_set_rtc_irq_bit(mask);
 
-       if ((mask & RTC_AIE) && use_acpi_alarm) {
+       if ((mask & RTC_AIE) && cmos_use_acpi_alarm()) {
                if (cmos->wake_on)
                        cmos->wake_on(cmos->dev);
        }
@@ -358,7 +371,7 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask)
        if (use_hpet_alarm())
                hpet_mask_rtc_irq_bit(mask);
 
-       if ((mask & RTC_AIE) && use_acpi_alarm) {
+       if ((mask & RTC_AIE) && cmos_use_acpi_alarm()) {
                if (cmos->wake_off)
                        cmos->wake_off(cmos->dev);
        }
@@ -980,7 +993,7 @@ static int cmos_suspend(struct device *dev)
        }
        spin_unlock_irq(&rtc_lock);
 
-       if ((tmp & RTC_AIE) && !use_acpi_alarm) {
+       if ((tmp & RTC_AIE) && !cmos_use_acpi_alarm()) {
                cmos->enabled_wake = 1;
                if (cmos->wake_on)
                        cmos->wake_on(dev);
@@ -1031,7 +1044,7 @@ static void cmos_check_wkalrm(struct device *dev)
         * ACPI RTC wake event is cleared after resume from STR,
         * ACK the rtc irq here
         */
-       if (t_now >= cmos->alarm_expires && use_acpi_alarm) {
+       if (t_now >= cmos->alarm_expires && cmos_use_acpi_alarm()) {
                cmos_interrupt(0, (void *)cmos->rtc);
                return;
        }
@@ -1053,7 +1066,7 @@ static int __maybe_unused cmos_resume(struct device *dev)
        struct cmos_rtc *cmos = dev_get_drvdata(dev);
        unsigned char tmp;
 
-       if (cmos->enabled_wake && !use_acpi_alarm) {
+       if (cmos->enabled_wake && !cmos_use_acpi_alarm()) {
                if (cmos->wake_off)
                        cmos->wake_off(dev);
                else
@@ -1132,7 +1145,7 @@ static u32 rtc_handler(void *context)
         * Or else, ACPI SCI is enabled during suspend/resume only,
         * update rtc irq in that case.
         */
-       if (use_acpi_alarm)
+       if (cmos_use_acpi_alarm())
                cmos_interrupt(0, (void *)cmos->rtc);
        else {
                /* Fix me: can we use cmos_interrupt() here as well? */
index ccc17a2..0abf989 100644 (file)
@@ -40,23 +40,9 @@ static inline void rtc_proc_del_device(struct rtc_device *rtc)
 
 #ifdef CONFIG_RTC_INTF_SYSFS
 const struct attribute_group **rtc_get_dev_attribute_groups(void);
-int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp);
-int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps);
 #else
 static inline const struct attribute_group **rtc_get_dev_attribute_groups(void)
 {
        return NULL;
 }
-
-static inline
-int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp)
-{
-       return 0;
-}
-
-static inline
-int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps)
-{
-       return 0;
-}
 #endif
index 4b2b462..74b31dc 100644 (file)
@@ -114,6 +114,20 @@ enum ds_type {
 #      define RX8025_BIT_VDET          0x40
 #      define RX8025_BIT_XST           0x20
 
+#define M41TXX_REG_CONTROL     0x07
+#      define M41TXX_BIT_OUT           BIT(7)
+#      define M41TXX_BIT_FT            BIT(6)
+#      define M41TXX_BIT_CALIB_SIGN    BIT(5)
+#      define M41TXX_M_CALIBRATION     GENMASK(4, 0)
+
+/* negative offset step is -2.034ppm */
+#define M41TXX_NEG_OFFSET_STEP_PPB     2034
+/* positive offset step is +4.068ppm */
+#define M41TXX_POS_OFFSET_STEP_PPB     4068
+/* Min and max values supported with 'offset' interface by M41TXX */
+#define M41TXX_MIN_OFFSET      ((-31) * M41TXX_NEG_OFFSET_STEP_PPB)
+#define M41TXX_MAX_OFFSET      ((31) * M41TXX_POS_OFFSET_STEP_PPB)
+
 struct ds1307 {
        enum ds_type            type;
        unsigned long           flags;
@@ -146,6 +160,9 @@ struct chip_desc {
 
 static int ds1307_get_time(struct device *dev, struct rtc_time *t);
 static int ds1307_set_time(struct device *dev, struct rtc_time *t);
+static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t);
+static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t);
+static int ds1307_alarm_irq_enable(struct device *dev, unsigned int enabled);
 static u8 do_trickle_setup_ds1339(struct ds1307 *, u32 ohms, bool diode);
 static irqreturn_t rx8130_irq(int irq, void *dev_id);
 static int rx8130_read_alarm(struct device *dev, struct rtc_wkalrm *t);
@@ -155,6 +172,8 @@ static irqreturn_t mcp794xx_irq(int irq, void *dev_id);
 static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t);
 static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t);
 static int mcp794xx_alarm_irq_enable(struct device *dev, unsigned int enabled);
+static int m41txx_rtc_read_offset(struct device *dev, long *offset);
+static int m41txx_rtc_set_offset(struct device *dev, long offset);
 
 static const struct rtc_class_ops rx8130_rtc_ops = {
        .read_time      = ds1307_get_time,
@@ -172,6 +191,16 @@ static const struct rtc_class_ops mcp794xx_rtc_ops = {
        .alarm_irq_enable = mcp794xx_alarm_irq_enable,
 };
 
+static const struct rtc_class_ops m41txx_rtc_ops = {
+       .read_time      = ds1307_get_time,
+       .set_time       = ds1307_set_time,
+       .read_alarm     = ds1337_read_alarm,
+       .set_alarm      = ds1337_set_alarm,
+       .alarm_irq_enable = ds1307_alarm_irq_enable,
+       .read_offset    = m41txx_rtc_read_offset,
+       .set_offset     = m41txx_rtc_set_offset,
+};
+
 static const struct chip_desc chips[last_ds_type] = {
        [ds_1307] = {
                .nvram_offset   = 8,
@@ -228,10 +257,17 @@ static const struct chip_desc chips[last_ds_type] = {
                .irq_handler = rx8130_irq,
                .rtc_ops = &rx8130_rtc_ops,
        },
+       [m41t0] = {
+               .rtc_ops        = &m41txx_rtc_ops,
+       },
+       [m41t00] = {
+               .rtc_ops        = &m41txx_rtc_ops,
+       },
        [m41t11] = {
                /* this is battery backed SRAM */
                .nvram_offset   = 8,
                .nvram_size     = 56,
+               .rtc_ops        = &m41txx_rtc_ops,
        },
        [mcp794xx] = {
                .alarm          = 1,
@@ -973,6 +1009,110 @@ static int mcp794xx_alarm_irq_enable(struct device *dev, unsigned int enabled)
                                  enabled ? MCP794XX_BIT_ALM0_EN : 0);
 }
 
+static int m41txx_rtc_read_offset(struct device *dev, long *offset)
+{
+       struct ds1307 *ds1307 = dev_get_drvdata(dev);
+       unsigned int ctrl_reg;
+       u8 val;
+
+       regmap_read(ds1307->regmap, M41TXX_REG_CONTROL, &ctrl_reg);
+
+       val = ctrl_reg & M41TXX_M_CALIBRATION;
+
+       /* check if positive */
+       if (ctrl_reg & M41TXX_BIT_CALIB_SIGN)
+               *offset = (val * M41TXX_POS_OFFSET_STEP_PPB);
+       else
+               *offset = -(val * M41TXX_NEG_OFFSET_STEP_PPB);
+
+       return 0;
+}
+
+static int m41txx_rtc_set_offset(struct device *dev, long offset)
+{
+       struct ds1307 *ds1307 = dev_get_drvdata(dev);
+       unsigned int ctrl_reg;
+
+       if ((offset < M41TXX_MIN_OFFSET) || (offset > M41TXX_MAX_OFFSET))
+               return -ERANGE;
+
+       if (offset >= 0) {
+               ctrl_reg = DIV_ROUND_CLOSEST(offset,
+                                            M41TXX_POS_OFFSET_STEP_PPB);
+               ctrl_reg |= M41TXX_BIT_CALIB_SIGN;
+       } else {
+               ctrl_reg = DIV_ROUND_CLOSEST(abs(offset),
+                                            M41TXX_NEG_OFFSET_STEP_PPB);
+       }
+
+       return regmap_update_bits(ds1307->regmap, M41TXX_REG_CONTROL,
+                                 M41TXX_M_CALIBRATION | M41TXX_BIT_CALIB_SIGN,
+                                 ctrl_reg);
+}
+
+static ssize_t frequency_test_store(struct device *dev,
+                                   struct device_attribute *attr,
+                                   const char *buf, size_t count)
+{
+       struct ds1307 *ds1307 = dev_get_drvdata(dev->parent);
+       bool freq_test_en;
+       int ret;
+
+       ret = kstrtobool(buf, &freq_test_en);
+       if (ret) {
+               dev_err(dev, "Failed to store RTC Frequency Test attribute\n");
+               return ret;
+       }
+
+       regmap_update_bits(ds1307->regmap, M41TXX_REG_CONTROL, M41TXX_BIT_FT,
+                          freq_test_en ? M41TXX_BIT_FT : 0);
+
+       return count;
+}
+
+static ssize_t frequency_test_show(struct device *dev,
+                                  struct device_attribute *attr,
+                                  char *buf)
+{
+       struct ds1307 *ds1307 = dev_get_drvdata(dev->parent);
+       unsigned int ctrl_reg;
+
+       regmap_read(ds1307->regmap, M41TXX_REG_CONTROL, &ctrl_reg);
+
+       return scnprintf(buf, PAGE_SIZE, (ctrl_reg & M41TXX_BIT_FT) ? "on\n" :
+                       "off\n");
+}
+
+static DEVICE_ATTR_RW(frequency_test);
+
+static struct attribute *rtc_freq_test_attrs[] = {
+       &dev_attr_frequency_test.attr,
+       NULL,
+};
+
+static const struct attribute_group rtc_freq_test_attr_group = {
+       .attrs          = rtc_freq_test_attrs,
+};
+
+static int ds1307_add_frequency_test(struct ds1307 *ds1307)
+{
+       int err;
+
+       switch (ds1307->type) {
+       case m41t0:
+       case m41t00:
+       case m41t11:
+               err = rtc_add_group(ds1307->rtc, &rtc_freq_test_attr_group);
+               if (err)
+                       return err;
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
 /*----------------------------------------------------------------------*/
 
 static int ds1307_nvram_read(void *priv, unsigned int offset, void *val,
@@ -1384,7 +1524,6 @@ static void ds1307_clks_register(struct ds1307 *ds1307)
 static const struct regmap_config regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
-       .max_register = 0x9,
 };
 
 static int ds1307_probe(struct i2c_client *client,
@@ -1711,6 +1850,10 @@ read_rtc:
        }
 
        ds1307->rtc->ops = chip->rtc_ops ?: &ds13xx_rtc_ops;
+       err = ds1307_add_frequency_test(ds1307);
+       if (err)
+               return err;
+
        err = rtc_register_device(ds1307->rtc);
        if (err)
                return err;
index 6f39f68..2710f25 100644 (file)
@@ -770,33 +770,6 @@ static const char *ds1685_rtc_sqw_freq[16] = {
        "512Hz", "256Hz", "128Hz", "64Hz", "32Hz", "16Hz", "8Hz", "4Hz", "2Hz"
 };
 
-#ifdef CONFIG_RTC_DS1685_PROC_REGS
-/**
- * ds1685_rtc_print_regs - helper function to print register values.
- * @hex: hex byte to convert into binary bits.
- * @dest: destination char array.
- *
- * This is basically a hex->binary function, just with extra spacing between
- * the digits.  It only works on 1-byte values (8 bits).
- */
-static char*
-ds1685_rtc_print_regs(u8 hex, char *dest)
-{
-       u32 i, j;
-       char *tmp = dest;
-
-       for (i = 0; i < NUM_BITS; i++) {
-               *tmp++ = ((hex & 0x80) != 0 ? '1' : '0');
-               for (j = 0; j < NUM_SPACES; j++)
-                       *tmp++ = ' ';
-               hex <<= 1;
-       }
-       *tmp++ = '\0';
-
-       return dest;
-}
-#endif
-
 /**
  * ds1685_rtc_proc - procfs access function.
  * @dev: pointer to device structure.
@@ -805,13 +778,9 @@ ds1685_rtc_print_regs(u8 hex, char *dest)
 static int
 ds1685_rtc_proc(struct device *dev, struct seq_file *seq)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       struct ds1685_priv *rtc = platform_get_drvdata(pdev);
+       struct ds1685_priv *rtc = dev_get_drvdata(dev);
        u8 ctrla, ctrlb, ctrlc, ctrld, ctrl4a, ctrl4b, ssn[8];
        char *model;
-#ifdef CONFIG_RTC_DS1685_PROC_REGS
-       char bits[NUM_REGS][(NUM_BITS * NUM_SPACES) + NUM_BITS + 1];
-#endif
 
        /* Read all the relevant data from the control registers. */
        ds1685_rtc_switch_to_bank1(rtc);
@@ -859,28 +828,7 @@ ds1685_rtc_proc(struct device *dev, struct seq_file *seq)
           "Periodic IRQ\t: %s\n"
           "Periodic Rate\t: %s\n"
           "SQW Freq\t: %s\n"
-#ifdef CONFIG_RTC_DS1685_PROC_REGS
-          "Serial #\t: %8phC\n"
-          "Register Status\t:\n"
-          "   Ctrl A\t: UIP  DV2  DV1  DV0  RS3  RS2  RS1  RS0\n"
-          "\t\t:  %s\n"
-          "   Ctrl B\t: SET  PIE  AIE  UIE  SQWE  DM  2412 DSE\n"
-          "\t\t:  %s\n"
-          "   Ctrl C\t: IRQF  PF   AF   UF  ---  ---  ---  ---\n"
-          "\t\t:  %s\n"
-          "   Ctrl D\t: VRT  ---  ---  ---  ---  ---  ---  ---\n"
-          "\t\t:  %s\n"
-#if !defined(CONFIG_RTC_DRV_DS1685) && !defined(CONFIG_RTC_DRV_DS1689)
-          "   Ctrl 4A\t: VRT2 INCR BME  ---  PAB   RF   WF   KF\n"
-#else
-          "   Ctrl 4A\t: VRT2 INCR ---  ---  PAB   RF   WF   KF\n"
-#endif
-          "\t\t:  %s\n"
-          "   Ctrl 4B\t: ABE  E32k  CS  RCE  PRS  RIE  WIE  KSE\n"
-          "\t\t:  %s\n",
-#else
           "Serial #\t: %8phC\n",
-#endif
           model,
           ((ctrla & RTC_CTRL_A_DV1) ? "enabled" : "disabled"),
           ((ctrlb & RTC_CTRL_B_2412) ? "24-hour" : "12-hour"),
@@ -894,17 +842,7 @@ ds1685_rtc_proc(struct device *dev, struct seq_file *seq)
            ds1685_rtc_pirq_rate[(ctrla & RTC_CTRL_A_RS_MASK)] : "none"),
           (!((ctrl4b & RTC_CTRL_4B_E32K)) ?
            ds1685_rtc_sqw_freq[(ctrla & RTC_CTRL_A_RS_MASK)] : "32768Hz"),
-#ifdef CONFIG_RTC_DS1685_PROC_REGS
-          ssn,
-          ds1685_rtc_print_regs(ctrla, bits[0]),
-          ds1685_rtc_print_regs(ctrlb, bits[1]),
-          ds1685_rtc_print_regs(ctrlc, bits[2]),
-          ds1685_rtc_print_regs(ctrld, bits[3]),
-          ds1685_rtc_print_regs(ctrl4a, bits[4]),
-          ds1685_rtc_print_regs(ctrl4b, bits[5]));
-#else
           ssn);
-#endif
        return 0;
 }
 #else
@@ -927,30 +865,13 @@ ds1685_rtc_ops = {
 };
 /* ----------------------------------------------------------------------- */
 
-
-/* ----------------------------------------------------------------------- */
-/* SysFS interface */
-
-#ifdef CONFIG_SYSFS
-/**
- * ds1685_rtc_sysfs_nvram_read - reads rtc nvram via sysfs.
- * @file: pointer to file structure.
- * @kobj: pointer to kobject structure.
- * @bin_attr: pointer to bin_attribute structure.
- * @buf: pointer to char array to hold the output.
- * @pos: current file position pointer.
- * @size: size of the data to read.
- */
-static ssize_t
-ds1685_rtc_sysfs_nvram_read(struct file *filp, struct kobject *kobj,
-                           struct bin_attribute *bin_attr, char *buf,
-                           loff_t pos, size_t size)
+static int ds1685_nvram_read(void *priv, unsigned int pos, void *val,
+                            size_t size)
 {
-       struct platform_device *pdev =
-               to_platform_device(container_of(kobj, struct device, kobj));
-       struct ds1685_priv *rtc = platform_get_drvdata(pdev);
+       struct ds1685_priv *rtc = priv;
        ssize_t count;
        unsigned long flags = 0;
+       u8 *buf = val;
 
        spin_lock_irqsave(&rtc->lock, flags);
        ds1685_rtc_switch_to_bank0(rtc);
@@ -1004,33 +925,16 @@ ds1685_rtc_sysfs_nvram_read(struct file *filp, struct kobject *kobj,
 #endif /* !CONFIG_RTC_DRV_DS1689 */
        spin_unlock_irqrestore(&rtc->lock, flags);
 
-       /*
-        * XXX: Bug? this appears to cause the function to get executed
-        * several times in succession.  But it's the only way to actually get
-        * data written out to a file.
-        */
-       return count;
+       return 0;
 }
 
-/**
- * ds1685_rtc_sysfs_nvram_write - writes rtc nvram via sysfs.
- * @file: pointer to file structure.
- * @kobj: pointer to kobject structure.
- * @bin_attr: pointer to bin_attribute structure.
- * @buf: pointer to char array to hold the input.
- * @pos: current file position pointer.
- * @size: size of the data to write.
- */
-static ssize_t
-ds1685_rtc_sysfs_nvram_write(struct file *filp, struct kobject *kobj,
-                            struct bin_attribute *bin_attr, char *buf,
-                            loff_t pos, size_t size)
+static int ds1685_nvram_write(void *priv, unsigned int pos, void *val,
+                             size_t size)
 {
-       struct platform_device *pdev =
-               to_platform_device(container_of(kobj, struct device, kobj));
-       struct ds1685_priv *rtc = platform_get_drvdata(pdev);
+       struct ds1685_priv *rtc = priv;
        ssize_t count;
        unsigned long flags = 0;
+       u8 *buf = val;
 
        spin_lock_irqsave(&rtc->lock, flags);
        ds1685_rtc_switch_to_bank0(rtc);
@@ -1084,26 +988,11 @@ ds1685_rtc_sysfs_nvram_write(struct file *filp, struct kobject *kobj,
 #endif /* !CONFIG_RTC_DRV_DS1689 */
        spin_unlock_irqrestore(&rtc->lock, flags);
 
-       return count;
+       return 0;
 }
 
-/**
- * struct ds1685_rtc_sysfs_nvram_attr - sysfs attributes for rtc nvram.
- * @attr: nvram attributes.
- * @read: nvram read function.
- * @write: nvram write function.
- * @size: nvram total size (bank0 + extended).
- */
-static struct bin_attribute
-ds1685_rtc_sysfs_nvram_attr = {
-       .attr = {
-               .name = "nvram",
-               .mode = S_IRUGO | S_IWUSR,
-       },
-       .read = ds1685_rtc_sysfs_nvram_read,
-       .write = ds1685_rtc_sysfs_nvram_write,
-       .size = NVRAM_TOTAL_SZ
-};
+/* ----------------------------------------------------------------------- */
+/* SysFS interface */
 
 /**
  * ds1685_rtc_sysfs_battery_show - sysfs file for main battery status.
@@ -1188,43 +1077,6 @@ ds1685_rtc_sysfs_misc_grp = {
        .attrs = ds1685_rtc_sysfs_misc_attrs,
 };
 
-/**
- * ds1685_rtc_sysfs_register - register sysfs files.
- * @dev: pointer to device structure.
- */
-static int
-ds1685_rtc_sysfs_register(struct device *dev)
-{
-       int ret = 0;
-
-       sysfs_bin_attr_init(&ds1685_rtc_sysfs_nvram_attr);
-       ret = sysfs_create_bin_file(&dev->kobj, &ds1685_rtc_sysfs_nvram_attr);
-       if (ret)
-               return ret;
-
-       ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_misc_grp);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-/**
- * ds1685_rtc_sysfs_unregister - unregister sysfs files.
- * @dev: pointer to device structure.
- */
-static int
-ds1685_rtc_sysfs_unregister(struct device *dev)
-{
-       sysfs_remove_bin_file(&dev->kobj, &ds1685_rtc_sysfs_nvram_attr);
-       sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_misc_grp);
-
-       return 0;
-}
-#endif /* CONFIG_SYSFS */
-
-
-
 /* ----------------------------------------------------------------------- */
 /* Driver Probe/Removal */
 
@@ -1242,6 +1094,12 @@ ds1685_rtc_probe(struct platform_device *pdev)
        u8 ctrla, ctrlb, hours;
        unsigned char am_pm;
        int ret = 0;
+       struct nvmem_config nvmem_cfg = {
+               .name = "ds1685_nvram",
+               .size = NVRAM_TOTAL_SZ,
+               .reg_read = ds1685_nvram_read,
+               .reg_write = ds1685_nvram_write,
+       };
 
        /* Get the platform data. */
        pdata = (struct ds1685_rtc_platform_data *) pdev->dev.platform_data;
@@ -1499,11 +1357,15 @@ ds1685_rtc_probe(struct platform_device *pdev)
        /* Setup complete. */
        ds1685_rtc_switch_to_bank0(rtc);
 
-#ifdef CONFIG_SYSFS
-       ret = ds1685_rtc_sysfs_register(&pdev->dev);
+       ret = rtc_add_group(rtc_dev, &ds1685_rtc_sysfs_misc_grp);
+       if (ret)
+               return ret;
+
+       rtc_dev->nvram_old_abi = true;
+       nvmem_cfg.priv = rtc;
+       ret = rtc_nvmem_register(rtc_dev, &nvmem_cfg);
        if (ret)
                return ret;
-#endif
 
        return rtc_register_device(rtc_dev);
 }
@@ -1517,10 +1379,6 @@ ds1685_rtc_remove(struct platform_device *pdev)
 {
        struct ds1685_priv *rtc = platform_get_drvdata(pdev);
 
-#ifdef CONFIG_SYSFS
-       ds1685_rtc_sysfs_unregister(&pdev->dev);
-#endif
-
        /* Read Ctrl B and clear PIE/AIE/UIE. */
        rtc->write(rtc, RTC_CTRL_B,
                   (rtc->read(rtc, RTC_CTRL_B) &
index ea18a8f..ec5ef51 100644 (file)
  *
  */
 
-#include <linux/module.h>
-#include <linux/i2c.h>
 #include <linux/bcd.h>
-#include <linux/rtc.h>
-#include "rtc-core.h"
+#include <linux/i2c.h>
+#include <linux/module.h>
 #include <linux/of_irq.h>
+#include <linux/rtc.h>
 
 /* Register map */
 /* rtc section */
@@ -518,7 +517,7 @@ static ssize_t timestamp0_store(struct device *dev,
                                struct device_attribute *attr,
                                const char *buf, size_t count)
 {
-       struct i2c_client *client = dev_get_drvdata(dev);
+       struct i2c_client *client = to_i2c_client(dev->parent);
        int sr;
 
        sr = isl1208_i2c_get_sr(client);
@@ -540,7 +539,7 @@ static ssize_t timestamp0_store(struct device *dev,
 static ssize_t timestamp0_show(struct device *dev,
                               struct device_attribute *attr, char *buf)
 {
-       struct i2c_client *client = dev_get_drvdata(dev);
+       struct i2c_client *client = to_i2c_client(dev->parent);
        u8 regs[ISL1219_EVT_SECTION_LEN] = { 0, };
        struct rtc_time tm;
        int sr;
@@ -650,7 +649,7 @@ static ssize_t
 isl1208_sysfs_show_atrim(struct device *dev,
                         struct device_attribute *attr, char *buf)
 {
-       int atr = isl1208_i2c_get_atr(to_i2c_client(dev));
+       int atr = isl1208_i2c_get_atr(to_i2c_client(dev->parent));
        if (atr < 0)
                return atr;
 
@@ -663,7 +662,7 @@ static ssize_t
 isl1208_sysfs_show_dtrim(struct device *dev,
                         struct device_attribute *attr, char *buf)
 {
-       int dtr = isl1208_i2c_get_dtr(to_i2c_client(dev));
+       int dtr = isl1208_i2c_get_dtr(to_i2c_client(dev->parent));
        if (dtr < 0)
                return dtr;
 
@@ -676,7 +675,7 @@ static ssize_t
 isl1208_sysfs_show_usr(struct device *dev,
                       struct device_attribute *attr, char *buf)
 {
-       int usr = isl1208_i2c_get_usr(to_i2c_client(dev));
+       int usr = isl1208_i2c_get_usr(to_i2c_client(dev->parent));
        if (usr < 0)
                return usr;
 
@@ -701,7 +700,10 @@ isl1208_sysfs_store_usr(struct device *dev,
        if (usr < 0 || usr > 0xffff)
                return -EINVAL;
 
-       return isl1208_i2c_set_usr(to_i2c_client(dev), usr) ? -EIO : count;
+       if (isl1208_i2c_set_usr(to_i2c_client(dev->parent), usr))
+               return -EIO;
+
+       return count;
 }
 
 static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr,
@@ -765,7 +767,6 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
        rtc->ops = &isl1208_rtc_ops;
 
        i2c_set_clientdata(client, rtc);
-       dev_set_drvdata(&rtc->dev, client);
 
        rc = isl1208_i2c_get_sr(client);
        if (rc < 0) {
@@ -804,7 +805,7 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
                evdet_irq = of_irq_get_byname(np, "evdet");
        }
 
-       rc = sysfs_create_group(&client->dev.kobj, &isl1208_rtc_sysfs_files);
+       rc = rtc_add_group(rtc, &isl1208_rtc_sysfs_files);
        if (rc)
                return rc;
 
@@ -821,14 +822,6 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
        return rtc_register_device(rtc);
 }
 
-static int
-isl1208_remove(struct i2c_client *client)
-{
-       sysfs_remove_group(&client->dev.kobj, &isl1208_rtc_sysfs_files);
-
-       return 0;
-}
-
 static const struct i2c_device_id isl1208_id[] = {
        { "isl1208", TYPE_ISL1208 },
        { "isl1218", TYPE_ISL1218 },
@@ -851,7 +844,6 @@ static struct i2c_driver isl1208_driver = {
                .of_match_table = of_match_ptr(isl1208_of_match),
        },
        .probe = isl1208_probe,
-       .remove = isl1208_remove,
        .id_table = isl1208_id,
 };
 
index 4a3c0f3..ef160da 100644 (file)
@@ -47,7 +47,7 @@ EXPORT_SYMBOL(rtc_year_days);
 
 
 /*
- * rtc_time_to_tm64 - Converts time64_t to rtc_time.
+ * rtc_time64_to_tm - Converts time64_t to rtc_time.
  * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
  */
 void rtc_time64_to_tm(time64_t time, struct rtc_time *tm)
index ad03e2f..a3fb235 100644 (file)
@@ -745,7 +745,7 @@ static int wdt_ioctl(struct file *file, unsigned int cmd,
                        return -EINVAL;
                wdt_margin = new_margin;
                wdt_ping();
-               /* Fall */
+               /* Fall through */
        case WDIOC_GETTIMEOUT:
                return put_user(wdt_margin, (int __user *)arg);
 
index 1925aaf..daf354a 100644 (file)
@@ -90,7 +90,7 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time)
        unsigned long flags;
 
        if (vrtc_is_updating())
-               mdelay(20);
+               msleep(20);
 
        spin_lock_irqsave(&rtc_lock, flags);
        time->tm_sec = vrtc_cmos_read(RTC_SECONDS);
@@ -261,11 +261,10 @@ static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 
 static int mrst_procfs(struct device *dev, struct seq_file *seq)
 {
-       unsigned char   rtc_control, valid;
+       unsigned char   rtc_control;
 
        spin_lock_irq(&rtc_lock);
        rtc_control = vrtc_cmos_read(RTC_CONTROL);
-       valid = vrtc_cmos_read(RTC_VALID);
        spin_unlock_irq(&rtc_lock);
 
        seq_printf(seq,
index 385f830..e9a25ec 100644 (file)
@@ -332,6 +332,10 @@ static int mtk_rtc_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, rtc);
 
+       rtc->rtc_dev = devm_rtc_allocate_device(rtc->dev);
+       if (IS_ERR(rtc->rtc_dev))
+               return PTR_ERR(rtc->rtc_dev);
+
        ret = request_threaded_irq(rtc->irq, NULL,
                                   mtk_rtc_irq_handler_thread,
                                   IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
@@ -344,11 +348,11 @@ static int mtk_rtc_probe(struct platform_device *pdev)
 
        device_init_wakeup(&pdev->dev, 1);
 
-       rtc->rtc_dev = rtc_device_register("mt6397-rtc", &pdev->dev,
-                                          &mtk_rtc_ops, THIS_MODULE);
-       if (IS_ERR(rtc->rtc_dev)) {
+       rtc->rtc_dev->ops = &mtk_rtc_ops;
+
+       ret = rtc_register_device(rtc->rtc_dev);
+       if (ret) {
                dev_err(&pdev->dev, "register rtc device failed\n");
-               ret = PTR_ERR(rtc->rtc_dev);
                goto out_free_irq;
        }
 
@@ -365,7 +369,6 @@ static int mtk_rtc_remove(struct platform_device *pdev)
 {
        struct mt6397_rtc *rtc = platform_get_drvdata(pdev);
 
-       rtc_device_unregister(rtc->rtc_dev);
        free_irq(rtc->irq, rtc->rtc_dev);
        irq_dispose_mapping(rtc->irq);
 
index 4b198b3..e7f14bd 100644 (file)
@@ -125,13 +125,9 @@ static int mv_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
        /* hw counts from year 2000, but tm_year is relative to 1900 */
        alm->time.tm_year = bcd2bin(year) + 100;
 
-       if (rtc_valid_tm(&alm->time) < 0) {
-               dev_err(dev, "retrieved alarm date/time is not valid.\n");
-               rtc_time_to_tm(0, &alm->time);
-       }
-
        alm->enabled = !!readl(ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
-       return 0;
+
+       return rtc_valid_tm(&alm->time);
 }
 
 static int mv_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
index 323ff55..320b4a5 100644 (file)
@@ -421,12 +421,6 @@ static struct omap_rtc *omap_rtc_power_off_rtc;
  * The RTC can be used to control an external PMIC via the pmic_power_en pin,
  * which can be configured to transition to OFF on ALARM2 events.
  *
- * Notes:
- * The two-second alarm offset is the shortest offset possible as the alarm
- * registers must be set before the next timer update and the offset
- * calculation is too heavy for everything to be done within a single access
- * period (~15 us).
- *
  * Called with local interrupts disabled.
  */
 static void omap_rtc_power_off(void)
@@ -434,6 +428,7 @@ static void omap_rtc_power_off(void)
        struct omap_rtc *rtc = omap_rtc_power_off_rtc;
        struct rtc_time tm;
        unsigned long now;
+       int seconds;
        u32 val;
 
        rtc->type->unlock(rtc);
@@ -441,11 +436,13 @@ static void omap_rtc_power_off(void)
        val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
        rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
 
-       /* set alarm two seconds from now */
+again:
+       /* set alarm one second from now */
        omap_rtc_read_time_raw(rtc, &tm);
+       seconds = tm.tm_sec;
        bcd2tm(&tm);
        rtc_tm_to_time(&tm, &now);
-       rtc_time_to_tm(now + 2, &tm);
+       rtc_time_to_tm(now + 1, &tm);
 
        if (tm2bcd(&tm) < 0) {
                dev_err(&rtc->rtc->dev, "power off failed\n");
@@ -470,14 +467,22 @@ static void omap_rtc_power_off(void)
        val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
        rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG,
                        val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
+
+       /* Retry in case roll over happened before alarm was armed. */
+       if (rtc_read(rtc, OMAP_RTC_SECONDS_REG) != seconds) {
+               val = rtc_read(rtc, OMAP_RTC_STATUS_REG);
+               if (!(val & OMAP_RTC_STATUS_ALARM2))
+                       goto again;
+       }
+
        rtc->type->lock(rtc);
 
        /*
-        * Wait for alarm to trigger (within two seconds) and external PMIC to
+        * Wait for alarm to trigger (within one second) and external PMIC to
         * power off the system. Add a 500 ms margin for external latencies
         * (e.g. debounce circuits).
         */
-       mdelay(2500);
+       mdelay(1500);
 }
 
 static const struct rtc_class_ops omap_rtc_ops = {
@@ -721,8 +726,7 @@ static int omap_rtc_probe(struct platform_device *pdev)
        if (of_id) {
                rtc->type = of_id->data;
                rtc->is_pmic_controller = rtc->type->has_pmic_mode &&
-                               of_property_read_bool(pdev->dev.of_node,
-                                               "system-power-controller");
+                       of_device_is_system_power_controller(pdev->dev.of_node);
        } else {
                id_entry = platform_get_device_id(pdev);
                rtc->type = (void *)id_entry->driver_data;
index f85a1a9..343bb6e 100644 (file)
@@ -112,6 +112,13 @@ static int pl030_probe(struct amba_device *dev, const struct amba_id *id)
                goto err_rtc;
        }
 
+       rtc->rtc = devm_rtc_allocate_device(&dev->dev);
+       if (IS_ERR(rtc->rtc)) {
+               ret = PTR_ERR(rtc->rtc);
+               goto err_rtc;
+       }
+
+       rtc->rtc->ops = &pl030_ops;
        rtc->base = ioremap(dev->res.start, resource_size(&dev->res));
        if (!rtc->base) {
                ret = -ENOMEM;
@@ -128,12 +135,9 @@ static int pl030_probe(struct amba_device *dev, const struct amba_id *id)
        if (ret)
                goto err_irq;
 
-       rtc->rtc = rtc_device_register("pl030", &dev->dev, &pl030_ops,
-                                      THIS_MODULE);
-       if (IS_ERR(rtc->rtc)) {
-               ret = PTR_ERR(rtc->rtc);
+       ret = rtc_register_device(rtc->rtc);
+       if (ret)
                goto err_reg;
-       }
 
        return 0;
 
@@ -154,7 +158,6 @@ static int pl030_remove(struct amba_device *dev)
        writel(0, rtc->base + RTC_CR);
 
        free_irq(dev->irq[0], rtc);
-       rtc_device_unregister(rtc->rtc);
        iounmap(rtc->base);
        amba_release_regions(dev);
 
index 82eb7da..30943d2 100644 (file)
@@ -310,7 +310,6 @@ static int pl031_remove(struct amba_device *adev)
        device_init_wakeup(&adev->dev, false);
        if (adev->irq[0])
                free_irq(adev->irq[0], ldata);
-       rtc_device_unregister(ldata->rtc);
        amba_release_regions(adev);
 
        return 0;
@@ -383,24 +382,25 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
        }
 
        device_init_wakeup(&adev->dev, true);
-       ldata->rtc = rtc_device_register("pl031", &adev->dev, ops,
-                                       THIS_MODULE);
-       if (IS_ERR(ldata->rtc)) {
-               ret = PTR_ERR(ldata->rtc);
+       ldata->rtc = devm_rtc_allocate_device(&adev->dev);
+       if (IS_ERR(ldata->rtc))
+               return PTR_ERR(ldata->rtc);
+
+       ldata->rtc->ops = ops;
+
+       ret = rtc_register_device(ldata->rtc);
+       if (ret)
                goto out;
-       }
 
        if (adev->irq[0]) {
                ret = request_irq(adev->irq[0], pl031_interrupt,
                                  vendor->irqflags, "rtc-pl031", ldata);
                if (ret)
-                       goto out_no_irq;
+                       goto out;
                dev_pm_set_wake_irq(&adev->dev, adev->irq[0]);
        }
        return 0;
 
-out_no_irq:
-       rtc_device_unregister(ldata->rtc);
 out:
        amba_release_regions(adev);
 err_req:
index f2de8b1..6582be7 100644 (file)
@@ -66,6 +66,17 @@ rs5c348_rtc_set_time(struct device *dev, struct rtc_time *tm)
        u8 txbuf[5+7], *txp;
        int ret;
 
+       ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2));
+       if (ret < 0)
+               return ret;
+       if (ret & RS5C348_BIT_XSTP) {
+               txbuf[0] = RS5C348_CMD_W(RS5C348_REG_CTL2);
+               txbuf[1] = 0;
+               ret = spi_write_then_read(spi, txbuf, 2, NULL, 0);
+               if (ret < 0)
+                       return ret;
+       }
+
        /* Transfer 5 bytes before writing SEC.  This gives 31us for carry. */
        txp = txbuf;
        txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
@@ -102,6 +113,16 @@ rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm)
        u8 txbuf[5], rxbuf[7];
        int ret;
 
+       ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2));
+       if (ret < 0)
+               return ret;
+       if (ret & RS5C348_BIT_VDET)
+               dev_warn(&spi->dev, "voltage-low detected.\n");
+       if (ret & RS5C348_BIT_XSTP) {
+               dev_warn(&spi->dev, "oscillator-stop detected.\n");
+               return -EINVAL;
+       }
+
        /* Transfer 5 byte befores reading SEC.  This gives 31us for carry. */
        txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
        txbuf[1] = 0;   /* dummy */
@@ -143,8 +164,6 @@ static const struct rtc_class_ops rs5c348_rtc_ops = {
        .set_time       = rs5c348_rtc_set_time,
 };
 
-static struct spi_driver rs5c348_driver;
-
 static int rs5c348_probe(struct spi_device *spi)
 {
        int ret;
@@ -161,53 +180,27 @@ static int rs5c348_probe(struct spi_device *spi)
        ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_SECS));
        if (ret < 0 || (ret & 0x80)) {
                dev_err(&spi->dev, "not found.\n");
-               goto kfree_exit;
+               return ret;
        }
 
        dev_info(&spi->dev, "spiclk %u KHz.\n",
                 (spi->max_speed_hz + 500) / 1000);
 
-       /* turn RTC on if it was not on */
-       ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2));
-       if (ret < 0)
-               goto kfree_exit;
-       if (ret & (RS5C348_BIT_XSTP | RS5C348_BIT_VDET)) {
-               u8 buf[2];
-               struct rtc_time tm;
-               if (ret & RS5C348_BIT_VDET)
-                       dev_warn(&spi->dev, "voltage-low detected.\n");
-               if (ret & RS5C348_BIT_XSTP)
-                       dev_warn(&spi->dev, "oscillator-stop detected.\n");
-               rtc_time_to_tm(0, &tm); /* 1970/1/1 */
-               ret = rs5c348_rtc_set_time(&spi->dev, &tm);
-               if (ret < 0)
-                       goto kfree_exit;
-               buf[0] = RS5C348_CMD_W(RS5C348_REG_CTL2);
-               buf[1] = 0;
-               ret = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0);
-               if (ret < 0)
-                       goto kfree_exit;
-       }
-
        ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL1));
        if (ret < 0)
-               goto kfree_exit;
+               return ret;
        if (ret & RS5C348_BIT_24H)
                pdata->rtc_24h = 1;
 
-       rtc = devm_rtc_device_register(&spi->dev, rs5c348_driver.driver.name,
-                                 &rs5c348_rtc_ops, THIS_MODULE);
-
-       if (IS_ERR(rtc)) {
-               ret = PTR_ERR(rtc);
-               goto kfree_exit;
-       }
+       rtc = devm_rtc_allocate_device(&spi->dev);
+       if (IS_ERR(rtc))
+               return PTR_ERR(rtc);
 
        pdata->rtc = rtc;
 
-       return 0;
- kfree_exit:
-       return ret;
+       rtc->ops = &rs5c348_rtc_ops;
+
+       return rtc_register_device(rtc);
 }
 
 static struct spi_driver rs5c348_driver = {
index 29fc3d2..450a0b8 100644 (file)
@@ -615,6 +615,7 @@ static int rv8803_probe(struct i2c_client *client,
 
 static const struct i2c_device_id rv8803_id[] = {
        { "rv8803", rv_8803 },
+       { "rx8803", rv_8803 },
        { "rx8900", rx_8900 },
        { }
 };
@@ -623,7 +624,11 @@ MODULE_DEVICE_TABLE(i2c, rv8803_id);
 static const struct of_device_id rv8803_of_match[] = {
        {
                .compatible = "microcrystal,rv8803",
-               .data = (void *)rx_8900
+               .data = (void *)rv_8803
+       },
+       {
+               .compatible = "epson,rx8803",
+               .data = (void *)rv_8803
        },
        {
                .compatible = "epson,rx8900",
index 77feb60..3c64dbb 100644 (file)
@@ -108,7 +108,7 @@ static int s35390a_get_reg(struct s35390a *s35390a, int reg, char *buf, int len)
 
 static int s35390a_init(struct s35390a *s35390a)
 {
-       char buf;
+       u8 buf;
        int ret;
        unsigned initcount = 0;
 
index deea5c3..b4eb3b3 100644 (file)
@@ -129,19 +129,6 @@ static int sprd_rtc_clear_alarm_ints(struct sprd_rtc *rtc)
                            SPRD_RTC_ALM_INT_MASK);
 }
 
-static int sprd_rtc_disable_ints(struct sprd_rtc *rtc)
-{
-       int ret;
-
-       ret = regmap_update_bits(rtc->regmap, rtc->base + SPRD_RTC_INT_EN,
-                                SPRD_RTC_INT_MASK, 0);
-       if (ret)
-               return ret;
-
-       return regmap_write(rtc->regmap, rtc->base + SPRD_RTC_INT_CLR,
-                           SPRD_RTC_INT_MASK);
-}
-
 static int sprd_rtc_lock_alarm(struct sprd_rtc *rtc, bool lock)
 {
        int ret;
@@ -172,7 +159,8 @@ static int sprd_rtc_lock_alarm(struct sprd_rtc *rtc, bool lock)
                return ret;
        }
 
-       return 0;
+       return regmap_write(rtc->regmap, rtc->base + SPRD_RTC_INT_CLR,
+                           SPRD_RTC_SPG_UPD_EN);
 }
 
 static int sprd_rtc_get_secs(struct sprd_rtc *rtc, enum sprd_rtc_reg_types type,
@@ -427,10 +415,14 @@ static int sprd_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
        u32 val;
 
        /*
-        * If aie_timer is enabled, we should get the normal alarm time.
+        * Before RTC device is registered, it will check to see if there is an
+        * alarm already set in RTC hardware, and we always read the normal
+        * alarm at this time.
+        *
+        * Or if aie_timer is enabled, we should get the normal alarm time.
         * Otherwise we should get auxiliary alarm time.
         */
-       if (rtc->rtc && rtc->rtc->aie_timer.enabled == 0)
+       if (rtc->rtc && rtc->rtc->registered && rtc->rtc->aie_timer.enabled == 0)
                return sprd_rtc_read_aux_alarm(dev, alrm);
 
        ret = sprd_rtc_get_secs(rtc, SPRD_RTC_ALARM, &secs);
@@ -575,6 +567,32 @@ static int sprd_rtc_check_power_down(struct sprd_rtc *rtc)
        return 0;
 }
 
+static int sprd_rtc_check_alarm_int(struct sprd_rtc *rtc)
+{
+       u32 val;
+       int ret;
+
+       ret = regmap_read(rtc->regmap, rtc->base + SPRD_RTC_SPG_VALUE, &val);
+       if (ret)
+               return ret;
+
+       /*
+        * The SPRD_RTC_INT_EN register is not put in always-power-on region
+        * supplied by VDDRTC, so we should check if we need enable the alarm
+        * interrupt when system booting.
+        *
+        * If we have set SPRD_RTC_POWEROFF_ALM_FLAG which is saved in
+        * always-power-on region, that means we have set one alarm last time,
+        * so we should enable the alarm interrupt to help RTC core to see if
+        * there is an alarm already set in RTC hardware.
+        */
+       if (!(val & SPRD_RTC_POWEROFF_ALM_FLAG))
+               return 0;
+
+       return regmap_update_bits(rtc->regmap, rtc->base + SPRD_RTC_INT_EN,
+                                 SPRD_RTC_ALARM_EN, SPRD_RTC_ALARM_EN);
+}
+
 static int sprd_rtc_probe(struct platform_device *pdev)
 {
        struct device_node *node = pdev->dev.of_node;
@@ -608,10 +626,10 @@ static int sprd_rtc_probe(struct platform_device *pdev)
        rtc->dev = &pdev->dev;
        platform_set_drvdata(pdev, rtc);
 
-       /* clear all RTC interrupts and disable all RTC interrupts */
-       ret = sprd_rtc_disable_ints(rtc);
+       /* check if we need set the alarm interrupt */
+       ret = sprd_rtc_check_alarm_int(rtc);
        if (ret) {
-               dev_err(&pdev->dev, "failed to disable RTC interrupts\n");
+               dev_err(&pdev->dev, "failed to check RTC alarm interrupt\n");
                return ret;
        }
 
@@ -631,16 +649,18 @@ static int sprd_rtc_probe(struct platform_device *pdev)
                return ret;
        }
 
+       device_init_wakeup(&pdev->dev, 1);
+
        rtc->rtc->ops = &sprd_rtc_ops;
        rtc->rtc->range_min = 0;
        rtc->rtc->range_max = 5662310399LL;
        ret = rtc_register_device(rtc->rtc);
        if (ret) {
                dev_err(&pdev->dev, "failed to register rtc device\n");
+               device_init_wakeup(&pdev->dev, 0);
                return ret;
        }
 
-       device_init_wakeup(&pdev->dev, 1);
        return 0;
 }
 
index 2cd5a7b..fe07310 100644 (file)
@@ -199,8 +199,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
        if (!rtc)
                return;
 
-       clk_data = kzalloc(sizeof(*clk_data) + (sizeof(*clk_data->hws) * 2),
-                          GFP_KERNEL);
+       clk_data = kzalloc(struct_size(clk_data, hws, 2), GFP_KERNEL);
        if (!clk_data) {
                kfree(rtc);
                return;
index f1ff30a..9746c32 100644 (file)
@@ -338,8 +338,8 @@ int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps)
 
        new_cnt = old_cnt + add_cnt + 1;
        groups = devm_kcalloc(&rtc->dev, new_cnt, sizeof(*groups), GFP_KERNEL);
-       if (IS_ERR_OR_NULL(groups))
-               return PTR_ERR(groups);
+       if (!groups)
+               return -ENOMEM;
        memcpy(groups, rtc->dev.groups, old_cnt * sizeof(*groups));
        memcpy(groups + old_cnt, grps, add_cnt * sizeof(*groups));
        groups[old_cnt + add_cnt] = NULL;
index 8dc48fe..c9e77a8 100644 (file)
@@ -322,9 +322,13 @@ static int __init tegra_rtc_probe(struct platform_device *pdev)
        if (IS_ERR(info->rtc_base))
                return PTR_ERR(info->rtc_base);
 
-       info->tegra_rtc_irq = platform_get_irq(pdev, 0);
-       if (info->tegra_rtc_irq <= 0)
-               return -EBUSY;
+       ret = platform_get_irq(pdev, 0);
+       if (ret <= 0) {
+               dev_err(&pdev->dev, "failed to get platform IRQ: %d\n", ret);
+               return ret;
+       }
+
+       info->tegra_rtc_irq = ret;
 
        info->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(info->clk))
index ade6a82..6c5f09c 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * An RTC test device/driver
  * Copyright (C) 2005 Tower Technologies
  * Author: Alessandro Zummo <a.zummo@towertech.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/module.h>
@@ -197,7 +194,7 @@ static void __exit test_exit(void)
 
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_DESCRIPTION("RTC test driver/device");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 
 module_init(test_init);
 module_exit(test_exit);
index 08dbefc..61c110b 100644 (file)
@@ -253,9 +253,7 @@ static int __init tx4939_rtc_probe(struct platform_device *pdev)
        struct resource *res;
        int irq, ret;
        struct nvmem_config nvmem_cfg = {
-               .name = "rv8803_nvram",
-               .word_size = 4,
-               .stride = 4,
+               .name = "tx4939_nvram",
                .size = TX4939_RTC_REG_RAMSIZE,
                .reg_read = tx4939_nvram_read,
                .reg_write = tx4939_nvram_write,
index 70f013e..e66d0f6 100644 (file)
@@ -136,8 +136,7 @@ static int vr41xx_rtc_set_time(struct device *dev, struct rtc_time *time)
        time64_t epoch_sec, current_sec;
 
        epoch_sec = mktime64(epoch, 1, 1, 0, 0, 0);
-       current_sec = mktime64(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
-                            time->tm_hour, time->tm_min, time->tm_sec);
+       current_sec = rtc_tm_to_time64(time);
 
        write_elapsed_second(current_sec - epoch_sec);
 
@@ -158,7 +157,7 @@ static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 
        spin_unlock_irq(&rtc_lock);
 
-       rtc_time_to_tm((high << 17) | (mid << 1) | (low >> 15), time);
+       rtc_time64_to_tm((high << 17) | (mid << 1) | (low >> 15), time);
 
        return 0;
 }
@@ -166,10 +165,8 @@ static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 {
        time64_t alarm_sec;
-       struct rtc_time *time = &wkalrm->time;
 
-       alarm_sec = mktime64(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
-                            time->tm_hour, time->tm_min, time->tm_sec);
+       alarm_sec = rtc_tm_to_time64(&wkalrm->time);
 
        spin_lock_irq(&rtc_lock);
 
index 6aedc30..c8bb4a2 100644 (file)
@@ -167,17 +167,12 @@ struct rtc_device {
 #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,
-                                       struct module *owner);
 extern struct rtc_device *devm_rtc_device_register(struct device *dev,
                                        const char *name,
                                        const struct rtc_class_ops *ops,
                                        struct module *owner);
 struct rtc_device *devm_rtc_allocate_device(struct device *dev);
 int __rtc_register_device(struct module *owner, struct rtc_device *rtc);
-extern void rtc_device_unregister(struct rtc_device *rtc);
 extern void devm_rtc_device_unregister(struct device *dev,
                                        struct rtc_device *rtc);
 
@@ -277,4 +272,20 @@ static inline int rtc_nvmem_register(struct rtc_device *rtc,
 static inline void rtc_nvmem_unregister(struct rtc_device *rtc) {}
 #endif
 
+#ifdef CONFIG_RTC_INTF_SYSFS
+int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp);
+int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps);
+#else
+static inline
+int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp)
+{
+       return 0;
+}
+
+static inline
+int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps)
+{
+       return 0;
+}
+#endif
 #endif /* _LINUX_RTC_H_ */