diff --git a/drivers/soc/qcom/rpmh-internal.h b/drivers/soc/qcom/rpmh-internal.h index 02ad7da2e75e..81185196e5ef 100644 --- a/drivers/soc/qcom/rpmh-internal.h +++ b/drivers/soc/qcom/rpmh-internal.h @@ -151,5 +151,6 @@ int rpmh_rsc_mode_solver_set(struct rsc_drv *drv, bool enable); void rpmh_tx_done(const struct tcs_request *msg, int r); int rpmh_flush(struct rpmh_ctrlr *ctrlr); +int _rpmh_flush(struct rpmh_ctrlr *ctrlr); #endif /* __RPM_INTERNAL_H__ */ diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 0f6b55ea426a..63fc115b3239 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -1064,7 +1064,7 @@ static int rpmh_rsc_pd_cb(struct notifier_block *nb, /* We don't need to lock as domin on/off are serialized */ if ((action == GENPD_NOTIFY_PRE_OFF) && - (rpmh_rsc_ctrlr_is_busy(drv) || rpmh_flush(&drv->client))) + (rpmh_rsc_ctrlr_is_busy(drv) || _rpmh_flush(&drv->client))) return NOTIFY_BAD; return NOTIFY_OK; diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c index e4a50fd41412..43a06d93cd56 100644 --- a/drivers/soc/qcom/rpmh.c +++ b/drivers/soc/qcom/rpmh.c @@ -470,6 +470,45 @@ static int send_single(struct rpmh_ctrlr *ctrlr, enum rpmh_state state, return rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr), &rpm_msg.msg); } +int _rpmh_flush(struct rpmh_ctrlr *ctrlr) +{ + struct cache_req *p; + int ret = 0; + + if (!ctrlr->dirty) { + pr_debug("Skipping flush, TCS has latest data.\n"); + return ret; + } + + /* Invalidate the TCSes first to avoid stale data */ + rpmh_rsc_invalidate(ctrlr_to_drv(ctrlr)); + + /* First flush the cached batch requests */ + ret = flush_batch(ctrlr); + if (ret) + return ret; + + list_for_each_entry(p, &ctrlr->cache, list) { + if (!is_req_valid(p)) { + pr_debug("%s: skipping RPMH req: a:%#x s:%#x w:%#x\n", + __func__, p->addr, p->sleep_val, p->wake_val); + continue; + } + ret = send_single(ctrlr, RPMH_SLEEP_STATE, p->addr, + p->sleep_val); + if (ret) + return ret; + ret = send_single(ctrlr, RPMH_WAKE_ONLY_STATE, p->addr, + p->wake_val); + if (ret) + return ret; + } + + ctrlr->dirty = false; + + return ret; +} + /** * rpmh_flush() - Flushes the buffered sleep and wake sets to TCSes * @@ -481,8 +520,7 @@ static int send_single(struct rpmh_ctrlr *ctrlr, enum rpmh_state state, */ int rpmh_flush(struct rpmh_ctrlr *ctrlr) { - struct cache_req *p; - int ret = 0; + int ret; if (rpmh_standalone) return 0; @@ -498,7 +536,6 @@ int rpmh_flush(struct rpmh_ctrlr *ctrlr) * Conditionally check for irqs_disabled only when solver mode * is not available. */ - if (!(ctrlr->flags & SOLVER_PRESENT)) lockdep_assert_irqs_disabled(); @@ -508,40 +545,9 @@ int rpmh_flush(struct rpmh_ctrlr *ctrlr) */ if (!spin_trylock(&ctrlr->cache_lock)) return -EBUSY; - - if (!ctrlr->dirty) { - pr_debug("Skipping flush, TCS has latest data.\n"); - goto exit; - } - - /* Invalidate the TCSes first to avoid stale data */ - rpmh_rsc_invalidate(ctrlr_to_drv(ctrlr)); - - /* First flush the cached batch requests */ - ret = flush_batch(ctrlr); - if (ret) - goto exit; - - list_for_each_entry(p, &ctrlr->cache, list) { - if (!is_req_valid(p)) { - pr_debug("%s: skipping RPMH req: a:%#x s:%#x w:%#x", - __func__, p->addr, p->sleep_val, p->wake_val); - continue; - } - ret = send_single(ctrlr, RPMH_SLEEP_STATE, p->addr, - p->sleep_val); - if (ret) - goto exit; - ret = send_single(ctrlr, RPMH_WAKE_ONLY_STATE, p->addr, - p->wake_val); - if (ret) - goto exit; - } - - ctrlr->dirty = false; - -exit: + ret = _rpmh_flush(ctrlr); spin_unlock(&ctrlr->cache_lock); + return ret; }