On QCS6490-based platforms booting via UEFI, the RSC hardware solver is already active when the kernel takes over from the firmware. Calling rpmh_probe_tcs_config() in this state reinitializes the controller while the firmware is actively managing it, causing a security violation and system reset.
Check whether the hardware solver is already enabled via the DRV_SOLVER_CONFIG register before calling rpmh_probe_tcs_config(). If the solver is active, skip TCS initialization and return early after setting the driver data, allowing other drivers to find the controller without disrupting the firmware-managed state. Tested on Radxa Dragon Q6A (QCS6490) Signed-off-by: Graham O'Connor <[email protected]> --- drivers/soc/qcom/rpmh-rsc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index c6f7d5c9c..7915f12de 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -1074,6 +1074,20 @@ static int rpmh_rsc_probe(struct platform_device *pdev) else drv->regs = rpmh_rsc_reg_offset_ver_2_7; + /* + * On some platforms the RSC is already managed by the firmware + * when the kernel boots. Calling rpmh_probe_tcs_config() in this + * state would reinitialize the controller and cause a security + * violation. Skip TCS initialization if the hardware solver is + * already active. + */ + if (readl_relaxed(drv->base + drv->regs[DRV_SOLVER_CONFIG]) & + (DRV_HW_SOLVER_MASK << DRV_HW_SOLVER_SHIFT)) { + dev_dbg(&pdev->dev, "RSC already managed by firmware, skipping TCS init\n"); + platform_set_drvdata(pdev, drv); + return 0; + } + ret = rpmh_probe_tcs_config(pdev, drv); if (ret) return ret; -- 2.53.0
