Signed-off-by: Mukesh Kumar Savaliya <quic_msavaliy@xxxxxxxxxxx>
---
drivers/i2c/busses/i2c-qcom-geni.c | 29 ++++++++++++++++++++++-------
1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c
b/drivers/i2c/busses/i2c-qcom-geni.c
index eebb0cbb6ca4..ee2e431601a6 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+// Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights
reserved.
#include <linux/acpi.h>
#include <linux/clk.h>
@@ -99,6 +100,7 @@ struct geni_i2c_dev {
struct dma_chan *rx_c;
bool gpi_mode;
bool abort_done;
+ bool is_shared;
};
struct geni_i2c_desc {
@@ -602,6 +604,7 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev
*gi2c, struct i2c_msg msgs[], i
peripheral.clk_div = itr->clk_div;
peripheral.set_config = 1;
peripheral.multi_msg = false;
+ peripheral.shared_se = gi2c->is_shared;
for (i = 0; i < num; i++) {
gi2c->cur = &msgs[i];
@@ -612,6 +615,8 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev
*gi2c, struct i2c_msg msgs[], i
if (i < num - 1)
peripheral.stretch = 1;
+ peripheral.first_msg = (i == 0);
+ peripheral.last_msg = (i == num - 1);
peripheral.addr = msgs[i].addr;
ret = geni_i2c_gpi(gi2c, &msgs[i], &config,
@@ -631,8 +636,11 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev
*gi2c, struct i2c_msg msgs[], i
dma_async_issue_pending(gi2c->tx_c);
time_left = wait_for_completion_timeout(&gi2c->done,
XFER_TIMEOUT);
- if (!time_left)
+ if (!time_left) {
+ dev_err(gi2c->se.dev, "I2C timeout gpi flags:%d
addr:0x%x\n",
+ gi2c->cur->flags, gi2c->cur->addr);
gi2c->err = -ETIMEDOUT;
+ }
if (gi2c->err) {
ret = gi2c->err;
@@ -800,6 +808,11 @@ static int geni_i2c_probe(struct platform_device
*pdev)
gi2c->clk_freq_out = KHZ(100);
}
+ if (of_property_read_bool(pdev->dev.of_node, "qcom,shared-se")) {
+ gi2c->is_shared = true;
+ dev_dbg(&pdev->dev, "Shared SE Usecase\n");
+ }
+
if (has_acpi_companion(dev))
ACPI_COMPANION_SET(&gi2c->adap.dev, ACPI_COMPANION(dev));
@@ -962,14 +975,16 @@ static int __maybe_unused
geni_i2c_runtime_suspend(struct device *dev)
struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);
disable_irq(gi2c->irq);
- ret = geni_se_resources_off(&gi2c->se);
- if (ret) {
- enable_irq(gi2c->irq);
- return ret;
-
+ if (gi2c->is_shared) {
+ geni_se_clks_off(&gi2c->se);
} else {
- gi2c->suspended = 1;
+ ret = geni_se_resources_off(&gi2c->se);
+ if (ret) {
+ enable_irq(gi2c->irq);
+ return ret;
+ }
}
+ gi2c->suspended = 1;
clk_disable_unprepare(gi2c->core_clk);