[PATCH 1/6] firmware: samsung: acpm: Consolidate transfer initialization helper
Peter Griffin
peter.griffin at linaro.org
Fri May 8 14:06:32 PDT 2026
On Wed, 6 May 2026 at 12:39, Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> Both the DVFS and PMIC ACPM sub-drivers implement similar local helper
> functions (acpm_dvfs_set_xfer and acpm_pmic_set_xfer) to initialize the
> acpm_xfer structure before sending an IPC message.
>
> Move this logic into a single centralized helper, acpm_set_xfer(),
> in the core ACPM driver to reduce boilerplate, eliminate code
> duplication, and prepare for the upcoming ACPM TMU helper sub-driver
> which will also utilize this method.
>
> Note that there is no change in underlying functionality. While the old
> acpm_pmic_set_xfer() unconditionally assigned the RX buffer parameters
> (xfer->rxd and xfer->rxcnt), the new unified helper introduces a
> 'response' boolean. All updated PMIC call sites now explicitly pass
> 'true' for this argument. This ensures the unified helper takes the
> 'if (response)' branch, performing the exact same assignments and
> preserving the original PMIC behavior.
>
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
> drivers/firmware/samsung/exynos-acpm-dvfs.c | 20 ++------------------
> drivers/firmware/samsung/exynos-acpm-pmic.c | 20 +++++---------------
> drivers/firmware/samsung/exynos-acpm.c | 26 ++++++++++++++++++++++++++
> drivers/firmware/samsung/exynos-acpm.h | 2 ++
> 4 files changed, 35 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.c b/drivers/firmware/samsung/exynos-acpm-dvfs.c
> index fdea7aa24ca0..7266312ef5a6 100644
> --- a/drivers/firmware/samsung/exynos-acpm-dvfs.c
> +++ b/drivers/firmware/samsung/exynos-acpm-dvfs.c
> @@ -21,22 +21,6 @@
> #define ACPM_DVFS_FREQ_REQ 0
> #define ACPM_DVFS_FREQ_GET 1
>
> -static void acpm_dvfs_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen,
> - unsigned int acpm_chan_id, bool response)
> -{
> - xfer->acpm_chan_id = acpm_chan_id;
> - xfer->txcnt = cmdlen;
> - xfer->txd = cmd;
> -
> - if (response) {
> - xfer->rxcnt = cmdlen;
> - xfer->rxd = cmd;
> - } else {
> - xfer->rxcnt = 0;
> - xfer->rxd = NULL;
> - }
> -}
> -
> static void acpm_dvfs_init_set_rate_cmd(u32 cmd[4], unsigned int clk_id,
> unsigned long rate)
> {
> @@ -54,7 +38,7 @@ int acpm_dvfs_set_rate(struct acpm_handle *handle,
> u32 cmd[4];
>
> acpm_dvfs_init_set_rate_cmd(cmd, clk_id, rate);
> - acpm_dvfs_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, false);
> + acpm_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, false);
>
> return acpm_do_xfer(handle, &xfer);
> }
> @@ -74,7 +58,7 @@ unsigned long acpm_dvfs_get_rate(struct acpm_handle *handle,
> int ret;
>
> acpm_dvfs_init_get_rate_cmd(cmd, clk_id);
> - acpm_dvfs_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, true);
> + acpm_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, true);
>
> ret = acpm_do_xfer(handle, &xfer);
> if (ret)
> diff --git a/drivers/firmware/samsung/exynos-acpm-pmic.c b/drivers/firmware/samsung/exynos-acpm-pmic.c
> index 0c50993cc9a8..f032f2c69685 100644
> --- a/drivers/firmware/samsung/exynos-acpm-pmic.c
> +++ b/drivers/firmware/samsung/exynos-acpm-pmic.c
> @@ -58,16 +58,6 @@ static inline u32 acpm_pmic_get_bulk(u32 data, unsigned int i)
> return (data >> (ACPM_PMIC_BULK_SHIFT * i)) & ACPM_PMIC_BULK_MASK;
> }
>
> -static void acpm_pmic_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen,
> - unsigned int acpm_chan_id)
> -{
> - xfer->txd = cmd;
> - xfer->rxd = cmd;
> - xfer->txcnt = cmdlen;
> - xfer->rxcnt = cmdlen;
> - xfer->acpm_chan_id = acpm_chan_id;
> -}
> -
> static void acpm_pmic_init_read_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan)
> {
> cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
> @@ -86,7 +76,7 @@ int acpm_pmic_read_reg(struct acpm_handle *handle,
> int ret;
>
> acpm_pmic_init_read_cmd(cmd, type, reg, chan);
> - acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id);
> + acpm_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, true);
>
> ret = acpm_do_xfer(handle, &xfer);
> if (ret)
> @@ -119,7 +109,7 @@ int acpm_pmic_bulk_read(struct acpm_handle *handle,
> return -EINVAL;
>
> acpm_pmic_init_bulk_read_cmd(cmd, type, reg, chan, count);
> - acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id);
> + acpm_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, true);
>
> ret = acpm_do_xfer(handle, &xfer);
> if (ret)
> @@ -159,7 +149,7 @@ int acpm_pmic_write_reg(struct acpm_handle *handle,
> int ret;
>
> acpm_pmic_init_write_cmd(cmd, type, reg, chan, value);
> - acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id);
> + acpm_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, true);
>
> ret = acpm_do_xfer(handle, &xfer);
> if (ret)
> @@ -199,7 +189,7 @@ int acpm_pmic_bulk_write(struct acpm_handle *handle,
> return -EINVAL;
>
> acpm_pmic_init_bulk_write_cmd(cmd, type, reg, chan, count, buf);
> - acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id);
> + acpm_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, true);
>
> ret = acpm_do_xfer(handle, &xfer);
> if (ret)
> @@ -229,7 +219,7 @@ int acpm_pmic_update_reg(struct acpm_handle *handle,
> int ret;
>
> acpm_pmic_init_update_cmd(cmd, type, reg, chan, value, mask);
> - acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id);
> + acpm_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, true);
>
> ret = acpm_do_xfer(handle, &xfer);
> if (ret)
> diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c
> index a2cac913b2bd..88a06842753d 100644
> --- a/drivers/firmware/samsung/exynos-acpm.c
> +++ b/drivers/firmware/samsung/exynos-acpm.c
> @@ -517,6 +517,32 @@ int acpm_do_xfer(struct acpm_handle *handle, const struct acpm_xfer *xfer)
> return acpm_wait_for_message_response(achan, xfer);
> }
>
> +/**
> + * acpm_set_xfer() - initialize an ACPM IPC transfer structure.
> + * @xfer: pointer to the ACPM transfer structure that is being initialized.
> + * @cmd: pointer to the buffer containing the command to be transmitted
> + * to the ACPM firmware.
> + * @cmdcnt: length of the command in 32-bit words.
> + * @acpm_chan_id: mailbox channel identifier.
> + * @response: boolean flag indicating whether the kernel expects the ACPM
> + * firmware to send a reply to this specific command.
> + */
> +void acpm_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdcnt,
> + unsigned int acpm_chan_id, bool response)
> +{
> + xfer->acpm_chan_id = acpm_chan_id;
> + xfer->txcnt = cmdcnt;
> + xfer->txd = cmd;
> +
> + if (response) {
> + xfer->rxcnt = cmdcnt;
> + xfer->rxd = cmd;
> + } else {
> + xfer->rxcnt = 0;
> + xfer->rxd = NULL;
> + }
> +}
> +
> /**
> * acpm_chan_shmem_get_params() - get channel parameters and addresses of the
> * TX/RX queues.
> diff --git a/drivers/firmware/samsung/exynos-acpm.h b/drivers/firmware/samsung/exynos-acpm.h
> index 5df8354dc96c..708f6b0102ac 100644
> --- a/drivers/firmware/samsung/exynos-acpm.h
> +++ b/drivers/firmware/samsung/exynos-acpm.h
> @@ -17,6 +17,8 @@ struct acpm_xfer {
>
> struct acpm_handle;
>
> +void acpm_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdcnt,
> + unsigned int acpm_chan_id, bool response);
> int acpm_do_xfer(struct acpm_handle *handle,
> const struct acpm_xfer *xfer);
>
>
> --
> 2.54.0.545.g6539524ca2-goog
>
More information about the linux-arm-kernel
mailing list