diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 1bd70bd83489f..0bd3c46e9fb1e 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -149,7 +149,7 @@ int rpmh_rsc_invalidate(struct rsc_drv *drv) static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv, const struct tcs_request *msg) { - int type; + int type, ret; struct tcs_group *tcs; switch (msg->state) { @@ -170,10 +170,19 @@ static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv, * If we are making an active request on a RSC that does not have a * dedicated TCS for active state use, then re-purpose a wake TCS to * send active votes. + * NOTE: The driver must be aware that this RSC does not have a + * dedicated AMC, and therefore would invalidate the sleep and wake + * TCSes before making an active state request. */ tcs = get_tcs_of_type(drv, type); - if (msg->state == RPMH_ACTIVE_ONLY_STATE && !tcs->num_tcs) + if (msg->state == RPMH_ACTIVE_ONLY_STATE && !tcs->num_tcs) { tcs = get_tcs_of_type(drv, WAKE_TCS); + if (tcs->num_tcs) { + ret = rpmh_rsc_invalidate(drv); + if (ret) + return ERR_PTR(ret); + } + } return tcs; } @@ -398,16 +407,8 @@ static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg) tcs->req[tcs_id - tcs->offset] = msg; set_bit(tcs_id, drv->tcs_in_use); - if (msg->state == RPMH_ACTIVE_ONLY_STATE && tcs->type != ACTIVE_TCS) { - /* - * Clear previously programmed WAKE commands in selected - * repurposed TCS to avoid triggering them. tcs->slots will be - * cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate() - */ - write_tcs_reg_sync(drv, RSC_DRV_CMD_ENABLE, tcs_id, 0); - write_tcs_reg_sync(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, 0); + if (msg->state == RPMH_ACTIVE_ONLY_STATE && tcs->type != ACTIVE_TCS) enable_tcs_irq(drv, tcs_id, true); - } spin_unlock(&drv->lock); __tcs_buffer_write(drv, tcs_id, 0, msg);