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

Reply via email to