Merge tag 'rtc-4.6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 25 Mar 2016 05:49:08 +0000 (22:49 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 25 Mar 2016 05:49:08 +0000 (22:49 -0700)
Pull more RTC updates from Alexandre Belloni:
 "A second pull request for v4.6 with a few fixesi before -rc1.  The new
  features for abx80x actually make the RTC behave correctly.

  Drivers:
   - abx80x: handle both XT and RC oscillators, XT failure bit and
     autocalibration
   - m41t80: avoid out of range year values
   - rv8803: workaround an i2c HW issue"

* tag 'rtc-4.6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux:
  rtc: abx80x: handle the oscillator failure bit
  rtc: abx80x: handle autocalibration
  rtc: rv8803: workaround i2c HW issue
  rtc: mcp795: add devicetree support
  rtc: asm9260: remove incorrect __init/__exit annotations
  rtc: m41t80: avoid out of range year values
  rtc: s3c: Don't print an error on probe deferral
  rtc: rv3029: stop mentioning rv3029c2

Documentation/devicetree/bindings/rtc/maxim,mcp795.txt [new file with mode: 0644]
drivers/rtc/Kconfig
drivers/rtc/rtc-abx80x.c
drivers/rtc/rtc-asm9260.c
drivers/rtc/rtc-m41t80.c
drivers/rtc/rtc-mcp795.c
drivers/rtc/rtc-rv8803.c
drivers/rtc/rtc-s3c.c

diff --git a/Documentation/devicetree/bindings/rtc/maxim,mcp795.txt b/Documentation/devicetree/bindings/rtc/maxim,mcp795.txt
new file mode 100644 (file)
index 0000000..a59fdd8
--- /dev/null
@@ -0,0 +1,11 @@
+* Maxim MCP795         SPI Serial Real-Time Clock
+
+Required properties:
+- compatible: Should contain "maxim,mcp795".
+- reg: SPI address for chip
+
+Example:
+       mcp795: rtc@0 {
+               compatible = "maxim,mcp795";
+               reg = <0>;
+       };
index 544bd34..3e84315 100644 (file)
@@ -589,7 +589,7 @@ config RTC_DRV_RV3029_HWMON
        default y
        help
          Say Y here if you want to expose temperature sensor data on
-         rtc-rv3029c2.
+         rtc-rv3029.
 
 config RTC_DRV_RV8803
        tristate "Micro Crystal RV8803"
index d41bbcd..ba0d619 100644 (file)
 
 #define ABX8XX_REG_CD_TIMER_CTL        0x18
 
+#define ABX8XX_REG_OSC         0x1c
+#define ABX8XX_OSC_FOS         BIT(3)
+#define ABX8XX_OSC_BOS         BIT(4)
+#define ABX8XX_OSC_ACAL_512    BIT(5)
+#define ABX8XX_OSC_ACAL_1024   BIT(6)
+
+#define ABX8XX_OSC_OSEL                BIT(7)
+
+#define ABX8XX_REG_OSS         0x1d
+#define ABX8XX_OSS_OF          BIT(1)
+#define ABX8XX_OSS_OMODE       BIT(4)
+
 #define ABX8XX_REG_CFG_KEY     0x1f
+#define ABX8XX_CFG_KEY_OSC     0xa1
 #define ABX8XX_CFG_KEY_MISC    0x9d
 
 #define ABX8XX_REG_ID0         0x28
@@ -81,6 +94,20 @@ static struct abx80x_cap abx80x_caps[] = {
        [ABX80X] = {.pn = 0}
 };
 
+static int abx80x_is_rc_mode(struct i2c_client *client)
+{
+       int flags = 0;
+
+       flags =  i2c_smbus_read_byte_data(client, ABX8XX_REG_OSS);
+       if (flags < 0) {
+               dev_err(&client->dev,
+                       "Failed to read autocalibration attribute\n");
+               return flags;
+       }
+
+       return (flags & ABX8XX_OSS_OMODE) ? 1 : 0;
+}
+
 static int abx80x_enable_trickle_charger(struct i2c_client *client,
                                         u8 trickle_cfg)
 {
@@ -112,7 +139,23 @@ static int abx80x_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
        struct i2c_client *client = to_i2c_client(dev);
        unsigned char buf[8];
-       int err;
+       int err, flags, rc_mode = 0;
+
+       /* Read the Oscillator Failure only in XT mode */
+       rc_mode = abx80x_is_rc_mode(client);
+       if (rc_mode < 0)
+               return rc_mode;
+
+       if (!rc_mode) {
+               flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSS);
+               if (flags < 0)
+                       return flags;
+
+               if (flags & ABX8XX_OSS_OF) {
+                       dev_err(dev, "Oscillator failure, data is invalid.\n");
+                       return -EINVAL;
+               }
+       }
 
        err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_HTH,
                                            sizeof(buf), buf);
@@ -140,7 +183,7 @@ static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
        struct i2c_client *client = to_i2c_client(dev);
        unsigned char buf[8];
-       int err;
+       int err, flags;
 
        if (tm->tm_year < 100)
                return -EINVAL;
@@ -161,6 +204,18 @@ static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
                return -EIO;
        }
 
+       /* Clear the OF bit of Oscillator Status Register */
+       flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSS);
+       if (flags < 0)
+               return flags;
+
+       err = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSS,
+                                       flags & ~ABX8XX_OSS_OF);
+       if (err < 0) {
+               dev_err(&client->dev, "Unable to write oscillator status register\n");
+               return err;
+       }
+
        return 0;
 }
 
@@ -248,6 +303,174 @@ static int abx80x_set_alarm(struct device *dev, struct rtc_wkalrm *t)
        return 0;
 }
 
+static int abx80x_rtc_set_autocalibration(struct device *dev,
+                                         int autocalibration)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       int retval, flags = 0;
+
+       if ((autocalibration != 0) && (autocalibration != 1024) &&
+           (autocalibration != 512)) {
+               dev_err(dev, "autocalibration value outside permitted range\n");
+               return -EINVAL;
+       }
+
+       flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSC);
+       if (flags < 0)
+               return flags;
+
+       if (autocalibration == 0) {
+               flags &= ~(ABX8XX_OSC_ACAL_512 | ABX8XX_OSC_ACAL_1024);
+       } else if (autocalibration == 1024) {
+               /* 1024 autocalibration is 0x10 */
+               flags |= ABX8XX_OSC_ACAL_1024;
+               flags &= ~(ABX8XX_OSC_ACAL_512);
+       } else {
+               /* 512 autocalibration is 0x11 */
+               flags |= (ABX8XX_OSC_ACAL_1024 | ABX8XX_OSC_ACAL_512);
+       }
+
+       /* Unlock write access to Oscillator Control Register */
+       retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY,
+                                          ABX8XX_CFG_KEY_OSC);
+       if (retval < 0) {
+               dev_err(dev, "Failed to write CONFIG_KEY register\n");
+               return retval;
+       }
+
+       retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSC, flags);
+
+       return retval;
+}
+
+static int abx80x_rtc_get_autocalibration(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       int flags = 0, autocalibration;
+
+       flags =  i2c_smbus_read_byte_data(client, ABX8XX_REG_OSC);
+       if (flags < 0)
+               return flags;
+
+       if (flags & ABX8XX_OSC_ACAL_512)
+               autocalibration = 512;
+       else if (flags & ABX8XX_OSC_ACAL_1024)
+               autocalibration = 1024;
+       else
+               autocalibration = 0;
+
+       return autocalibration;
+}
+
+static ssize_t autocalibration_store(struct device *dev,
+                                    struct device_attribute *attr,
+                                    const char *buf, size_t count)
+{
+       int retval;
+       unsigned long autocalibration = 0;
+
+       retval = kstrtoul(buf, 10, &autocalibration);
+       if (retval < 0) {
+               dev_err(dev, "Failed to store RTC autocalibration attribute\n");
+               return -EINVAL;
+       }
+
+       retval = abx80x_rtc_set_autocalibration(dev, autocalibration);
+
+       return retval ? retval : count;
+}
+
+static ssize_t autocalibration_show(struct device *dev,
+                                   struct device_attribute *attr, char *buf)
+{
+       int autocalibration = 0;
+
+       autocalibration = abx80x_rtc_get_autocalibration(dev);
+       if (autocalibration < 0) {
+               dev_err(dev, "Failed to read RTC autocalibration\n");
+               sprintf(buf, "0\n");
+               return autocalibration;
+       }
+
+       return sprintf(buf, "%d\n", autocalibration);
+}
+
+static DEVICE_ATTR_RW(autocalibration);
+
+static ssize_t oscillator_store(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       int retval, flags, rc_mode = 0;
+
+       if (strncmp(buf, "rc", 2) == 0) {
+               rc_mode = 1;
+       } else if (strncmp(buf, "xtal", 4) == 0) {
+               rc_mode = 0;
+       } else {
+               dev_err(dev, "Oscillator selection value outside permitted ones\n");
+               return -EINVAL;
+       }
+
+       flags =  i2c_smbus_read_byte_data(client, ABX8XX_REG_OSC);
+       if (flags < 0)
+               return flags;
+
+       if (rc_mode == 0)
+               flags &= ~(ABX8XX_OSC_OSEL);
+       else
+               flags |= (ABX8XX_OSC_OSEL);
+
+       /* Unlock write access on Oscillator Control register */
+       retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY,
+                                          ABX8XX_CFG_KEY_OSC);
+       if (retval < 0) {
+               dev_err(dev, "Failed to write CONFIG_KEY register\n");
+               return retval;
+       }
+
+       retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSC, flags);
+       if (retval < 0) {
+               dev_err(dev, "Failed to write Oscillator Control register\n");
+               return retval;
+       }
+
+       return retval ? retval : count;
+}
+
+static ssize_t oscillator_show(struct device *dev,
+                              struct device_attribute *attr, char *buf)
+{
+       int rc_mode = 0;
+       struct i2c_client *client = to_i2c_client(dev);
+
+       rc_mode = abx80x_is_rc_mode(client);
+
+       if (rc_mode < 0) {
+               dev_err(dev, "Failed to read RTC oscillator selection\n");
+               sprintf(buf, "\n");
+               return rc_mode;
+       }
+
+       if (rc_mode)
+               return sprintf(buf, "rc\n");
+       else
+               return sprintf(buf, "xtal\n");
+}
+
+static DEVICE_ATTR_RW(oscillator);
+
+static struct attribute *rtc_calib_attrs[] = {
+       &dev_attr_autocalibration.attr,
+       &dev_attr_oscillator.attr,
+       NULL,
+};
+
+static const struct attribute_group rtc_calib_attr_group = {
+       .attrs          = rtc_calib_attrs,
+};
+
 static int abx80x_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
        struct i2c_client *client = to_i2c_client(dev);
@@ -303,6 +526,13 @@ static int abx80x_dt_trickle_cfg(struct device_node *np)
        return (trickle_cfg | i);
 }
 
+static void rtc_calib_remove_sysfs_group(void *_dev)
+{
+       struct device *dev = _dev;
+
+       sysfs_remove_group(&dev->kobj, &rtc_calib_attr_group);
+}
+
 static int abx80x_probe(struct i2c_client *client,
                        const struct i2c_device_id *id)
 {
@@ -405,6 +635,24 @@ static int abx80x_probe(struct i2c_client *client,
                }
        }
 
+       /* Export sysfs entries */
+       err = sysfs_create_group(&(&client->dev)->kobj, &rtc_calib_attr_group);
+       if (err) {
+               dev_err(&client->dev, "Failed to create sysfs group: %d\n",
+                       err);
+               return err;
+       }
+
+       err = devm_add_action(&client->dev, rtc_calib_remove_sysfs_group,
+                             &client->dev);
+       if (err) {
+               rtc_calib_remove_sysfs_group(&client->dev);
+               dev_err(&client->dev,
+                       "Failed to add sysfs cleanup action: %d\n",
+                       err);
+               return err;
+       }
+
        return 0;
 }
 
index 14e08c4..355fdb9 100644 (file)
@@ -255,7 +255,7 @@ static const struct rtc_class_ops asm9260_rtc_ops = {
        .alarm_irq_enable       = asm9260_alarm_irq_enable,
 };
 
-static int __init asm9260_rtc_probe(struct platform_device *pdev)
+static int asm9260_rtc_probe(struct platform_device *pdev)
 {
        struct asm9260_rtc_priv *priv;
        struct device *dev = &pdev->dev;
@@ -323,7 +323,7 @@ err_return:
        return ret;
 }
 
-static int __exit asm9260_rtc_remove(struct platform_device *pdev)
+static int asm9260_rtc_remove(struct platform_device *pdev)
 {
        struct asm9260_rtc_priv *priv = platform_get_drvdata(pdev);
 
index a82937e..d107a8e 100644 (file)
@@ -176,7 +176,13 @@ static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm)
                bin2bcd(tm->tm_mday) | (buf[M41T80_REG_DAY] & ~0x3f);
        buf[M41T80_REG_MON] =
                bin2bcd(tm->tm_mon + 1) | (buf[M41T80_REG_MON] & ~0x1f);
+
        /* assume 20YY not 19YY */
+       if (tm->tm_year < 100 || tm->tm_year > 199) {
+               dev_err(&client->dev, "Year must be between 2000 and 2099. It's %d.\n",
+                       tm->tm_year + 1900);
+               return -EINVAL;
+       }
        buf[M41T80_REG_YEAR] = bin2bcd(tm->tm_year % 100);
 
        if (i2c_transfer(client->adapter, msgs, 1) != 1) {
index 1c91ce8..025bb33 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/printk.h>
 #include <linux/spi/spi.h>
 #include <linux/rtc.h>
+#include <linux/of.h>
 
 /* MCP795 Instructions, see datasheet table 3-1 */
 #define MCP795_EEREAD  0x03
@@ -183,9 +184,18 @@ static int mcp795_probe(struct spi_device *spi)
        return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id mcp795_of_match[] = {
+       { .compatible = "maxim,mcp795" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, mcp795_of_match);
+#endif
+
 static struct spi_driver mcp795_driver = {
                .driver = {
                                .name = "rtc-mcp795",
+                               .of_match_table = of_match_ptr(mcp795_of_match),
                },
                .probe = mcp795_probe,
 };
index 8d9f35c..f623038 100644 (file)
@@ -61,11 +61,14 @@ static irqreturn_t rv8803_handle_irq(int irq, void *dev_id)
        struct i2c_client *client = dev_id;
        struct rv8803_data *rv8803 = i2c_get_clientdata(client);
        unsigned long events = 0;
-       int flags;
+       int flags, try = 0;
 
        mutex_lock(&rv8803->flags_lock);
 
-       flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
+       do {
+               flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
+               try++;
+       } while ((flags == -ENXIO) && (try < 3));
        if (flags <= 0) {
                mutex_unlock(&rv8803->flags_lock);
                return IRQ_NONE;
@@ -424,7 +427,7 @@ static int rv8803_probe(struct i2c_client *client,
 {
        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
        struct rv8803_data *rv8803;
-       int err, flags;
+       int err, flags, try = 0;
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
                                     I2C_FUNC_SMBUS_I2C_BLOCK)) {
@@ -441,7 +444,16 @@ static int rv8803_probe(struct i2c_client *client,
        rv8803->client = client;
        i2c_set_clientdata(client, rv8803);
 
-       flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
+       /*
+        * There is a 60µs window where the RTC may not reply on the i2c bus in
+        * that case, the transfer is not ACKed. In that case, ensure there are
+        * multiple attempts.
+        */
+       do {
+               flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
+               try++;
+       } while ((flags == -ENXIO) && (try < 3));
+
        if (flags < 0)
                return flags;
 
@@ -476,8 +488,12 @@ static int rv8803_probe(struct i2c_client *client,
                return PTR_ERR(rv8803->rtc);
        }
 
-       err = i2c_smbus_write_byte_data(rv8803->client, RV8803_EXT,
-                                       RV8803_EXT_WADA);
+       try = 0;
+       do {
+               err = i2c_smbus_write_byte_data(rv8803->client, RV8803_EXT,
+                                               RV8803_EXT_WADA);
+               try++;
+       } while ((err == -ENXIO) && (try < 3));
        if (err)
                return err;
 
index ffb860d..d01ad7e 100644 (file)
@@ -501,18 +501,27 @@ static int s3c_rtc_probe(struct platform_device *pdev)
 
        info->rtc_clk = devm_clk_get(&pdev->dev, "rtc");
        if (IS_ERR(info->rtc_clk)) {
-               dev_err(&pdev->dev, "failed to find rtc clock\n");
-               return PTR_ERR(info->rtc_clk);
+               ret = PTR_ERR(info->rtc_clk);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "failed to find rtc clock\n");
+               else
+                       dev_dbg(&pdev->dev, "probe deferred due to missing rtc clk\n");
+               return ret;
        }
        clk_prepare_enable(info->rtc_clk);
 
        if (info->data->needs_src_clk) {
                info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src");
                if (IS_ERR(info->rtc_src_clk)) {
-                       dev_err(&pdev->dev,
-                               "failed to find rtc source clock\n");
+                       ret = PTR_ERR(info->rtc_src_clk);
+                       if (ret != -EPROBE_DEFER)
+                               dev_err(&pdev->dev,
+                                       "failed to find rtc source clock\n");
+                       else
+                               dev_dbg(&pdev->dev,
+                                       "probe deferred due to missing rtc src clk\n");
                        clk_disable_unprepare(info->rtc_clk);
-                       return PTR_ERR(info->rtc_src_clk);
+                       return ret;
                }
                clk_prepare_enable(info->rtc_src_clk);
        }