i2c: tegra: Factor out error recovery from tegra_i2c_xfer_msg()
authorDmitry Osipenko <digetx@gmail.com>
Tue, 29 Sep 2020 22:19:05 +0000 (01:19 +0300)
committerWolfram Sang <wsa@kernel.org>
Mon, 5 Oct 2020 20:57:43 +0000 (22:57 +0200)
Factor out error recovery code from tegra_i2c_xfer_msg() in order to
make this function easier to read and follow.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Acked-by: Thierry Reding <treding@nvidia.com>
Tested-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
drivers/i2c/busses/i2c-tegra.c

index f8bee67..95d257c 100644 (file)
@@ -1105,6 +1105,32 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
        return -EAGAIN;
 }
 
+static int tegra_i2c_error_recover(struct tegra_i2c_dev *i2c_dev,
+                                  struct i2c_msg *msg)
+{
+       if (i2c_dev->msg_err == I2C_ERR_NONE)
+               return 0;
+
+       tegra_i2c_init(i2c_dev);
+
+       /* start recovery upon arbitration loss in single master mode */
+       if (i2c_dev->msg_err == I2C_ERR_ARBITRATION_LOST) {
+               if (!i2c_dev->is_multimaster_mode)
+                       return i2c_recover_bus(&i2c_dev->adapter);
+
+               return -EAGAIN;
+       }
+
+       if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
+               if (msg->flags & I2C_M_IGNORE_NAK)
+                       return 0;
+
+               return -EREMOTEIO;
+       }
+
+       return -EIO;
+}
+
 static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
                              struct i2c_msg *msg,
                              enum msg_end_type end_state)
@@ -1288,24 +1314,12 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
                i2c_dev->msg_err);
 
        i2c_dev->is_curr_dma_xfer = false;
-       if (i2c_dev->msg_err == I2C_ERR_NONE)
-               return 0;
 
-       tegra_i2c_init(i2c_dev);
-       /* start recovery upon arbitration loss in single master mode */
-       if (i2c_dev->msg_err == I2C_ERR_ARBITRATION_LOST) {
-               if (!i2c_dev->is_multimaster_mode)
-                       return i2c_recover_bus(&i2c_dev->adapter);
-               return -EAGAIN;
-       }
-
-       if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
-               if (msg->flags & I2C_M_IGNORE_NAK)
-                       return 0;
-               return -EREMOTEIO;
-       }
+       err = tegra_i2c_error_recover(i2c_dev, msg);
+       if (err)
+               return err;
 
-       return -EIO;
+       return 0;
 }
 
 static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],