summaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
authorBenoît Monin <benoit.monin@bootlin.com>2025-11-26 11:46:27 +0100
committerAndi Shyti <andi.shyti@kernel.org>2025-12-17 00:37:24 +0100
commit6a28174326289834c6767bdeb1ba348aa9831e91 (patch)
tree4ddfdd249e7a51eaa2c30ebeb0a89545209ad6ec /drivers/i2c
parentea032b451134e5cc79ed1affc9a237ce5bdda9ed (diff)
i2c: designware: Add dedicated algorithm for AMD NAVI
Apart from runtime PM, there is nothing in common between i2c_dw_xfer() and amd_i2c_dw_xfer_quirk(), so give AMD NAVI controller its own algorithm instead of calling the quirk from i2c_dw_xfer(). Add runtime PM handling to amd_i2c_dw_xfer_quirk() and a dedicated i2c_algorithm for AMD NAVI controllers. The adapter algorithm is set during probe based on the device model. This way we avoid checking for the device model at the start of every transfer. Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Benoît Monin <benoit.monin@bootlin.com> Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Andi Shyti <andi.shyti@kernel.org> Link: https://lore.kernel.org/r/20251126-i2c-dw-v4-4-b0654598e7c5@bootlin.com
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-designware-master.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c
index 4493568e2fa3..f247cf323207 100644
--- a/drivers/i2c/busses/i2c-designware-master.c
+++ b/drivers/i2c/busses/i2c-designware-master.c
@@ -361,6 +361,10 @@ static int amd_i2c_dw_xfer_quirk(struct i2c_adapter *adap, struct i2c_msg *msgs,
u8 *tx_buf;
unsigned int val;
+ ACQUIRE(pm_runtime_active_auto_try, pm)(dev->dev);
+ if (ACQUIRE_ERR(pm_runtime_active_auto_try, &pm))
+ return -ENXIO;
+
/*
* In order to enable the interrupt for UCSI i.e. AMD NAVI GPU card,
* it is mandatory to set the right value in specific register
@@ -820,14 +824,6 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
pm_runtime_get_sync(dev->dev);
- switch (dev->flags & MODEL_MASK) {
- case MODEL_AMD_NAVI_GPU:
- ret = amd_i2c_dw_xfer_quirk(adap, msgs, num);
- goto done_nolock;
- default:
- break;
- }
-
reinit_completion(&dev->cmd_complete);
dev->msgs = msgs;
dev->msgs_num = num;
@@ -917,6 +913,11 @@ static const struct i2c_algorithm i2c_dw_algo = {
.functionality = i2c_dw_func,
};
+static const struct i2c_algorithm amd_i2c_dw_algo = {
+ .xfer = amd_i2c_dw_xfer_quirk,
+ .functionality = i2c_dw_func,
+};
+
static const struct i2c_adapter_quirks i2c_dw_quirks = {
.flags = I2C_AQ_NO_ZERO_LEN,
};
@@ -1052,7 +1053,10 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev)
scnprintf(adap->name, sizeof(adap->name),
"Synopsys DesignWare I2C adapter");
adap->retries = 3;
- adap->algo = &i2c_dw_algo;
+ if ((dev->flags & MODEL_MASK) == MODEL_AMD_NAVI_GPU)
+ adap->algo = &amd_i2c_dw_algo;
+ else
+ adap->algo = &i2c_dw_algo;
adap->quirks = &i2c_dw_quirks;
adap->dev.parent = dev->dev;
i2c_set_adapdata(adap, dev);