Merge tag 'rtc-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 3 May 2021 19:15:21 +0000 (12:15 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 3 May 2021 19:15:21 +0000 (12:15 -0700)
Pull RTC updates from Alexandre Belloni:
 "Mostly small fixes and two drivers gaining alarm support. Summary:

  Subsystem:

    - UIE emulation has been reworked to avoid calling driver callbacks
      when it is known it will not work

  Drivers:

   - ab-eoz9: add alarm support

   - pcf8523: add alarm support"

* tag 'rtc-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (27 commits)
  rtc: sysfs: check features instead of ops
  rtc: omap: use rtc_write to access OMAP_RTC_OSC_REG
  rtc: s5m: Remove reference to parent's device pdata
  rtc: ds1307: Fix wday settings for rx8130
  rtc: pcf8523: report oscillator failures
  rtc: pcf8523: add alarm support
  rtc: pcf8523: remove useless define
  rtc: rtc_update_irq_enable: rework UIE emulation
  rtc: ds1307: remove flags
  rtc: ds1307: replace HAS_ALARM by RTC_FEATURE_ALARM
  rtc: imx-sc: remove .read_alarm
  rtc: ds1511: remove unused function
  rtc: fsl-ftm-alarm: add MODULE_TABLE()
  rtc: rtc-spear: replace spin_lock_irqsave by spin_lock in hard IRQ
  dt-bindings: rtc: qcom-pm8xxx-rtc: Add qcom pm8xxx rtc bindings
  rtc: pm8xxx: Add RTC support for PMIC PMK8350
  rtc: ab-eoz9: make use of RTC_FEATURE_ALARM
  rtc: ab-eoz9: add alarm support
  rtc: ab-eoz9: set regmap max_register
  rtc: pcf85063: fallback to parent of_node
  ...

21 files changed:
Documentation/devicetree/bindings/rtc/qcom-pm8xxx-rtc.yaml [new file with mode: 0644]
drivers/rtc/Kconfig
drivers/rtc/interface.c
drivers/rtc/rtc-ab-eoz9.c
drivers/rtc/rtc-ds1307.c
drivers/rtc/rtc-ds1511.c
drivers/rtc/rtc-fsl-ftm-alarm.c
drivers/rtc/rtc-imx-sc.c
drivers/rtc/rtc-imxdi.c
drivers/rtc/rtc-m48t59.c
drivers/rtc/rtc-mxc.c
drivers/rtc/rtc-omap.c
drivers/rtc/rtc-pcf85063.c
drivers/rtc/rtc-pcf8523.c
drivers/rtc/rtc-pm8xxx.c
drivers/rtc/rtc-rv3028.c
drivers/rtc/rtc-rx6110.c
drivers/rtc/rtc-s5m.c
drivers/rtc/rtc-spear.c
drivers/rtc/rtc-tps65910.c
drivers/rtc/sysfs.c

diff --git a/Documentation/devicetree/bindings/rtc/qcom-pm8xxx-rtc.yaml b/Documentation/devicetree/bindings/rtc/qcom-pm8xxx-rtc.yaml
new file mode 100644 (file)
index 0000000..4fba6db
--- /dev/null
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/qcom-pm8xxx-rtc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm PM8xxx PMIC RTC device
+
+maintainers:
+  - Satya Priya <skakit@codeaurora.org>
+
+properties:
+  compatible:
+    enum:
+      - qcom,pm8058-rtc
+      - qcom,pm8921-rtc
+      - qcom,pm8941-rtc
+      - qcom,pm8018-rtc
+      - qcom,pmk8350-rtc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  allow-set-time:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      Indicates that the setting of RTC time is allowed by the host CPU.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/spmi/spmi.h>
+    spmi_bus: spmi@c440000 {
+      reg = <0x0c440000 0x1100>;
+      #address-cells = <2>;
+      #size-cells = <0>;
+      pmicintc: pmic@0 {
+        reg = <0x0 SPMI_USID>;
+        compatible = "qcom,pm8921";
+        interrupts = <104 8>;
+        #interrupt-cells = <2>;
+        interrupt-controller;
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pm8921_rtc: rtc@11d {
+          compatible = "qcom,pm8921-rtc";
+          reg = <0x11d>;
+          interrupts = <0x27 0>;
+        };
+      };
+    };
+...
index 773386b4aeb78342cff005ca8f7009c597bebc83..d8c13fded164f8549aeee92651d32e22fcd95864 100644 (file)
@@ -1339,6 +1339,7 @@ config RTC_DRV_DIGICOLOR
 config RTC_DRV_IMXDI
        tristate "Freescale IMX DryIce Real Time Clock"
        depends on ARCH_MXC
+       depends on OF
        help
           Support for Freescale IMX DryIce RTC
 
@@ -1906,7 +1907,7 @@ config RTC_DRV_HID_SENSOR_TIME
 
 config RTC_DRV_GOLDFISH
        tristate "Goldfish Real Time Clock"
-       depends on OF && HAS_IOMEM
+       depends on HAS_IOMEM
        help
          Say yes to enable RTC driver for the Goldfish based virtual platform.
 
index dcb34c73319e3b9a1b243eb7eb4c83fbf0eb04f1..9a2bd4947007c79d992a3f77b1aae48b615683cc 100644 (file)
@@ -545,7 +545,7 @@ EXPORT_SYMBOL_GPL(rtc_alarm_irq_enable);
 
 int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
 {
-       int rc = 0, err;
+       int err;
 
        err = mutex_lock_interruptible(&rtc->ops_lock);
        if (err)
@@ -561,17 +561,21 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
        if (rtc->uie_rtctimer.enabled == enabled)
                goto out;
 
-       if (rtc->uie_unsupported) {
-               err = -EINVAL;
-               goto out;
+       if (rtc->uie_unsupported || !test_bit(RTC_FEATURE_ALARM, rtc->features)) {
+               mutex_unlock(&rtc->ops_lock);
+#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
+               return rtc_dev_update_irq_enable_emul(rtc, enabled);
+#else
+               return -EINVAL;
+#endif
        }
 
        if (enabled) {
                struct rtc_time tm;
                ktime_t now, onesec;
 
-               rc = __rtc_read_time(rtc, &tm);
-               if (rc)
+               err = __rtc_read_time(rtc, &tm);
+               if (err)
                        goto out;
                onesec = ktime_set(1, 0);
                now = rtc_tm_to_ktime(tm);
@@ -585,24 +589,6 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
 out:
        mutex_unlock(&rtc->ops_lock);
 
-       /*
-        * __rtc_read_time() failed, this probably means that the RTC time has
-        * never been set or less probably there is a transient error on the
-        * bus. In any case, avoid enabling emulation has this will fail when
-        * reading the time too.
-        */
-       if (rc)
-               return rc;
-
-#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
-       /*
-        * Enable emulation if the driver returned -EINVAL to signal that it has
-        * been configured without interrupts or they are not available at the
-        * moment.
-        */
-       if (err == -EINVAL)
-               err = rtc_dev_update_irq_enable_emul(rtc, enabled);
-#endif
        return err;
 }
 EXPORT_SYMBOL_GPL(rtc_update_irq_enable);
index b20d8f26dcdb85a7fddc4f2f00e8b4290cf89235..a9b355510cd47d5037cc25c577747268fbf6c682 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/bcd.h>
 #include <linux/of.h>
 #include <linux/regmap.h>
+#include <linux/bitfield.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 
 
 #define ABEOZ9_SEC_LEN                 7
 
+#define ABEOZ9_REG_ALARM_SEC           0x10
+#define ABEOZ9_BIT_ALARM_SEC           GENMASK(6, 0)
+#define ABEOZ9_REG_ALARM_MIN           0x11
+#define ABEOZ9_BIT_ALARM_MIN           GENMASK(6, 0)
+#define ABEOZ9_REG_ALARM_HOURS         0x12
+#define ABEOZ9_BIT_ALARM_HOURS_PM      BIT(5)
+#define ABEOZ9_BIT_ALARM_HOURS         GENMASK(4, 0)
+#define ABEOZ9_REG_ALARM_DAYS          0x13
+#define ABEOZ9_BIT_ALARM_DAYS          GENMASK(5, 0)
+#define ABEOZ9_REG_ALARM_WEEKDAYS      0x14
+#define ABEOZ9_BIT_ALARM_WEEKDAYS      GENMASK(2, 0)
+#define ABEOZ9_REG_ALARM_MONTHS                0x15
+#define ABEOZ9_BIT_ALARM_MONTHS                GENMASK(4, 0)
+#define ABEOZ9_REG_ALARM_YEARS         0x16
+
+#define ABEOZ9_ALARM_LEN               7
+#define ABEOZ9_BIT_ALARM_AE            BIT(7)
+
 #define ABEOZ9_REG_REG_TEMP            0x20
 #define ABEOZ953_TEMP_MAX              120
 #define ABEOZ953_TEMP_MIN              -60
@@ -186,6 +205,98 @@ static int abeoz9_rtc_set_time(struct device *dev, struct rtc_time *tm)
        return abeoz9_reset_validity(regmap);
 }
 
+static int abeoz9_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+       struct abeoz9_rtc_data *data = dev_get_drvdata(dev);
+       struct regmap *regmap = data->regmap;
+       u8 regs[ABEOZ9_ALARM_LEN];
+       u8 val[2];
+       int ret;
+
+       ret = abeoz9_check_validity(dev);
+       if (ret)
+               return ret;
+
+       ret = regmap_bulk_read(regmap, ABEOZ9_REG_CTRL_INT, val, sizeof(val));
+       if (ret)
+               return ret;
+
+       alarm->enabled = val[0] & ABEOZ9_REG_CTRL_INT_AIE;
+       alarm->pending = val[1] & ABEOZ9_REG_CTRL_INT_FLAG_AF;
+
+       ret = regmap_bulk_read(regmap, ABEOZ9_REG_ALARM_SEC, regs, sizeof(regs));
+       if (ret)
+               return ret;
+
+       alarm->time.tm_sec = bcd2bin(FIELD_GET(ABEOZ9_BIT_ALARM_SEC, regs[0]));
+       alarm->time.tm_min = bcd2bin(FIELD_GET(ABEOZ9_BIT_ALARM_MIN, regs[1]));
+       alarm->time.tm_hour = bcd2bin(FIELD_GET(ABEOZ9_BIT_ALARM_HOURS, regs[2]));
+       if (FIELD_GET(ABEOZ9_BIT_ALARM_HOURS_PM, regs[2]))
+               alarm->time.tm_hour += 12;
+
+       alarm->time.tm_mday = bcd2bin(FIELD_GET(ABEOZ9_BIT_ALARM_DAYS, regs[3]));
+
+       return 0;
+}
+
+static int abeoz9_rtc_alarm_irq_enable(struct device *dev, u32 enable)
+{
+       struct abeoz9_rtc_data *data = dev_get_drvdata(dev);
+
+       return regmap_update_bits(data->regmap, ABEOZ9_REG_CTRL_INT,
+                                 ABEOZ9_REG_CTRL_INT_AIE,
+                                 FIELD_PREP(ABEOZ9_REG_CTRL_INT_AIE, enable));
+}
+
+static int abeoz9_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+       struct abeoz9_rtc_data *data = dev_get_drvdata(dev);
+       u8 regs[ABEOZ9_ALARM_LEN] = {0};
+       int ret;
+
+       ret = regmap_update_bits(data->regmap, ABEOZ9_REG_CTRL_INT_FLAG,
+                                ABEOZ9_REG_CTRL_INT_FLAG_AF, 0);
+       if (ret)
+               return ret;
+
+       regs[0] = ABEOZ9_BIT_ALARM_AE | FIELD_PREP(ABEOZ9_BIT_ALARM_SEC,
+                                                  bin2bcd(alarm->time.tm_sec));
+       regs[1] = ABEOZ9_BIT_ALARM_AE | FIELD_PREP(ABEOZ9_BIT_ALARM_MIN,
+                                                  bin2bcd(alarm->time.tm_min));
+       regs[2] = ABEOZ9_BIT_ALARM_AE | FIELD_PREP(ABEOZ9_BIT_ALARM_HOURS,
+                                                  bin2bcd(alarm->time.tm_hour));
+       regs[3] = ABEOZ9_BIT_ALARM_AE | FIELD_PREP(ABEOZ9_BIT_ALARM_DAYS,
+                                                  bin2bcd(alarm->time.tm_mday));
+
+       ret = regmap_bulk_write(data->regmap, ABEOZ9_REG_ALARM_SEC, regs,
+                               sizeof(regs));
+       if (ret)
+               return ret;
+
+       return abeoz9_rtc_alarm_irq_enable(dev, alarm->enabled);
+}
+
+static irqreturn_t abeoz9_rtc_irq(int irq, void *dev)
+{
+       struct abeoz9_rtc_data *data = dev_get_drvdata(dev);
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(data->regmap, ABEOZ9_REG_CTRL_INT_FLAG, &val);
+       if (ret)
+               return IRQ_NONE;
+
+       if (!FIELD_GET(ABEOZ9_REG_CTRL_INT_FLAG_AF, val))
+               return IRQ_NONE;
+
+       regmap_update_bits(data->regmap, ABEOZ9_REG_CTRL_INT_FLAG,
+                          ABEOZ9_REG_CTRL_INT_FLAG_AF, 0);
+
+       rtc_update_irq(data->rtc, 1, RTC_IRQF | RTC_AF);
+
+       return IRQ_HANDLED;
+}
+
 static int abeoz9_trickle_parse_dt(struct device_node *node)
 {
        u32 ohms = 0;
@@ -258,12 +369,16 @@ static int abeoz9_rtc_setup(struct device *dev, struct device_node *node)
 
 static const struct rtc_class_ops rtc_ops = {
        .read_time = abeoz9_rtc_get_time,
-       .set_time  = abeoz9_rtc_set_time,
+       .set_time = abeoz9_rtc_set_time,
+       .read_alarm = abeoz9_rtc_read_alarm,
+       .set_alarm = abeoz9_rtc_set_alarm,
+       .alarm_irq_enable = abeoz9_rtc_alarm_irq_enable,
 };
 
 static const struct regmap_config abeoz9_rtc_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
+       .max_register = 0x3f,
 };
 
 #if IS_REACHABLE(CONFIG_HWMON)
@@ -419,6 +534,24 @@ static int abeoz9_probe(struct i2c_client *client,
        data->rtc->ops = &rtc_ops;
        data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
        data->rtc->range_max = RTC_TIMESTAMP_END_2099;
+       data->rtc->uie_unsupported = 1;
+       clear_bit(RTC_FEATURE_ALARM, data->rtc->features);
+
+       if (client->irq > 0) {
+               ret = devm_request_threaded_irq(dev, client->irq, NULL,
+                                               abeoz9_rtc_irq,
+                                               IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+                                               dev_name(dev), dev);
+               if (ret) {
+                       dev_err(dev, "failed to request alarm irq\n");
+                       return ret;
+               }
+       }
+
+       if (client->irq > 0 || device_property_read_bool(dev, "wakeup-source")) {
+               ret = device_init_wakeup(dev, true);
+               set_bit(RTC_FEATURE_ALARM, data->rtc->features);
+       }
 
        ret = devm_rtc_register_device(data->rtc);
        if (ret)
index cd8e438bc9c46b0baaa55727267b31e7cbffc2ac..336cb9aa5e336d74889343a7e53bcbeb269683fb 100644 (file)
@@ -169,9 +169,6 @@ enum ds_type {
 
 struct ds1307 {
        enum ds_type            type;
-       unsigned long           flags;
-#define HAS_NVRAM      0               /* bit 0 == sysfs file active */
-#define HAS_ALARM      1               /* bit 1 == irq claimed */
        struct device           *dev;
        struct regmap           *regmap;
        const char              *name;
@@ -296,7 +293,11 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
        t->tm_min = bcd2bin(regs[DS1307_REG_MIN] & 0x7f);
        tmp = regs[DS1307_REG_HOUR] & 0x3f;
        t->tm_hour = bcd2bin(tmp);
-       t->tm_wday = bcd2bin(regs[DS1307_REG_WDAY] & 0x07) - 1;
+       /* rx8130 is bit position, not BCD */
+       if (ds1307->type == rx_8130)
+               t->tm_wday = fls(regs[DS1307_REG_WDAY] & 0x7f);
+       else
+               t->tm_wday = bcd2bin(regs[DS1307_REG_WDAY] & 0x07) - 1;
        t->tm_mday = bcd2bin(regs[DS1307_REG_MDAY] & 0x3f);
        tmp = regs[DS1307_REG_MONTH] & 0x1f;
        t->tm_mon = bcd2bin(tmp) - 1;
@@ -343,7 +344,11 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
        regs[DS1307_REG_SECS] = bin2bcd(t->tm_sec);
        regs[DS1307_REG_MIN] = bin2bcd(t->tm_min);
        regs[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
-       regs[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1);
+       /* rx8130 is bit position, not BCD */
+       if (ds1307->type == rx_8130)
+               regs[DS1307_REG_WDAY] = 1 << t->tm_wday;
+       else
+               regs[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1);
        regs[DS1307_REG_MDAY] = bin2bcd(t->tm_mday);
        regs[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1);
 
@@ -411,9 +416,6 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
        int                     ret;
        u8                      regs[9];
 
-       if (!test_bit(HAS_ALARM, &ds1307->flags))
-               return -EINVAL;
-
        /* read all ALARM1, ALARM2, and status registers at once */
        ret = regmap_bulk_read(ds1307->regmap, DS1339_REG_ALARM1_SECS,
                               regs, sizeof(regs));
@@ -454,9 +456,6 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
        u8                      control, status;
        int                     ret;
 
-       if (!test_bit(HAS_ALARM, &ds1307->flags))
-               return -EINVAL;
-
        dev_dbg(dev, "%s secs=%d, mins=%d, "
                "hours=%d, mday=%d, enabled=%d, pending=%d\n",
                "alarm set", t->time.tm_sec, t->time.tm_min,
@@ -512,9 +511,6 @@ static int ds1307_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
        struct ds1307           *ds1307 = dev_get_drvdata(dev);
 
-       if (!test_bit(HAS_ALARM, &ds1307->flags))
-               return -ENOTTY;
-
        return regmap_update_bits(ds1307->regmap, DS1337_REG_CONTROL,
                                  DS1337_BIT_A1IE,
                                  enabled ? DS1337_BIT_A1IE : 0);
@@ -592,9 +588,6 @@ static int rx8130_read_alarm(struct device *dev, struct rtc_wkalrm *t)
        u8 ald[3], ctl[3];
        int ret;
 
-       if (!test_bit(HAS_ALARM, &ds1307->flags))
-               return -EINVAL;
-
        /* Read alarm registers. */
        ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_ALARM_MIN, ald,
                               sizeof(ald));
@@ -634,9 +627,6 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t)
        u8 ald[3], ctl[3];
        int ret;
 
-       if (!test_bit(HAS_ALARM, &ds1307->flags))
-               return -EINVAL;
-
        dev_dbg(dev, "%s, sec=%d min=%d hour=%d wday=%d mday=%d mon=%d "
                "enabled=%d pending=%d\n", __func__,
                t->time.tm_sec, t->time.tm_min, t->time.tm_hour,
@@ -681,9 +671,6 @@ static int rx8130_alarm_irq_enable(struct device *dev, unsigned int enabled)
        struct ds1307 *ds1307 = dev_get_drvdata(dev);
        int ret, reg;
 
-       if (!test_bit(HAS_ALARM, &ds1307->flags))
-               return -EINVAL;
-
        ret = regmap_read(ds1307->regmap, RX8130_REG_CONTROL0, &reg);
        if (ret < 0)
                return ret;
@@ -735,9 +722,6 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t)
        u8 regs[10];
        int ret;
 
-       if (!test_bit(HAS_ALARM, &ds1307->flags))
-               return -EINVAL;
-
        /* Read control and alarm 0 registers. */
        ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs,
                               sizeof(regs));
@@ -793,9 +777,6 @@ static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t)
        unsigned char regs[10];
        int wday, ret;
 
-       if (!test_bit(HAS_ALARM, &ds1307->flags))
-               return -EINVAL;
-
        wday = mcp794xx_alm_weekday(dev, &t->time);
        if (wday < 0)
                return wday;
@@ -842,9 +823,6 @@ static int mcp794xx_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
        struct ds1307 *ds1307 = dev_get_drvdata(dev);
 
-       if (!test_bit(HAS_ALARM, &ds1307->flags))
-               return -EINVAL;
-
        return regmap_update_bits(ds1307->regmap, MCP794XX_REG_CONTROL,
                                  MCP794XX_BIT_ALM0_EN,
                                  enabled ? MCP794XX_BIT_ALM0_EN : 0);
@@ -1641,7 +1619,7 @@ static int ds3231_clks_register(struct ds1307 *ds1307)
                 * Interrupt signal due to alarm conditions and square-wave
                 * output share same pin, so don't initialize both.
                 */
-               if (i == DS3231_CLK_SQW && test_bit(HAS_ALARM, &ds1307->flags))
+               if (i == DS3231_CLK_SQW && test_bit(RTC_FEATURE_ALARM, ds1307->rtc->features))
                        continue;
 
                init.name = ds3231_clks_names[i];
@@ -1964,15 +1942,15 @@ static int ds1307_probe(struct i2c_client *client,
                             bin2bcd(tmp));
        }
 
-       if (want_irq || ds1307_can_wakeup_device) {
-               device_set_wakeup_capable(ds1307->dev, true);
-               set_bit(HAS_ALARM, &ds1307->flags);
-       }
-
        ds1307->rtc = devm_rtc_allocate_device(ds1307->dev);
        if (IS_ERR(ds1307->rtc))
                return PTR_ERR(ds1307->rtc);
 
+       if (want_irq || ds1307_can_wakeup_device)
+               device_set_wakeup_capable(ds1307->dev, true);
+       else
+               clear_bit(RTC_FEATURE_ALARM, ds1307->rtc->features);
+
        if (ds1307_can_wakeup_device && !want_irq) {
                dev_info(ds1307->dev,
                         "'wakeup-source' is set, request for an IRQ is disabled!\n");
@@ -1988,7 +1966,7 @@ static int ds1307_probe(struct i2c_client *client,
                if (err) {
                        client->irq = 0;
                        device_set_wakeup_capable(ds1307->dev, false);
-                       clear_bit(HAS_ALARM, &ds1307->flags);
+                       clear_bit(RTC_FEATURE_ALARM, ds1307->rtc->features);
                        dev_err(ds1307->dev, "unable to request IRQ!\n");
                } else {
                        dev_dbg(ds1307->dev, "got IRQ %d\n", client->irq);
index bda8843330821eaaf579501231022008f3651a2f..1109cad83838496d92cd328bc14213f50f2c4413 100644 (file)
@@ -104,12 +104,6 @@ rtc_write(uint8_t val, uint32_t reg)
        writeb(val, ds1511_base + (reg * reg_spacing));
 }
 
-static inline void
-rtc_write_alarm(uint8_t val, enum ds1511reg reg)
-{
-       rtc_write((val | 0x80), reg);
-}
-
 static noinline uint8_t
 rtc_read(enum ds1511reg reg)
 {
index 57cc09d0a8067fd42656903d9600758ed61e89f2..c0df49fb978ce0ba5ae138c4fc0da04248fc5d78 100644 (file)
@@ -310,6 +310,7 @@ static const struct of_device_id ftm_rtc_match[] = {
        { .compatible = "fsl,lx2160a-ftm-alarm", },
        { },
 };
+MODULE_DEVICE_TABLE(of, ftm_rtc_match);
 
 static const struct acpi_device_id ftm_imx_acpi_ids[] = {
        {"NXP0014",},
index cc9fbab499994e901aa341653656ed7db7057987..814d516645e28307f1121ab9987cc3e00a1ba716 100644 (file)
@@ -80,16 +80,6 @@ static int imx_sc_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
        return imx_scu_irq_group_enable(SC_IRQ_GROUP_RTC, SC_IRQ_RTC, enable);
 }
 
-static int imx_sc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
-       /*
-        * SCU firmware does NOT provide read alarm API, but .read_alarm
-        * callback is required by RTC framework to support alarm function,
-        * so just return here.
-        */
-       return 0;
-}
-
 static int imx_sc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
        struct imx_sc_msg_timer_rtc_set_alarm msg;
@@ -127,7 +117,6 @@ static int imx_sc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 static const struct rtc_class_ops imx_sc_rtc_ops = {
        .read_time = imx_sc_rtc_read_time,
        .set_time = imx_sc_rtc_set_time,
-       .read_alarm = imx_sc_rtc_read_alarm,
        .set_alarm = imx_sc_rtc_set_alarm,
        .alarm_irq_enable = imx_sc_rtc_alarm_irq_enable,
 };
index c2692da74e098e43c3d7aa4594af663ce572b147..c1806f4d68e7692a3a8002de9390da7327b4dfde 100644 (file)
@@ -840,19 +840,17 @@ static int __exit dryice_rtc_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_OF
 static const struct of_device_id dryice_dt_ids[] = {
        { .compatible = "fsl,imx25-rtc" },
        { /* sentinel */ }
 };
 
 MODULE_DEVICE_TABLE(of, dryice_dt_ids);
-#endif
 
 static struct platform_driver dryice_rtc_driver = {
        .driver = {
                   .name = "imxdi_rtc",
-                  .of_match_table = of_match_ptr(dryice_dt_ids),
+                  .of_match_table = dryice_dt_ids,
                   },
        .remove = __exit_p(dryice_rtc_remove),
 };
index 1d2e99a70fce828c066b4bbdeedc427803321c2b..f0f6b9b6daecbfeb118676f6e71e7e480a24b246 100644 (file)
@@ -421,7 +421,7 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
        /* Try to get irq number. We also can work in
         * the mode without IRQ.
         */
-       m48t59->irq = platform_get_irq(pdev, 0);
+       m48t59->irq = platform_get_irq_optional(pdev, 0);
        if (m48t59->irq <= 0)
                m48t59->irq = NO_IRQ;
 
index db57dda7ab97b83c3e3a5d6b84ad92bf0cf6463f..0f08f22df869eed6882c5745022b926ebccdee58 100644 (file)
@@ -415,7 +415,7 @@ static int mxc_rtc_probe(struct platform_device *pdev)
 static struct platform_driver mxc_rtc_driver = {
        .driver = {
                   .name        = "mxc_rtc",
-                  .of_match_table = of_match_ptr(imx_rtc_dt_ids),
+                  .of_match_table = imx_rtc_dt_ids,
        },
        .probe = mxc_rtc_probe,
 };
index dc7db2477f883c7173f73bdc73416c0c9a82e630..d46e0f0cc50204b6368d50c0b1b0dd5f8f137b10 100644 (file)
@@ -786,8 +786,7 @@ static int omap_rtc_probe(struct platform_device *pdev)
        /* enable RTC functional clock */
        if (rtc->type->has_32kclk_en) {
                reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
-               rtc_writel(rtc, OMAP_RTC_OSC_REG,
-                               reg | OMAP_RTC_OSC_32KCLK_EN);
+               rtc_write(rtc, OMAP_RTC_OSC_REG, reg | OMAP_RTC_OSC_32KCLK_EN);
        }
 
        /* clear old status */
@@ -845,7 +844,7 @@ static int omap_rtc_probe(struct platform_device *pdev)
                reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
                reg &= ~OMAP_RTC_OSC_OSC32K_GZ_DISABLE;
                reg |= OMAP_RTC_OSC_32KCLK_EN | OMAP_RTC_OSC_SEL_32KCLK_SRC;
-               rtc_writel(rtc, OMAP_RTC_OSC_REG, reg);
+               rtc_write(rtc, OMAP_RTC_OSC_REG, reg);
        }
 
        rtc->type->lock(rtc);
index aef6c1ee8bb0e22794592e1c862542952e2d2b49..82becae1422990b616396bd9a46db9431882e259 100644 (file)
@@ -478,6 +478,7 @@ static struct clk *pcf85063_clkout_register_clk(struct pcf85063 *pcf85063)
 {
        struct clk *clk;
        struct clk_init_data init;
+       struct device_node *node = pcf85063->rtc->dev.parent->of_node;
 
        init.name = "pcf85063-clkout";
        init.ops = &pcf85063_clkout_ops;
@@ -487,15 +488,13 @@ static struct clk *pcf85063_clkout_register_clk(struct pcf85063 *pcf85063)
        pcf85063->clkout_hw.init = &init;
 
        /* optional override of the clockname */
-       of_property_read_string(pcf85063->rtc->dev.of_node,
-                               "clock-output-names", &init.name);
+       of_property_read_string(node, "clock-output-names", &init.name);
 
        /* register the clock */
        clk = devm_clk_register(&pcf85063->rtc->dev, &pcf85063->clkout_hw);
 
        if (!IS_ERR(clk))
-               of_clk_add_provider(pcf85063->rtc->dev.of_node,
-                                   of_clk_src_simple_get, clk);
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
 
        return clk;
 }
index 5e1e7b2a8c9a18608aa6f81659d7a804f630a4f7..740e2136ca98cd3468c72edd0a8c393461cccffb 100644 (file)
@@ -8,12 +8,15 @@
 #include <linux/module.h>
 #include <linux/rtc.h>
 #include <linux/of.h>
-
-#define DRIVER_NAME "rtc-pcf8523"
+#include <linux/pm_wakeirq.h>
 
 #define REG_CONTROL1 0x00
 #define REG_CONTROL1_CAP_SEL BIT(7)
 #define REG_CONTROL1_STOP    BIT(5)
+#define REG_CONTROL1_AIE    BIT(1)
+
+#define REG_CONTROL2 0x01
+#define REG_CONTROL2_AF BIT(3)
 
 #define REG_CONTROL3 0x02
 #define REG_CONTROL3_PM_BLD BIT(7) /* battery low detection disabled */
 #define REG_MONTHS   0x08
 #define REG_YEARS    0x09
 
+#define REG_MINUTE_ALARM       0x0a
+#define REG_HOUR_ALARM         0x0b
+#define REG_DAY_ALARM          0x0c
+#define REG_WEEKDAY_ALARM      0x0d
+#define ALARM_DIS BIT(7)
+
 #define REG_OFFSET   0x0e
 #define REG_OFFSET_MODE BIT(7)
 
+#define REG_TMR_CLKOUT_CTRL 0x0f
+
+struct pcf8523 {
+       struct rtc_device *rtc;
+       struct i2c_client *client;
+};
+
 static int pcf8523_read(struct i2c_client *client, u8 reg, u8 *valuep)
 {
        struct i2c_msg msgs[2];
@@ -140,6 +156,27 @@ static int pcf8523_set_pm(struct i2c_client *client, u8 pm)
        return 0;
 }
 
+static irqreturn_t pcf8523_irq(int irq, void *dev_id)
+{
+       struct pcf8523 *pcf8523 = i2c_get_clientdata(dev_id);
+       u8 value;
+       int err;
+
+       err = pcf8523_read(pcf8523->client, REG_CONTROL2, &value);
+       if (err < 0)
+               return IRQ_HANDLED;
+
+       if (value & REG_CONTROL2_AF) {
+               value &= ~REG_CONTROL2_AF;
+               pcf8523_write(pcf8523->client, REG_CONTROL2, value);
+               rtc_update_irq(pcf8523->rtc, 1, RTC_IRQF | RTC_AF);
+
+               return IRQ_HANDLED;
+       }
+
+       return IRQ_NONE;
+}
+
 static int pcf8523_stop_rtc(struct i2c_client *client)
 {
        u8 value;
@@ -259,11 +296,118 @@ static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm)
        return pcf8523_start_rtc(client);
 }
 
+static int pcf8523_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       u8 start = REG_MINUTE_ALARM, regs[4];
+       struct i2c_msg msgs[2];
+       u8 value;
+       int err;
+
+       msgs[0].addr = client->addr;
+       msgs[0].flags = 0;
+       msgs[0].len = 1;
+       msgs[0].buf = &start;
+
+       msgs[1].addr = client->addr;
+       msgs[1].flags = I2C_M_RD;
+       msgs[1].len = sizeof(regs);
+       msgs[1].buf = regs;
+
+       err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+       if (err < 0)
+               return err;
+
+       tm->time.tm_sec = 0;
+       tm->time.tm_min = bcd2bin(regs[0] & 0x7F);
+       tm->time.tm_hour = bcd2bin(regs[1] & 0x3F);
+       tm->time.tm_mday = bcd2bin(regs[2] & 0x3F);
+       tm->time.tm_wday = bcd2bin(regs[3] & 0x7);
+
+       err = pcf8523_read(client, REG_CONTROL1, &value);
+       if (err < 0)
+               return err;
+       tm->enabled = !!(value & REG_CONTROL1_AIE);
+
+       err = pcf8523_read(client, REG_CONTROL2, &value);
+       if (err < 0)
+               return err;
+       tm->pending = !!(value & REG_CONTROL2_AF);
+
+       return 0;
+}
+
+static int pcf8523_irq_enable(struct device *dev, unsigned int enabled)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       u8 value;
+       int err;
+
+       err = pcf8523_read(client, REG_CONTROL1, &value);
+       if (err < 0)
+               return err;
+
+       value &= REG_CONTROL1_AIE;
+
+       if (enabled)
+               value |= REG_CONTROL1_AIE;
+
+       err = pcf8523_write(client, REG_CONTROL1, value);
+       if (err < 0)
+               return err;
+
+       return 0;
+}
+
+static int pcf8523_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct i2c_msg msg;
+       u8 regs[5];
+       int err;
+
+       err = pcf8523_irq_enable(dev, 0);
+       if (err)
+               return err;
+
+       err = pcf8523_write(client, REG_CONTROL2, 0);
+       if (err < 0)
+               return err;
+
+       /* The alarm has no seconds, round up to nearest minute */
+       if (tm->time.tm_sec) {
+               time64_t alarm_time = rtc_tm_to_time64(&tm->time);
+
+               alarm_time += 60 - tm->time.tm_sec;
+               rtc_time64_to_tm(alarm_time, &tm->time);
+       }
+
+       regs[0] = REG_MINUTE_ALARM;
+       regs[1] = bin2bcd(tm->time.tm_min);
+       regs[2] = bin2bcd(tm->time.tm_hour);
+       regs[3] = bin2bcd(tm->time.tm_mday);
+       regs[4] = ALARM_DIS;
+       msg.addr = client->addr;
+       msg.flags = 0;
+       msg.len = sizeof(regs);
+       msg.buf = regs;
+       err = i2c_transfer(client->adapter, &msg, 1);
+       if (err < 0)
+               return err;
+
+       if (tm->enabled)
+               return pcf8523_irq_enable(dev, tm->enabled);
+
+       return 0;
+}
+
 #ifdef CONFIG_RTC_INTF_DEV
 static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
                             unsigned long arg)
 {
        struct i2c_client *client = to_i2c_client(dev);
+       unsigned int flags = 0;
+       u8 value;
        int ret;
 
        switch (cmd) {
@@ -272,9 +416,16 @@ static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
                if (ret < 0)
                        return ret;
                if (ret)
-                       ret = RTC_VL_BACKUP_LOW;
+                       flags |= RTC_VL_BACKUP_LOW;
 
-               return put_user(ret, (unsigned int __user *)arg);
+               ret = pcf8523_read(client, REG_SECONDS, &value);
+               if (ret < 0)
+                       return ret;
+
+               if (value & REG_SECONDS_OS)
+                       flags |= RTC_VL_DATA_INVALID;
+
+               return put_user(flags, (unsigned int __user *)arg);
 
        default:
                return -ENOIOCTLCMD;
@@ -322,6 +473,9 @@ static int pcf8523_rtc_set_offset(struct device *dev, long offset)
 static const struct rtc_class_ops pcf8523_rtc_ops = {
        .read_time = pcf8523_rtc_read_time,
        .set_time = pcf8523_rtc_set_time,
+       .read_alarm = pcf8523_rtc_read_alarm,
+       .set_alarm = pcf8523_rtc_set_alarm,
+       .alarm_irq_enable = pcf8523_irq_enable,
        .ioctl = pcf8523_rtc_ioctl,
        .read_offset = pcf8523_rtc_read_offset,
        .set_offset = pcf8523_rtc_set_offset,
@@ -330,12 +484,21 @@ static const struct rtc_class_ops pcf8523_rtc_ops = {
 static int pcf8523_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
+       struct pcf8523 *pcf8523;
        struct rtc_device *rtc;
+       bool wakeup_source = false;
        int err;
 
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
                return -ENODEV;
 
+       pcf8523 = devm_kzalloc(&client->dev, sizeof(struct pcf8523), GFP_KERNEL);
+       if (!pcf8523)
+               return -ENOMEM;
+
+       i2c_set_clientdata(client, pcf8523);
+       pcf8523->client = client;
+
        err = pcf8523_load_capacitance(client);
        if (err < 0)
                dev_warn(&client->dev, "failed to set xtal load capacitance: %d",
@@ -349,9 +512,32 @@ static int pcf8523_probe(struct i2c_client *client,
        if (IS_ERR(rtc))
                return PTR_ERR(rtc);
 
+       pcf8523->rtc = rtc;
        rtc->ops = &pcf8523_rtc_ops;
        rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
        rtc->range_max = RTC_TIMESTAMP_END_2099;
+       rtc->uie_unsupported = 1;
+
+       if (client->irq > 0) {
+               err = pcf8523_write(client, REG_TMR_CLKOUT_CTRL, 0x38);
+               if (err < 0)
+                       return err;
+
+               err = devm_request_threaded_irq(&client->dev, client->irq,
+                                               NULL, pcf8523_irq,
+                                               IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_LOW,
+                                               dev_name(&rtc->dev), client);
+               if (err)
+                       return err;
+
+               dev_pm_set_wake_irq(&client->dev, client->irq);
+       }
+
+#ifdef CONFIG_OF
+       wakeup_source = of_property_read_bool(client->dev.of_node, "wakeup-source");
+#endif
+       if (client->irq > 0 || wakeup_source)
+               device_init_wakeup(&client->dev, true);
 
        return devm_rtc_register_device(rtc);
 }
@@ -373,7 +559,7 @@ MODULE_DEVICE_TABLE(of, pcf8523_of_match);
 
 static struct i2c_driver pcf8523_driver = {
        .driver = {
-               .name = DRIVER_NAME,
+               .name = "rtc-pcf8523",
                .of_match_table = of_match_ptr(pcf8523_of_match),
        },
        .probe = pcf8523_probe,
index eb206597a8fa67845898ca33ec04478c9d90dca9..29a1c65661e99d21a4c11754bb94aa379baba181 100644 (file)
@@ -445,6 +445,16 @@ static const struct pm8xxx_rtc_regs pm8941_regs = {
        .alarm_en       = BIT(7),
 };
 
+static const struct pm8xxx_rtc_regs pmk8350_regs = {
+       .ctrl           = 0x6146,
+       .write          = 0x6140,
+       .read           = 0x6148,
+       .alarm_rw       = 0x6240,
+       .alarm_ctrl     = 0x6246,
+       .alarm_ctrl2    = 0x6248,
+       .alarm_en       = BIT(7),
+};
+
 /*
  * Hardcoded RTC bases until IORESOURCE_REG mapping is figured out
  */
@@ -453,6 +463,7 @@ static const struct of_device_id pm8xxx_id_table[] = {
        { .compatible = "qcom,pm8018-rtc", .data = &pm8921_regs },
        { .compatible = "qcom,pm8058-rtc", .data = &pm8058_regs },
        { .compatible = "qcom,pm8941-rtc", .data = &pm8941_regs },
+       { .compatible = "qcom,pmk8350-rtc", .data = &pmk8350_regs },
        { },
 };
 MODULE_DEVICE_TABLE(of, pm8xxx_id_table);
index 0c48d980d06ae14d5659269ed87493f9e21efce6..12c807306893f083e2c0a8030d17f35c1c5e3de7 100644 (file)
@@ -320,7 +320,7 @@ static int rv3028_get_time(struct device *dev, struct rtc_time *tm)
        tm->tm_sec  = bcd2bin(date[RV3028_SEC] & 0x7f);
        tm->tm_min  = bcd2bin(date[RV3028_MIN] & 0x7f);
        tm->tm_hour = bcd2bin(date[RV3028_HOUR] & 0x3f);
-       tm->tm_wday = ilog2(date[RV3028_WDAY] & 0x7f);
+       tm->tm_wday = date[RV3028_WDAY] & 0x7f;
        tm->tm_mday = bcd2bin(date[RV3028_DAY] & 0x3f);
        tm->tm_mon  = bcd2bin(date[RV3028_MONTH] & 0x1f) - 1;
        tm->tm_year = bcd2bin(date[RV3028_YEAR]) + 100;
@@ -337,7 +337,7 @@ static int rv3028_set_time(struct device *dev, struct rtc_time *tm)
        date[RV3028_SEC]   = bin2bcd(tm->tm_sec);
        date[RV3028_MIN]   = bin2bcd(tm->tm_min);
        date[RV3028_HOUR]  = bin2bcd(tm->tm_hour);
-       date[RV3028_WDAY]  = 1 << (tm->tm_wday);
+       date[RV3028_WDAY]  = tm->tm_wday;
        date[RV3028_DAY]   = bin2bcd(tm->tm_mday);
        date[RV3028_MONTH] = bin2bcd(tm->tm_mon + 1);
        date[RV3028_YEAR]  = bin2bcd(tm->tm_year - 100);
index 79161d4c6ce4d204edc03cea37bb02e6c646f06f..f4d425002f7fdbabc7f80156c16294d067aabb8e 100644 (file)
@@ -447,6 +447,12 @@ static int rx6110_i2c_probe(struct i2c_client *client,
        return rx6110_probe(rx6110, &client->dev);
 }
 
+static const struct acpi_device_id rx6110_i2c_acpi_match[] = {
+       { "SECC6110" },
+       { }
+};
+MODULE_DEVICE_TABLE(acpi, rx6110_i2c_acpi_match);
+
 static const struct i2c_device_id rx6110_i2c_id[] = {
        { "rx6110", 0 },
        { }
@@ -456,6 +462,7 @@ MODULE_DEVICE_TABLE(i2c, rx6110_i2c_id);
 static struct i2c_driver rx6110_i2c_driver = {
        .driver = {
                .name = RX6110_DRIVER_NAME,
+               .acpi_match_table = rx6110_i2c_acpi_match,
        },
        .probe          = rx6110_i2c_probe,
        .id_table       = rx6110_i2c_id,
index 80b66f16db899f180b13a6b96749c8f68c59f65a..038269a6b08c5518dcb730e8659d93026f953ae0 100644 (file)
@@ -713,16 +713,10 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
 static int s5m_rtc_probe(struct platform_device *pdev)
 {
        struct sec_pmic_dev *s5m87xx = dev_get_drvdata(pdev->dev.parent);
-       struct sec_platform_data *pdata = s5m87xx->pdata;
        struct s5m_rtc_info *info;
        const struct regmap_config *regmap_cfg;
        int ret, alarm_irq;
 
-       if (!pdata) {
-               dev_err(pdev->dev.parent, "Platform data not supplied\n");
-               return -ENODEV;
-       }
-
        info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
        if (!info)
                return -ENOMEM;
index 833daeb7b60e506a38b569fa655b9783402791e3..ee721e53c155b74e6abfbf485f5ba89490ca73f1 100644 (file)
@@ -153,12 +153,12 @@ static void rtc_wait_not_busy(struct spear_rtc_config *config)
 static irqreturn_t spear_rtc_irq(int irq, void *dev_id)
 {
        struct spear_rtc_config *config = dev_id;
-       unsigned long flags, events = 0;
+       unsigned long events = 0;
        unsigned int irq_data;
 
-       spin_lock_irqsave(&config->lock, flags);
+       spin_lock(&config->lock);
        irq_data = readl(config->ioaddr + STATUS_REG);
-       spin_unlock_irqrestore(&config->lock, flags);
+       spin_unlock(&config->lock);
 
        if ((irq_data & RTC_INT_MASK)) {
                spear_rtc_clear_interrupt(config);
index 288abb1abdb8df52084ad61a32612ed7bcacd452..bc89c62ccb9b5447f56f0d58c2def9098929385a 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/rtc.h>
 #include <linux/bcd.h>
 #include <linux/math64.h>
+#include <linux/property.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/mfd/tps65910.h>
index 8a957d31a1a4a77d8771b583ae32163cf840580e..74026f67fdfb07fbfdd6ebdf079a9bc292b2e42f 100644 (file)
@@ -273,7 +273,7 @@ static bool rtc_does_wakealarm(struct rtc_device *rtc)
        if (!device_can_wakeup(rtc->dev.parent))
                return false;
 
-       return rtc->ops->set_alarm != NULL;
+       return !!test_bit(RTC_FEATURE_ALARM, rtc->features);
 }
 
 static umode_t rtc_attr_is_visible(struct kobject *kobj,