mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/2] i2c: qcom-geni: Quiesce hardware on shutdown and panic
@ 2026-08-18  5:01 Praveen Talari
  2026-08-18  5:01 ` [PATCH 1/2] i2c: qcom-geni: Add shutdown callback to quiesce hardware on reboot Praveen Talari
  2026-08-18  5:01 ` [PATCH 2/2] i2c: qcom-geni: Add panic notifier to prevent transfers during panic Praveen Talari
  0 siblings, 2 replies; 5+ messages in thread
From: Praveen Talari @ 2026-08-18  5:01 UTC (permalink / raw)
  To: konrad.dybcio, Mukesh Kumar Savaliya, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, linux-i2c, linux-arm-msm, linux-kernel,
	Praveen Talari

This series hardens the GENI I2C driver against two related VM-teardown
scenarios where an in-flight I2C DMA transfer can trigger SMMU context
faults after the VM's memory context has already been invalidated.

Patch 1 adds a shutdown callback that cancels/aborts any in-progress
GENI or GPI DMA transfer and resets the TX/RX FSMs before a normal
reboot proceeds, so the hardware is left idle rather than mid-transfer.

Patch 2 adds a panic notifier that marks the I2C adapter suspended and
performs the same cancel/abort/DMA-reset cleanup as the shutdown path,
using atomic-context-safe DMA termination since panic notifiers cannot
sleep.

Together these prevent both hardware state corruption on reboot and
SMMU faults (which can affect other VMs sharing the same SMMU instance)
during VM shutdown/crash.

Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
Praveen Talari (2):
      i2c: qcom-geni: Add shutdown callback to quiesce hardware on reboot
      i2c: qcom-geni: Add panic notifier to prevent transfers during panic

 drivers/i2c/busses/i2c-qcom-geni.c | 77 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 74 insertions(+), 3 deletions(-)
---
base-commit: 4477a78374a57c3809b172ad30cceabda48c47c6
change-id: 20260817-add-shutdown-and-panic-notifier-for-i2c-6723fc0f557e

Best regards,
--  
Praveen Talari <praveen.talari@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] i2c: qcom-geni: Add shutdown callback to quiesce hardware on reboot
  2026-08-18  5:01 [PATCH 0/2] i2c: qcom-geni: Quiesce hardware on shutdown and panic Praveen Talari
@ 2026-08-18  5:01 ` Praveen Talari
  2026-10-26 18:45   ` Mukesh Savaliya
  2026-08-18  5:01 ` [PATCH 2/2] i2c: qcom-geni: Add panic notifier to prevent transfers during panic Praveen Talari
  1 sibling, 1 reply; 5+ messages in thread
From: Praveen Talari @ 2026-08-18  5:01 UTC (permalink / raw)
  To: konrad.dybcio, Mukesh Kumar Savaliya, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, linux-i2c, linux-arm-msm, linux-kernel,
	Praveen Talari

During system reboot, an active I2C transfer can leave the GENI Serial
Engine in an indeterminate state. On VM-based platforms, if a DMA
transfer is in progress when the VM is shut down, the SMMU can raise
context faults as the DMA engine continues to access IOVAs that have
already been invalidated during VM teardown.

Add a geni_i2c_quiesce() helper that cancels/aborts any in-progress
GENI or GPI DMA transfer and resets the TX/RX FSMs, and call it from a
new shutdown callback before the system resets. This prevents both
hardware state corruption on reboot and SMMU faults during VM
shutdown. dmaengine_terminate_async() is used unconditionally so the
helper is also safe to call from atomic contexts such as a panic
notifier.

Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
 drivers/i2c/busses/i2c-qcom-geni.c | 51 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index 658636c1ee0e..10c6a4b0b825 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -13,6 +13,7 @@
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -1034,6 +1035,53 @@ static int setup_gpi_dma(struct geni_i2c_dev *gi2c)
 	return ret;
 }
 
+static void geni_i2c_quiesce(struct geni_i2c_dev *gi2c)
+{
+	void __iomem *base = gi2c->se.base;
+	u32 val;
+
+	/* Make client i2c transfers start failing */
+	i2c_mark_adapter_suspended(&gi2c->adap);
+
+	if (!pm_runtime_active(gi2c->se.dev))
+		return;
+
+	if (gi2c->gpi_mode) {
+		dmaengine_terminate_async(gi2c->tx_c);
+		dmaengine_terminate_async(gi2c->rx_c);
+		return;
+	}
+
+	if (!(readl_relaxed(base + SE_GENI_STATUS) & M_GENI_CMD_ACTIVE))
+		return;
+
+	geni_se_cancel_m_cmd(&gi2c->se);
+
+	if (!readl_poll_timeout_atomic(base + SE_GENI_M_IRQ_STATUS, val,
+				       val & M_CMD_CANCEL_EN, 10, 200000)) {
+		writel_relaxed(M_CMD_CANCEL_EN, base + SE_GENI_M_IRQ_CLEAR);
+		return;
+	}
+
+	geni_se_abort_m_cmd(&gi2c->se);
+
+	if (!readl_poll_timeout_atomic(base + SE_GENI_M_IRQ_STATUS, val,
+				       val & M_CMD_ABORT_EN, 10, 200000))
+		writel_relaxed(M_CMD_ABORT_EN, base + SE_GENI_M_IRQ_CLEAR);
+
+	if (readl_relaxed(base + SE_GENI_DMA_MODE_EN)) {
+		writel_relaxed(1, base + SE_DMA_TX_FSM_RST);
+		readl_poll_timeout_atomic(base + SE_DMA_TX_IRQ_STAT, val,
+					  val & TX_RESET_DONE, 10, 50000);
+		writel_relaxed(val, base + SE_DMA_TX_IRQ_CLR);
+
+		writel_relaxed(1, base + SE_DMA_RX_FSM_RST);
+		readl_poll_timeout_atomic(base + SE_DMA_RX_IRQ_STAT, val,
+					  val & RX_RESET_DONE, 10, 50000);
+		writel_relaxed(val, base + SE_DMA_RX_IRQ_CLR);
+	}
+}
+
 static int geni_i2c_init(struct geni_i2c_dev *gi2c)
 {
 	u32 proto, tx_depth;
@@ -1209,8 +1257,7 @@ static void geni_i2c_shutdown(struct platform_device *pdev)
 {
 	struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev);
 
-	/* Make client i2c transfers start failing */
-	i2c_mark_adapter_suspended(&gi2c->adap);
+	geni_i2c_quiesce(gi2c);
 }
 
 static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/2] i2c: qcom-geni: Add panic notifier to prevent transfers during panic
  2026-08-18  5:01 [PATCH 0/2] i2c: qcom-geni: Quiesce hardware on shutdown and panic Praveen Talari
  2026-08-18  5:01 ` [PATCH 1/2] i2c: qcom-geni: Add shutdown callback to quiesce hardware on reboot Praveen Talari
@ 2026-08-18  5:01 ` Praveen Talari
  2026-10-26 18:55   ` Mukesh Savaliya
  1 sibling, 1 reply; 5+ messages in thread
From: Praveen Talari @ 2026-08-18  5:01 UTC (permalink / raw)
  To: konrad.dybcio, Mukesh Kumar Savaliya, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, linux-i2c, linux-arm-msm, linux-kernel,
	Praveen Talari

When a VM crashes with an active I2C DMA transfer in progress, the
SMMU raises context faults as the DMA engine continues to access IOVAs
that are invalidated when the VM's memory context is torn down. These
faults can affect other VMs sharing the same SMMU instance.

Register a panic notifier that calls the same geni_i2c_quiesce()
helper used by the shutdown path. This marks the I2C adapter
suspended, preventing new transfers from being initiated, and
cancels/aborts any transfer already in flight, limiting the window
during which the DMA engine can access IOVAs that are about to be
invalidated.

Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
 drivers/i2c/busses/i2c-qcom-geni.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index 10c6a4b0b825..2f8237c232e1 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -16,6 +16,7 @@
 #include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/panic_notifier.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/soc/qcom/geni-se.h>
@@ -139,6 +140,7 @@ struct geni_i2c_dev {
 	u32 num_msgs;
 	struct geni_i2c_gpi_multi_desc_xfer i2c_multi_desc_config;
 	const struct geni_i2c_desc *dev_data;
+	struct notifier_block panic_nb;
 };
 
 struct geni_i2c_err_log {
@@ -1082,6 +1084,19 @@ static void geni_i2c_quiesce(struct geni_i2c_dev *gi2c)
 	}
 }
 
+static int geni_i2c_panic_notifier(struct notifier_block *nb,
+				   unsigned long action, void *data)
+{
+	struct geni_i2c_dev *gi2c = container_of(nb, struct geni_i2c_dev, panic_nb);
+
+	/* Make client i2c transfers start failing */
+	i2c_mark_adapter_suspended(&gi2c->adap);
+
+	geni_i2c_quiesce(gi2c);
+
+	return NOTIFY_OK;
+}
+
 static int geni_i2c_init(struct geni_i2c_dev *gi2c)
 {
 	u32 proto, tx_depth;
@@ -1236,9 +1251,16 @@ static int geni_i2c_probe(struct platform_device *pdev)
 	if (ret < 0)
 		return ret;
 
-	ret = i2c_add_adapter(&gi2c->adap);
+	gi2c->panic_nb.notifier_call = geni_i2c_panic_notifier;
+	ret = atomic_notifier_chain_register(&panic_notifier_list, &gi2c->panic_nb);
 	if (ret)
+		return dev_err_probe(dev, ret, "Error registering panic notifier\n");
+
+	ret = i2c_add_adapter(&gi2c->adap);
+	if (ret) {
+		atomic_notifier_chain_unregister(&panic_notifier_list, &gi2c->panic_nb);
 		return dev_err_probe(dev, ret, "Error adding i2c adapter\n");
+	}
 
 	dev_dbg(dev, "Geni-I2C adaptor successfully added\n");
 
@@ -1249,6 +1271,8 @@ static void geni_i2c_remove(struct platform_device *pdev)
 {
 	struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev);
 
+	atomic_notifier_chain_unregister(&panic_notifier_list, &gi2c->panic_nb);
+
 	i2c_del_adapter(&gi2c->adap);
 	release_gpi_dma(gi2c);
 }

-- 
2.34.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] i2c: qcom-geni: Add shutdown callback to quiesce hardware on reboot
  2026-08-18  5:01 ` [PATCH 1/2] i2c: qcom-geni: Add shutdown callback to quiesce hardware on reboot Praveen Talari
@ 2026-10-26 18:45   ` Mukesh Savaliya
  0 siblings, 0 replies; 5+ messages in thread
From: Mukesh Savaliya @ 2026-10-26 18:45 UTC (permalink / raw)
  To: Praveen Talari, konrad.dybcio, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, linux-i2c, linux-arm-msm, linux-kernel



On 8/18/2026 10:31 AM, Praveen Talari wrote:
[...]> ---
>   drivers/i2c/busses/i2c-qcom-geni.c | 51 ++++++++++++++++++++++++++++++++++++--
>   1 file changed, 49 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
> index 658636c1ee0e..10c6a4b0b825 100644
> --- a/drivers/i2c/busses/i2c-qcom-geni.c
> +++ b/drivers/i2c/busses/i2c-qcom-geni.c

[...]

> +	geni_se_abort_m_cmd(&gi2c->se);
> +
> +	if (!readl_poll_timeout_atomic(base + SE_GENI_M_IRQ_STATUS, val,
> +				       val & M_CMD_ABORT_EN, 10, 200000))
> +		writel_relaxed(M_CMD_ABORT_EN, base + SE_GENI_M_IRQ_CLEAR);
> +
> +	if (readl_relaxed(base + SE_GENI_DMA_MODE_EN)) {
> +		writel_relaxed(1, base + SE_DMA_TX_FSM_RST);
> +		readl_poll_timeout_atomic(base + SE_DMA_TX_IRQ_STAT, val,
> +					  val & TX_RESET_DONE, 10, 50000);
Any error log to print if times out ?

if (ret)
	dev_err(gi2c->se.dev, "Timeout resetting TX DMA FSM\n");
else
	writel_relaxed(TX_RESET_DONE, base + SE_DMA_TX_IRQ_CLR);

> +		writel_relaxed(val, base + SE_DMA_TX_IRQ_CLR);
> +
> +		writel_relaxed(1, base + SE_DMA_RX_FSM_RST);
> +		readl_poll_timeout_atomic(base + SE_DMA_RX_IRQ_STAT, val,
> +					  val & RX_RESET_DONE, 10, 50000);
Any error log to print if times out ?

> +		writel_relaxed(val, base + SE_DMA_RX_IRQ_CLR);
> +	}
> +}
> +
>   static int geni_i2c_init(struct geni_i2c_dev *gi2c)
>   {
>   	u32 proto, tx_depth;
> @@ -1209,8 +1257,7 @@ static void geni_i2c_shutdown(struct platform_device *pdev)
>   {
>   	struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev);
>   
> -	/* Make client i2c transfers start failing */
> -	i2c_mark_adapter_suspended(&gi2c->adap);
> +	geni_i2c_quiesce(gi2c);
>   }
>   
>   static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev)
> 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] i2c: qcom-geni: Add panic notifier to prevent transfers during panic
  2026-08-18  5:01 ` [PATCH 2/2] i2c: qcom-geni: Add panic notifier to prevent transfers during panic Praveen Talari
@ 2026-10-26 18:55   ` Mukesh Savaliya
  0 siblings, 0 replies; 5+ messages in thread
From: Mukesh Savaliya @ 2026-10-26 18:55 UTC (permalink / raw)
  To: Praveen Talari, konrad.dybcio, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, linux-i2c, linux-arm-msm, linux-kernel



On 8/18/2026 10:31 AM, Praveen Talari wrote:

> ---
>   drivers/i2c/busses/i2c-qcom-geni.c | 26 +++++++++++++++++++++++++-
>   1 file changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
> index 10c6a4b0b825..2f8237c232e1 100644
> --- a/drivers/i2c/busses/i2c-qcom-geni.c
> +++ b/drivers/i2c/busses/i2c-qcom-geni.c

[...]
>   
> +static int geni_i2c_panic_notifier(struct notifier_block *nb,
> +				   unsigned long action, void *data)
> +{
> +	struct geni_i2c_dev *gi2c = container_of(nb, struct geni_i2c_dev, panic_nb);
> +
> +	/* Make client i2c transfers start failing */
> +	i2c_mark_adapter_suspended(&gi2c->adap);
> +
Duplicate/Double  call - i2c_mark_adapter_suspended() already called 
within geni_i2c_quiesce().

> +	geni_i2c_quiesce(gi2c);
> +
> +	return NOTIFY_OK;
> +}
> +
[...]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-10-26 18:55 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-18  5:01 [PATCH 0/2] i2c: qcom-geni: Quiesce hardware on shutdown and panic Praveen Talari
2026-08-18  5:01 ` [PATCH 1/2] i2c: qcom-geni: Add shutdown callback to quiesce hardware on reboot Praveen Talari
2026-10-26 18:45   ` Mukesh Savaliya
2026-08-18  5:01 ` [PATCH 2/2] i2c: qcom-geni: Add panic notifier to prevent transfers during panic Praveen Talari
2026-10-26 18:55   ` Mukesh Savaliya

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®