]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
i2c: cadence: Split cdns_i2c_master_xfer for Atomic Mode
authorManikanta Guntupalli <manikanta.guntupalli@amd.com>
Wed, 11 Sep 2024 10:38:51 +0000 (16:08 +0530)
committerAndi Shyti <andi.shyti@kernel.org>
Wed, 13 Nov 2024 22:29:45 +0000 (23:29 +0100)
The cdns_i2c_master_xfer function has been refactored to separate
the common code. This change facilitates better support for atomic
mode operations by isolating the shared logic.

Signed-off-by: Manikanta Guntupalli <manikanta.guntupalli@amd.com>
Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
Acked-by: Michal Simek <michal.simek@amd.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
drivers/i2c/busses/i2c-cadence.c

index d3f6ca2cb4d7c69e2c89a7e0d27ab7089b6a0e65..e689448d229f1b096f3428a3ecdc84dfb303ce68 100644 (file)
@@ -866,46 +866,14 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg,
        return 0;
 }
 
-/**
- * cdns_i2c_master_xfer - The main i2c transfer function
- * @adap:      pointer to the i2c adapter driver instance
- * @msgs:      pointer to the i2c message structure
- * @num:       the number of messages to transfer
- *
- * Initiates the send/recv activity based on the transfer message received.
- *
- * Return: number of msgs processed on success, negative error otherwise
- */
-static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
-                               int num)
+static int cdns_i2c_master_common_xfer(struct i2c_adapter *adap,
+                                      struct i2c_msg *msgs,
+                                      int num)
 {
        int ret, count;
        u32 reg;
        struct cdns_i2c *id = adap->algo_data;
        bool hold_quirk;
-#if IS_ENABLED(CONFIG_I2C_SLAVE)
-       bool change_role = false;
-#endif
-
-       ret = pm_runtime_resume_and_get(id->dev);
-       if (ret < 0)
-               return ret;
-
-#if IS_ENABLED(CONFIG_I2C_SLAVE)
-       /* Check i2c operating mode and switch if possible */
-       if (id->dev_mode == CDNS_I2C_MODE_SLAVE) {
-               if (id->slave_state != CDNS_I2C_SLAVE_STATE_IDLE) {
-                       ret = -EAGAIN;
-                       goto out;
-               }
-
-               /* Set mode to master */
-               cdns_i2c_set_mode(CDNS_I2C_MODE_MASTER, id);
-
-               /* Mark flag to change role once xfer is completed */
-               change_role = true;
-       }
-#endif
 
        /* Check if the bus is free */
 
@@ -917,7 +885,7 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
                ret = -EAGAIN;
                if (id->adap.bus_recovery_info)
                        i2c_recover_bus(adap);
-               goto out;
+               return ret;
        }
 
        hold_quirk = !!(id->quirks & CDNS_I2C_BROKEN_HOLD_BIT);
@@ -937,8 +905,7 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
                        if (msgs[count].flags & I2C_M_RD) {
                                dev_warn(adap->dev.parent,
                                         "Can't do repeated start after a receive message\n");
-                               ret = -EOPNOTSUPP;
-                               goto out;
+                               return -EOPNOTSUPP;
                        }
                }
                id->bus_hold_flag = 1;
@@ -956,26 +923,65 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
 
                ret = cdns_i2c_process_msg(id, msgs, adap);
                if (ret)
-                       goto out;
+                       return ret;
 
                /* Report the other error interrupts to application */
                if (id->err_status) {
                        cdns_i2c_master_reset(adap);
 
-                       if (id->err_status & CDNS_I2C_IXR_NACK) {
-                               ret = -ENXIO;
-                               goto out;
-                       }
-                       ret = -EIO;
-                       goto out;
+                       if (id->err_status & CDNS_I2C_IXR_NACK)
+                               return -ENXIO;
+
+                       return -EIO;
                }
        }
+       return 0;
+}
 
-       ret = num;
+/**
+ * cdns_i2c_master_xfer - The main i2c transfer function
+ * @adap:      pointer to the i2c adapter driver instance
+ * @msgs:      pointer to the i2c message structure
+ * @num:       the number of messages to transfer
+ *
+ * Initiates the send/recv activity based on the transfer message received.
+ *
+ * Return: number of msgs processed on success, negative error otherwise
+ */
+static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+                               int num)
+{
+       int ret;
+       struct cdns_i2c *id = adap->algo_data;
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+       bool change_role = false;
+#endif
 
-out:
+       ret = pm_runtime_resume_and_get(id->dev);
+       if (ret < 0)
+               return ret;
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+       /* Check i2c operating mode and switch if possible */
+       if (id->dev_mode == CDNS_I2C_MODE_SLAVE) {
+               if (id->slave_state != CDNS_I2C_SLAVE_STATE_IDLE) {
+                       ret = -EAGAIN;
+                       goto out;
+               }
+
+               /* Set mode to master */
+               cdns_i2c_set_mode(CDNS_I2C_MODE_MASTER, id);
+
+               /* Mark flag to change role once xfer is completed */
+               change_role = true;
+       }
+#endif
 
+       ret = cdns_i2c_master_common_xfer(adap, msgs, num);
+       if (!ret)
+               ret = num;
 #if IS_ENABLED(CONFIG_I2C_SLAVE)
+out:
        /* Switch i2c mode to slave */
        if (change_role)
                cdns_i2c_set_mode(CDNS_I2C_MODE_SLAVE, id);