Re: [PATCH v4] i2c: cadence: Add shutdown handler
From: Pandey, Radhey Shyam <hidden>
Date: 2026-06-09 05:13:20
Also in:
linux-i2c, lkml
During system reboot or kexec, in-flight I2C transfers can cause spurious interrupts or leave the bus in an undefined state. Add a shutdown handler that marks the adapter suspended and resets the controller, ensuring a clean handoff. Signed-off-by: Ajay Neeli <ajay.neeli@amd.com>
Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> Thanks!
quoted hunk ↗ jump to hunk
--- Link: https://lore.kernel.org/linux-i2c/20250730122907.18909-1-ajay.neeli@amd.com/ (local) Changes v3->v4: - Replaced disable_irq() with cdns_i2c_master_reset() to avoid potential deadlocks during shutdown - Added pm_runtime_status_suspended() check to skip register access when clocks are disabled Changes v2->v3: Corrected a typo that caused a build error in v2 Changes in v1->v2: Disable interrupts --- drivers/i2c/busses/i2c-cadence.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index 0fb728ade92e..da8770182a18 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c@@ -1635,6 +1635,25 @@ static void cdns_i2c_remove(struct platform_device *pdev) reset_control_assert(id->reset); } +/** + * cdns_i2c_shutdown - Prepare I2C controller for system shutdown + * @pdev: Handle to the platform device structure + * + * Mark the adapter as suspended and reset the controller to ensure a clean + * handoff during system reboot or kexec. + */ +static void cdns_i2c_shutdown(struct platform_device *pdev) +{ + struct cdns_i2c *id = platform_get_drvdata(pdev); + + /* Mark the adapter as suspended to prevent further I2C transfers */ + i2c_mark_adapter_suspended(&id->adap); + + /* Reset the controller state if active - clocks are disabled when suspended */ + if (!pm_runtime_status_suspended(&pdev->dev)) + cdns_i2c_master_reset(&id->adap); +} + static struct platform_driver cdns_i2c_drv = { .driver = { .name = DRIVER_NAME,@@ -1643,6 +1662,7 @@ static struct platform_driver cdns_i2c_drv = { }, .probe = cdns_i2c_probe, .remove = cdns_i2c_remove, + .shutdown = cdns_i2c_shutdown, }; module_platform_driver(cdns_i2c_drv);