diff --git a/drivers/soc/qcom/rpmh-internal.h b/drivers/soc/qcom/rpmh-internal.h index 52554d737093..54c1e014f17f 100644 --- a/drivers/soc/qcom/rpmh-internal.h +++ b/drivers/soc/qcom/rpmh-internal.h @@ -17,6 +17,9 @@ #define MAX_TCS_NR (MAX_TCS_PER_TYPE * TCS_TYPE_NR) #define MAX_TCS_SLOTS (MAX_CMDS_PER_TCS * MAX_TCS_PER_TYPE) +/* CTRLR specific flags */ +#define SOLVER_PRESENT 1 + struct rsc_drv; /** @@ -78,6 +81,7 @@ struct rpmh_request { * @cache_lock: synchronize access to the cache data * @dirty: was the cache updated since flush * @in_solver_mode: Controller is busy in solver mode + * @flags: Controller specific flags * @batch_cache: Cache sleep and wake requests sent as batch */ struct rpmh_ctrlr { @@ -85,6 +89,7 @@ struct rpmh_ctrlr { spinlock_t cache_lock; bool dirty; bool in_solver_mode; + u32 flags; struct list_head batch_cache; }; diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 6d9ca686f527..cf561f09bc3e 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -1128,6 +1128,9 @@ static int rpmh_rsc_probe(struct platform_device *pdev) if (!solver_config) { drv->rsc_pm.notifier_call = rpmh_rsc_cpu_pm_callback; cpu_pm_register_notifier(&drv->rsc_pm); + drv->client.flags &= ~SOLVER_PRESENT; + } else { + drv->client.flags |= SOLVER_PRESENT; } /* Enable the active TCS to send requests immediately */ diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c index 3f44e8526a7f..e4a50fd41412 100644 --- a/drivers/soc/qcom/rpmh.c +++ b/drivers/soc/qcom/rpmh.c @@ -83,6 +83,9 @@ static int check_ctrlr_state(struct rpmh_ctrlr *ctrlr, enum rpmh_state state) if (state != RPMH_ACTIVE_ONLY_STATE) return ret; + if (!(ctrlr->flags & SOLVER_PRESENT)) + return ret; + /* Do not allow sending active votes when in solver mode */ spin_lock(&ctrlr->cache_lock); if (ctrlr->in_solver_mode) @@ -484,12 +487,24 @@ int rpmh_flush(struct rpmh_ctrlr *ctrlr) if (rpmh_standalone) return 0; - lockdep_assert_irqs_disabled(); + /* + * For RSC that don't have solver mode, + * rpmh_flush() is only called when we think we're running + * on the last CPU with irqs_disabled. + * + * For RSC that have solver mode, + * rpmh_flush() can be invoked with irqs enabled by any CPU. + * + * Conditionally check for irqs_disabled only when solver mode + * is not available. + */ + + if (!(ctrlr->flags & SOLVER_PRESENT)) + lockdep_assert_irqs_disabled(); /* - * Currently rpmh_flush() is only called when we think we're running - * on the last processor. If the lock is busy it means another - * processor is up and it's better to abort than spin. + * If the lock is busy it means another transaction is on going, + * in such case it's better to abort than spin. */ if (!spin_trylock(&ctrlr->cache_lock)) return -EBUSY; @@ -588,6 +603,9 @@ int rpmh_mode_solver_set(const struct device *dev, bool enable) if (rpmh_standalone) return 0; + if (!(ctrlr->flags & SOLVER_PRESENT)) + return -EINVAL; + spin_lock(&ctrlr->cache_lock); ret = rpmh_rsc_mode_solver_set(ctrlr_to_drv(ctrlr), enable); if (!ret)