Skip to content

Commit d00f474

Browse files
mukesh-savaliyavdadhani
authored andcommitted
FROMLIST: i2c: qcom-geni: Support multi-owner controllers in GPI mode
Some platforms use a QUP-based I2C controller in a configuration where the controller is shared with another system processor. In this setup the operating system must not assume exclusive ownership of the controller or its associated pins. Add support for enabling multi-owner operation when DeviceTree specifies qcom,qup-multi-owner. When enabled, mark the underlying serial engine as shared so the common GENI resource handling avoids selecting the "sleep" pinctrl state, which could disrupt transfers initiated by the other processor. For GPI mode transfers, request lock/unlock TRE sequencing from the GPI driver by setting a single lock_action selector per message, emitting lock before the first message and unlock after the last message (handling the single-message case as well). This serializes access to the shared controller without requiring message-position flags to be passed into the DMA engine layer. Link: https://lore.kernel.org/all/20260331114742.2896317-5-mukesh.savaliya@oss.qualcomm.com/ Signed-off-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
1 parent 309f439 commit d00f474

1 file changed

Lines changed: 26 additions & 1 deletion

File tree

drivers/i2c/busses/i2c-qcom-geni.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,14 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i
829829
if (i < num - 1)
830830
peripheral.stretch = 1;
831831

832+
peripheral.lock_action = GPI_LOCK_NONE;
833+
if (gi2c->se.multi_owner) {
834+
if (i == 0)
835+
peripheral.lock_action = GPI_LOCK_ACQUIRE;
836+
else if (i == num - 1)
837+
peripheral.lock_action = GPI_LOCK_RELEASE;
838+
}
839+
832840
peripheral.addr = msgs[i].addr;
833841
if (i > 0 && (!(msgs[i].flags & I2C_M_RD)))
834842
peripheral.multi_msg = false;
@@ -1028,6 +1036,17 @@ static int geni_i2c_probe(struct platform_device *pdev)
10281036
gi2c->clk_freq_out = I2C_MAX_STANDARD_MODE_FREQ;
10291037
}
10301038

1039+
if (of_property_read_bool(pdev->dev.of_node, "qcom,qup-multi-owner")) {
1040+
/*
1041+
* Multi-owner controller configuration: the controller may be
1042+
* used by another system processor. Mark the SE as shared so
1043+
* common GENI resource handling can avoid pin state changes
1044+
* that would disrupt the other user.
1045+
*/
1046+
gi2c->se.multi_owner = true;
1047+
dev_dbg(&pdev->dev, "I2C controller is shared with another system processor\n");
1048+
}
1049+
10311050
if (has_acpi_companion(dev))
10321051
ACPI_COMPANION_SET(&gi2c->adap.dev, ACPI_COMPANION(dev));
10331052

@@ -1103,7 +1122,9 @@ static int geni_i2c_probe(struct platform_device *pdev)
11031122
}
11041123

11051124
if (fifo_disable) {
1106-
/* FIFO is disabled, so we can only use GPI DMA */
1125+
/* FIFO is disabled, so we can only use GPI DMA.
1126+
* SE can be shared in GSI mode between subsystems, each SS owns a GPII.
1127+
*/
11071128
gi2c->gpi_mode = true;
11081129
ret = setup_gpi_dma(gi2c);
11091130
if (ret)
@@ -1112,6 +1133,10 @@ static int geni_i2c_probe(struct platform_device *pdev)
11121133
dev_dbg(dev, "Using GPI DMA mode for I2C\n");
11131134
} else {
11141135
gi2c->gpi_mode = false;
1136+
1137+
if (gi2c->se.multi_owner)
1138+
dev_err_probe(dev, -EINVAL, "I2C sharing not supported in non GSI mode\n");
1139+
11151140
tx_depth = geni_se_get_tx_fifo_depth(&gi2c->se);
11161141

11171142
/* I2C Master Hub Serial Elements doesn't have the HW_PARAM_0 register */

0 commit comments

Comments
 (0)