From: Biju Das biju.das.jz@bp.renesas.com
[ Upstream commit ad4728740bd68d74365a43acc25a65339a9b2173 ]
On RZ/G3E using PSCI, s2ram powers down the SoC. After resume, reinitialize the hardware for SPI operations.
Signed-off-by: Biju Das biju.das.jz@bp.renesas.com Link: https://patch.msgid.link/20250921112649.104516-3-biju.das.jz@bp.renesas.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES
- What changed: The resume callback now reinitializes the underlying RPC-IF hardware by calling `rpcif_hw_init(dev, false)` before resuming the SPI controller queue. See drivers/spi/spi-rpc-if.c:210. The rest of the resume path remains unchanged and returns `spi_controller_resume(ctlr)` (drivers/spi/spi-rpc-if.c:212). The patch is a small, contained 2-line addition in a single driver file.
- Why it’s needed: On RZ/G3E systems using PSCI, s2ram powers the SoC off, so the RPC-IF/xSPI controller loses register state. The SPI core’s `spi_controller_resume()` does not reconfigure hardware (drivers/spi/spi.c:3519), it only restarts the message queue. Without reinitialization, resumed SPI operations can fail or misbehave. The added `rpcif_hw_init()` reprograms controller registers and ensures the hardware is ready post-resume.
- Correctness of the reinit: `rpcif_hw_init()` is the standard hardware bring-up routine used in probe; it resumes runtime PM, reconfigures the controller for the appropriate mode, and then drops the PM reference. See drivers/memory/renesas-rpc-if.c:315. It’s already invoked during probe for the SPI path (drivers/spi/spi-rpc-if.c:173), so reusing it on resume is appropriate and consistent.
- Scope and risk: The change is isolated to RPC-IF SPI driver resume. It does not alter normal operation, only system-suspend resume behavior. The call is idempotent and guarded by runtime PM (pm_runtime_resume_and_get/put inside rpcif_hw_init), minimizing risk. It doesn’t introduce features or architectural changes.
- Impacted platforms: Although the commit message highlights RZ/G3E (xSPI), the reinit is generally safe for other RPC-IF variants too and can only improve robustness after system suspend.
- Stable-tree suitability: - Fixes a real user-visible bug (SPI transactions can fail after S2RAM on RZ/G3E). - Minimal change (two added lines), fully contained in the driver. - Low regression risk and no API or architectural churn. - Touches a specific subsystem driver (SPI/Renesas RPC-IF), not core kernel paths.
- Backport notes (API/context): - `rpcif_hw_init()` currently takes a `struct device *` (drivers/memory/renesas-rpc-if.c:315; include/memory/renesas-rpc- if.h:75). On older stable trees that predate commit a198fcd1d53cb (which changed RPC-IF APIs to pass a device instead of an internal handle), the signature may differ. In such trees, adapt the call accordingly (e.g., pass `rpc->dev` or the older handle type). - Ensure the device passed to `rpcif_hw_init()` is the one holding `rpcif_priv` (in probe we pass `rpc->dev`, which is the parent RPC- IF device). If the stable branch still uses the older arrangement, the backport should call `rpcif_hw_init(rpc->dev, false)` after obtaining `struct rpcif *rpc = spi_controller_get_devdata(ctlr)` in resume. - Macro context (SIMPLE_DEV_PM_OPS vs DEFINE_SIMPLE_DEV_PM_OPS) may differ between branches; this is mechanical and does not affect the substance of the fix.
In summary, this is a classic, low-risk, correctness fix for resume on RZ/G3E that should be backported to stable kernels that include the RPC- IF xSPI support, with trivial API/context adjustments as needed.
drivers/spi/spi-rpc-if.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/spi/spi-rpc-if.c b/drivers/spi/spi-rpc-if.c index 627cffea5d5c7..300a7c10b3d40 100644 --- a/drivers/spi/spi-rpc-if.c +++ b/drivers/spi/spi-rpc-if.c @@ -207,6 +207,8 @@ static int __maybe_unused rpcif_spi_resume(struct device *dev) { struct spi_controller *ctlr = dev_get_drvdata(dev);
+ rpcif_hw_init(dev, false); + return spi_controller_resume(ctlr); }