Re: [PATCH 4/4] firmware: qcom: scm: introduce qcom_scm_bw class for bandwidth management
From: Mukesh Ojha
Date: Thu Jul 02 2026 - 05:03:05 EST
On Wed, Jul 01, 2026 at 03:38:58PM +0200, Bartosz Golaszewski wrote:
> Define DEFINE_CLASS(qcom_scm_bw) that calls qcom_scm_bw_enable() on
> construction and automatically calls qcom_scm_bw_disable() at scope exit
> *if* the enable succeeded.
>
> This allows us to convert all call sites to using
> CLASS(qcom_scm_bw, bw)() instead of the manual enable/check/disable
> pattern and to remove the associated goto labels in cleanup path.
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxxxxxxxx>
> ---
> drivers/firmware/qcom/qcom_scm.c | 61 ++++++++++++++++------------------------
> 1 file changed, 25 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 35aa9e8886b6ce8ab8eaf16c83fef7aafaef2822..6b64ed5a2b70a5ad3e57efb780df7dfa43518f91 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -227,6 +227,9 @@ static void qcom_scm_bw_disable(void)
> mutex_unlock(&__scm->scm_bw_lock);
> }
>
> +DEFINE_CLASS(qcom_scm_bw, int, if (!_T) qcom_scm_bw_disable(),
> + qcom_scm_bw_enable(), void)
> +
> enum qcom_scm_convention qcom_scm_convention = SMC_CONVENTION_UNKNOWN;
> static DEFINE_SPINLOCK(scm_query_lock);
>
> @@ -621,14 +624,13 @@ static int __qcom_scm_pas_init_image(u32 pas_id, dma_addr_t mdata_phys,
> if (clk)
> return clk;
>
> - ret = qcom_scm_bw_enable();
> - if (ret)
> - return ret;
> + CLASS(qcom_scm_bw, bw)();
> + if (bw)
> + return bw;
>
> desc.args[1] = mdata_phys;
>
> ret = qcom_scm_call(__scm->dev, &desc, res);
> - qcom_scm_bw_disable();
>
> return ret;
> }
> @@ -760,12 +762,11 @@ int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)
> if (clk)
> return clk;
>
> - ret = qcom_scm_bw_enable();
> - if (ret)
> - return ret;
> + CLASS(qcom_scm_bw, bw)();
> + if (bw)
> + return bw;
>
> ret = qcom_scm_call(__scm->dev, &desc, &res);
> - qcom_scm_bw_disable();
>
> return ret ? : res.result[0];
> }
> @@ -870,15 +871,14 @@ struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *c
> struct resource_table empty_rsc = {};
> size_t size = SZ_16K;
> void *tbl_ptr;
> - int ret;
>
> CLASS(qcom_scm_clk, clk)();
> if (clk)
> return ERR_PTR(clk);
>
> - ret = qcom_scm_bw_enable();
> - if (ret)
> - return ERR_PTR(ret);
> + CLASS(qcom_scm_bw, bw)();
> + if (bw)
> + return ERR_PTR(bw);
>
> /*
> * TrustZone can not accept buffer as NULL value as argument hence,
> @@ -893,10 +893,8 @@ struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *c
> void *input_rt_tzm __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
> input_rt_size,
> GFP_KERNEL);
> - if (!input_rt_tzm) {
> - ret = -ENOMEM;
> - goto disable_scm_bw;
> - }
> + if (!input_rt_tzm)
> + return ERR_PTR(-ENOMEM);
>
> memcpy(input_rt_tzm, input_rt, input_rt_size);
>
> @@ -909,23 +907,16 @@ struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *c
> input_rt_tzm,
> input_rt_size,
> &size);
> - if (IS_ERR(output_rt_tzm)) {
> - ret = PTR_ERR(output_rt_tzm);
> - goto disable_scm_bw;
> - }
> + if (IS_ERR(output_rt_tzm))
> + return output_rt_tzm;
>
> tbl_ptr = kmemdup(output_rt_tzm, size, GFP_KERNEL);
> - if (!tbl_ptr) {
> - ret = -ENOMEM;
> - goto disable_scm_bw;
> - }
> + if (!tbl_ptr)
> + return ERR_PTR(-ENOMEM);
>
> *output_rt_size = size;
>
> -disable_scm_bw:
> - qcom_scm_bw_disable();
> -
> - return ret ? ERR_PTR(ret) : tbl_ptr;
> + return tbl_ptr;
> }
> EXPORT_SYMBOL_GPL(qcom_scm_pas_get_rsc_table);
>
> @@ -952,12 +943,11 @@ int qcom_scm_pas_auth_and_reset(u32 pas_id)
> if (clk)
> return clk;
>
> - ret = qcom_scm_bw_enable();
> - if (ret)
> - return ret;
> + CLASS(qcom_scm_bw, bw)();
> + if (bw)
> + return bw;
>
> ret = qcom_scm_call(__scm->dev, &desc, &res);
> - qcom_scm_bw_disable();
>
> return ret ? : res.result[0];
> }
> @@ -1032,12 +1022,11 @@ int qcom_scm_pas_shutdown(u32 pas_id)
> if (clk)
> return clk;
>
> - ret = qcom_scm_bw_enable();
> - if (ret)
> - return ret;
> + CLASS(qcom_scm_bw, bw)();
> + if (bw)
> + return bw;
>
> ret = qcom_scm_call(__scm->dev, &desc, &res);
> - qcom_scm_bw_disable();
>
> return ret ? : res.result[0];
> }
Reviewed-by: Mukesh Ojha <mukesh.ojha@xxxxxxxxxxxxxxxx>
--
-Mukesh Ojha