#      define RS5C_CTRL1_CT4           (4 << 0)        /* 1 Hz level irq */
 #define RS5C_REG_CTRL2         15
 #      define RS5C372_CTRL2_24         (1 << 5)
-#      define R2x2x_CTRL2_XSTP         (1 << 5)        /* only if R2x2x */
 #      define RS5C_CTRL2_XSTP          (1 << 4)        /* only if !R2x2x */
+#      define R2x2x_CTRL2_VDET         (1 << 6)        /* only if  R2x2x */
+#      define R2x2x_CTRL2_XSTP         (1 << 5)        /* only if  R2x2x */
+#      define R2x2x_CTRL2_PON          (1 << 4)        /* only if  R2x2x */
 #      define RS5C_CTRL2_CTFG          (1 << 2)
 #      define RS5C_CTRL2_AAFG          (1 << 1)        /* or WAFG */
 #      define RS5C_CTRL2_BAFG          (1 << 0)        /* or DAFG */
        struct i2c_client *client = to_i2c_client(dev);
        struct rs5c372  *rs5c = i2c_get_clientdata(client);
        int             status = rs5c_get_regs(rs5c);
+       unsigned char ctrl2 = rs5c->regs[RS5C_REG_CTRL2];
 
        if (status < 0)
                return status;
 
+       switch (rs5c->type) {
+       case rtc_r2025sd:
+       case rtc_r2221tl:
+               if ((rs5c->type == rtc_r2025sd && !(ctrl2 & R2x2x_CTRL2_XSTP)) ||
+                   (rs5c->type == rtc_r2221tl &&  (ctrl2 & R2x2x_CTRL2_XSTP))) {
+                       dev_warn(&client->dev, "rtc oscillator interruption detected. Please reset the rtc clock.\n");
+                       return -EINVAL;
+               }
+               break;
+       default:
+               if (ctrl2 & RS5C_CTRL2_XSTP) {
+                       dev_warn(&client->dev, "rtc oscillator interruption detected. Please reset the rtc clock.\n");
+                       return -EINVAL;
+               }
+       }
+
        tm->tm_sec = bcd2bin(rs5c->regs[RS5C372_REG_SECS] & 0x7f);
        tm->tm_min = bcd2bin(rs5c->regs[RS5C372_REG_MINS] & 0x7f);
        tm->tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C372_REG_HOURS]);
        struct i2c_client *client = to_i2c_client(dev);
        struct rs5c372  *rs5c = i2c_get_clientdata(client);
        unsigned char   buf[7];
+       unsigned char   ctrl2;
        int             addr;
 
        dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d "
        buf[6] = bin2bcd(tm->tm_year - 100);
 
        if (i2c_smbus_write_i2c_block_data(client, addr, sizeof(buf), buf) < 0) {
-               dev_err(&client->dev, "%s: write error\n", __func__);
+               dev_dbg(&client->dev, "%s: write error in line %i\n",
+                       __func__, __LINE__);
+               return -EIO;
+       }
+
+       addr = RS5C_ADDR(RS5C_REG_CTRL2);
+       ctrl2 = i2c_smbus_read_byte_data(client, addr);
+
+       /* clear rtc warning bits */
+       switch (rs5c->type) {
+       case rtc_r2025sd:
+       case rtc_r2221tl:
+               ctrl2 &= ~(R2x2x_CTRL2_VDET | R2x2x_CTRL2_PON);
+               if (rs5c->type == rtc_r2025sd)
+                       ctrl2 |= R2x2x_CTRL2_XSTP;
+               else
+                       ctrl2 &= ~R2x2x_CTRL2_XSTP;
+               break;
+       default:
+               ctrl2 &= ~RS5C_CTRL2_XSTP;
+               break;
+       }
+
+       if (i2c_smbus_write_byte_data(client, addr, ctrl2) < 0) {
+               dev_dbg(&client->dev, "%s: write error in line %i\n",
+                       __func__, __LINE__);
                return -EIO;
        }
 
        buf[0] = rs5c372->regs[RS5C_REG_CTRL1];
        buf[1] = rs5c372->regs[RS5C_REG_CTRL2];
 
-       /* handle xstp bit */
        switch (rs5c372->type) {
        case rtc_r2025sd:
                if (buf[1] & R2x2x_CTRL2_XSTP)
                        return ret;
-               rs5c372->regs[RS5C_REG_CTRL2] |= R2x2x_CTRL2_XSTP;
                break;
        case rtc_r2221tl:
                if (!(buf[1] & R2x2x_CTRL2_XSTP))
                        return ret;
-               rs5c372->regs[RS5C_REG_CTRL2] &= ~R2x2x_CTRL2_XSTP;
                break;
-
        default:
                if (!(buf[1] & RS5C_CTRL2_XSTP))
                        return ret;
-               rs5c372->regs[RS5C_REG_CTRL2] &= ~RS5C_CTRL2_XSTP;
                break;
        }