Merge branch 'ipvs'
[deliverable/linux.git] / drivers / rtc / rtc-m41t80.c
index a5248aa1abf143c852597ff12e4ecda0bcd9cd7e..7ff7427c2e6ac9cb6d4e4d6232cf5fd50998bd5f 100644 (file)
@@ -66,8 +66,6 @@
 #define M41T80_FEATURE_WD      (1 << 3)        /* Extra watchdog resolution */
 #define M41T80_FEATURE_SQ_ALT  (1 << 4)        /* RSx bits are in reg 4 */
 
-#define DRV_VERSION "0.05"
-
 static DEFINE_MUTEX(m41t80_rtc_mutex);
 static const struct i2c_device_id m41t80_id[] = {
        { "m41t62", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT },
@@ -80,6 +78,7 @@ static const struct i2c_device_id m41t80_id[] = {
        { "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
        { "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
        { "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
+       { "rv4162", M41T80_FEATURE_SQ | M41T80_FEATURE_WD | M41T80_FEATURE_SQ_ALT },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, m41t80_id);
@@ -232,7 +231,7 @@ static ssize_t m41t80_sysfs_show_flags(struct device *dev,
 
        val = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
        if (val < 0)
-               return -EIO;
+               return val;
        return sprintf(buf, "%#x\n", val);
 }
 static DEVICE_ATTR(flags, S_IRUGO, m41t80_sysfs_show_flags, NULL);
@@ -252,7 +251,7 @@ static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev,
                reg_sqw = M41T80_REG_WDAY;
        val = i2c_smbus_read_byte_data(client, reg_sqw);
        if (val < 0)
-               return -EIO;
+               return val;
        val = (val >> 4) & 0xf;
        switch (val) {
        case 0:
@@ -271,7 +270,7 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct m41t80_data *clientdata = i2c_get_clientdata(client);
-       int almon, sqw, reg_sqw;
+       int almon, sqw, reg_sqw, rc;
        int val = simple_strtoul(buf, NULL, 0);
 
        if (!(clientdata->features & M41T80_FEATURE_SQ))
@@ -291,21 +290,30 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
        /* disable SQW, set SQW frequency & re-enable */
        almon = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
        if (almon < 0)
-               return -EIO;
+               return almon;
        reg_sqw = M41T80_REG_SQW;
        if (clientdata->features & M41T80_FEATURE_SQ_ALT)
                reg_sqw = M41T80_REG_WDAY;
        sqw = i2c_smbus_read_byte_data(client, reg_sqw);
        if (sqw < 0)
-               return -EIO;
+               return sqw;
        sqw = (sqw & 0x0f) | (val << 4);
-       if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
-                                     almon & ~M41T80_ALMON_SQWE) < 0 ||
-           i2c_smbus_write_byte_data(client, reg_sqw, sqw) < 0)
-               return -EIO;
-       if (val && i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
-                                            almon | M41T80_ALMON_SQWE) < 0)
-               return -EIO;
+
+       rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
+                                     almon & ~M41T80_ALMON_SQWE);
+       if (rc < 0)
+               return rc;
+
+       if (val) {
+               rc = i2c_smbus_write_byte_data(client, reg_sqw, sqw);
+               if (rc < 0)
+                       return rc;
+
+               rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
+                                            almon | M41T80_ALMON_SQWE);
+               if (rc <0)
+                       return rc;
+       }
        return count;
 }
 static DEVICE_ATTR(sqwfreq, S_IRUGO | S_IWUSR,
@@ -629,40 +637,28 @@ static int m41t80_probe(struct i2c_client *client,
        struct m41t80_data *clientdata = NULL;
 
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C
-                                    | I2C_FUNC_SMBUS_BYTE_DATA)) {
-               rc = -ENODEV;
-               goto exit;
-       }
-
-       dev_info(&client->dev,
-                "chip found, driver version " DRV_VERSION "\n");
+                                    | I2C_FUNC_SMBUS_BYTE_DATA))
+               return -ENODEV;
 
        clientdata = devm_kzalloc(&client->dev, sizeof(*clientdata),
                                GFP_KERNEL);
-       if (!clientdata) {
-               rc = -ENOMEM;
-               goto exit;
-       }
+       if (!clientdata)
+               return -ENOMEM;
 
        clientdata->features = id->driver_data;
        i2c_set_clientdata(client, clientdata);
 
        rtc = devm_rtc_device_register(&client->dev, client->name,
                                        &m41t80_rtc_ops, THIS_MODULE);
-       if (IS_ERR(rtc)) {
-               rc = PTR_ERR(rtc);
-               rtc = NULL;
-               goto exit;
-       }
+       if (IS_ERR(rtc))
+               return PTR_ERR(rtc);
 
        clientdata->rtc = rtc;
 
        /* Make sure HT (Halt Update) bit is cleared */
        rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR);
-       if (rc < 0)
-               goto ht_err;
 
-       if (rc & M41T80_ALHOUR_HT) {
+       if (rc >= 0 && rc & M41T80_ALHOUR_HT) {
                if (clientdata->features & M41T80_FEATURE_HT) {
                        m41t80_get_datetime(client, &tm);
                        dev_info(&client->dev, "HT bit was set!\n");
@@ -673,53 +669,44 @@ static int m41t80_probe(struct i2c_client *client,
                                 tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
                                 tm.tm_min, tm.tm_sec);
                }
-               if (i2c_smbus_write_byte_data(client,
-                                             M41T80_REG_ALARM_HOUR,
-                                             rc & ~M41T80_ALHOUR_HT) < 0)
-                       goto ht_err;
+               rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_HOUR,
+                                             rc & ~M41T80_ALHOUR_HT);
+       }
+
+       if (rc < 0) {
+               dev_err(&client->dev, "Can't clear HT bit\n");
+               return rc;
        }
 
        /* Make sure ST (stop) bit is cleared */
        rc = i2c_smbus_read_byte_data(client, M41T80_REG_SEC);
-       if (rc < 0)
-               goto st_err;
 
-       if (rc & M41T80_SEC_ST) {
-               if (i2c_smbus_write_byte_data(client, M41T80_REG_SEC,
-                                             rc & ~M41T80_SEC_ST) < 0)
-                       goto st_err;
+       if (rc >= 0 && rc & M41T80_SEC_ST)
+               rc = i2c_smbus_write_byte_data(client, M41T80_REG_SEC,
+                                             rc & ~M41T80_SEC_ST);
+       if (rc < 0) {
+               dev_err(&client->dev, "Can't clear ST bit\n");
+               return rc;
        }
 
        rc = m41t80_sysfs_register(&client->dev);
        if (rc)
-               goto exit;
+               return rc;
 
 #ifdef CONFIG_RTC_DRV_M41T80_WDT
        if (clientdata->features & M41T80_FEATURE_HT) {
                save_client = client;
                rc = misc_register(&wdt_dev);
                if (rc)
-                       goto exit;
+                       return rc;
                rc = register_reboot_notifier(&wdt_notifier);
                if (rc) {
                        misc_deregister(&wdt_dev);
-                       goto exit;
+                       return rc;
                }
        }
 #endif
        return 0;
-
-st_err:
-       rc = -EIO;
-       dev_err(&client->dev, "Can't clear ST bit\n");
-       goto exit;
-ht_err:
-       rc = -EIO;
-       dev_err(&client->dev, "Can't clear HT bit\n");
-       goto exit;
-
-exit:
-       return rc;
 }
 
 static int m41t80_remove(struct i2c_client *client)
@@ -750,4 +737,3 @@ module_i2c_driver(m41t80_driver);
 MODULE_AUTHOR("Alexander Bigga <ab@mycable.de>");
 MODULE_DESCRIPTION("ST Microelectronics M41T80 series RTC I2C Client Driver");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
This page took 0.028213 seconds and 5 git commands to generate.