FAILED: patch "[PATCH] i2c: i2c-qcom-geni: Add shutdown callback for i2c" failed to apply to 4.19-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 4.19-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From e0371298ddc51761be257698554ea507ac8bf831 Mon Sep 17 00:00:00 2001
From: Roja Rani Yarubandi <[email protected]>
Date: Fri, 8 Jan 2021 20:35:45 +0530
Subject: [PATCH] i2c: i2c-qcom-geni: Add shutdown callback for i2c
If the hardware is still accessing memory after SMMU translation is disabled (as part of smmu shutdown callback), then the IOVAs (I/O virtual address) which it was using will go on the bus as the physical addresses which will result in unknown crashes like NoC/interconnect errors.
So, implement shutdown callback to i2c driver to stop on-going transfer and unmap DMA mappings during system "reboot" or "shutdown".
drivers/i2c/busses/i2c-qcom-geni.c +34 -0
@@ -375,6 +375,32 @@ static void geni_i2c_tx_msg_cleanup(struct geni_i2c_dev *gi2c, } } +static void geni_i2c_stop_xfer (struct geni_i2c_dev *gi2c) +{ +int ret; +u32 geni_status; +struct i2c_msg *cur; + +/* Resume device, as runtime suspend can happen anytime during transfer */ + ret =pm_runtime_get_sync (gi2c->se.dev); +if (ret <0 ) { +dev_err (gi2c->se.dev,"Failed to resume device: %d\n" , ret); +return ; + } + + geni_status =readl_relaxed (gi2c->se.base +SE_GENI_STATUS ); +if (geni_status &M_GENI_CMD_ACTIVE ) { + cur = gi2c->cur; +geni_i2c_abort_xfer (gi2c); +if (cur->flags &I2C_M_RD ) +geni_i2c_rx_msg_cleanup (gi2c, cur); +else +geni_i2c_tx_msg_cleanup (gi2c, cur); + } + +pm_runtime_put_sync_suspend (gi2c->se.dev); +} +static int geni_i2c_rx_one_msg (struct geni_i2c_dev *gi2c,struct i2c_msg *msg,u32 m_param) {
@@ -650,6 +676,13 @@ static int geni_i2c_remove(struct platform_device *pdev)return 0 ; } +static void geni_i2c_shutdown (struct platform_device *pdev) +{ +struct geni_i2c_dev *gi2c =platform_get_drvdata (pdev); + +geni_i2c_stop_xfer (gi2c); +} +static int __maybe_unused geni_i2c_runtime_suspend (struct device *dev) {int ret;
@@ -714,6 +747,7 @@ MODULE_DEVICE_TABLE(of, geni_i2c_dt_match);static struct platform_driver geni_i2c_driver = { .probe = geni_i2c_probe, .remove = geni_i2c_remove, + .shutdown = geni_i2c_shutdown, .driver = { .name ="geni_i2c" , .pm = &geni_i2c_pm_ops,