From 910e91a6496f7e0af80e945a6b850b589b90669e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 19 Feb 2026 12:27:10 +0100 Subject: [PATCH 1/5] firmware: exynos-acpm: Use unsigned int for acpm_pmic_linux_errmap index acpm_pmic_to_linux_err() uses an unsigned integer obtained from messages as index of array to map them to error codes. Array index cannot be negative, so make that explicit. Reviewed-by: Tudor Ambarus Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20260219-firmare-acpm-counted-v2-1-e1f7389237d3@oss.qualcomm.com Signed-off-by: Krzysztof Kozlowski --- drivers/firmware/samsung/exynos-acpm-pmic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/samsung/exynos-acpm-pmic.c b/drivers/firmware/samsung/exynos-acpm-pmic.c index 961d7599e422..44265db34ae6 100644 --- a/drivers/firmware/samsung/exynos-acpm-pmic.c +++ b/drivers/firmware/samsung/exynos-acpm-pmic.c @@ -41,7 +41,7 @@ static const int acpm_pmic_linux_errmap[] = { [2] = -EACCES, /* Write register can't be accessed or issues to access it. */ }; -static int acpm_pmic_to_linux_err(int err) +static int acpm_pmic_to_linux_err(unsigned int err) { if (err >= 0 && err < ARRAY_SIZE(acpm_pmic_linux_errmap)) return acpm_pmic_linux_errmap[err]; From 00808ae2e679a97dccc5cf0ee4474ba1e2e8a21a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 19 Feb 2026 12:27:11 +0100 Subject: [PATCH 2/5] firmware: exynos-acpm: Count number of commands in acpm_xfer Struct acpm_xfer holds two buffers with u32 commands - rxd and txd - and counts their size by rxlen and txlen. "len" suffix is here ambiguous, so could mean length of the buffer or length of commands, and these are not the same since each command is u32. Rename these to rxcnt and txcnt, and change their usage to count the number of commands in each buffer. This will have a benefit of allowing to use __counted_by_ptr later. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Tudor Ambarus Link: https://patch.msgid.link/20260219-firmare-acpm-counted-v2-2-e1f7389237d3@oss.qualcomm.com Signed-off-by: Krzysztof Kozlowski --- drivers/firmware/samsung/exynos-acpm-dvfs.c | 9 +++++---- drivers/firmware/samsung/exynos-acpm-pmic.c | 14 +++++++------- drivers/firmware/samsung/exynos-acpm.c | 14 +++++++------- drivers/firmware/samsung/exynos-acpm.h | 4 ++-- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.c b/drivers/firmware/samsung/exynos-acpm-dvfs.c index 1c5b2b143bcc..485fc77ad4b1 100644 --- a/drivers/firmware/samsung/exynos-acpm-dvfs.c +++ b/drivers/firmware/samsung/exynos-acpm-dvfs.c @@ -5,6 +5,7 @@ * Copyright 2025 Linaro Ltd. */ +#include #include #include #include @@ -25,11 +26,11 @@ static void acpm_dvfs_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen, { xfer->acpm_chan_id = acpm_chan_id; xfer->txd = cmd; - xfer->txlen = cmdlen; + xfer->txcnt = cmdlen; if (response) { xfer->rxd = cmd; - xfer->rxlen = cmdlen; + xfer->rxcnt = cmdlen; } } @@ -50,7 +51,7 @@ int acpm_dvfs_set_rate(const struct acpm_handle *handle, u32 cmd[4]; acpm_dvfs_init_set_rate_cmd(cmd, clk_id, rate); - acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, false); + acpm_dvfs_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, false); return acpm_do_xfer(handle, &xfer); } @@ -70,7 +71,7 @@ unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle, int ret; acpm_dvfs_init_get_rate_cmd(cmd, clk_id); - acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, true); + acpm_dvfs_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 44265db34ae6..26a9024d8ed8 100644 --- a/drivers/firmware/samsung/exynos-acpm-pmic.c +++ b/drivers/firmware/samsung/exynos-acpm-pmic.c @@ -63,8 +63,8 @@ static void acpm_pmic_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen, { xfer->txd = cmd; xfer->rxd = cmd; - xfer->txlen = cmdlen; - xfer->rxlen = cmdlen; + xfer->txcnt = cmdlen; + xfer->rxcnt = cmdlen; xfer->acpm_chan_id = acpm_chan_id; } @@ -86,7 +86,7 @@ int acpm_pmic_read_reg(const struct acpm_handle *handle, int ret; acpm_pmic_init_read_cmd(cmd, type, reg, chan); - acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id); + acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id); ret = acpm_do_xfer(handle, &xfer); if (ret) @@ -119,7 +119,7 @@ int acpm_pmic_bulk_read(const struct acpm_handle *handle, return -EINVAL; acpm_pmic_init_bulk_read_cmd(cmd, type, reg, chan, count); - acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id); + acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id); ret = acpm_do_xfer(handle, &xfer); if (ret) @@ -159,7 +159,7 @@ int acpm_pmic_write_reg(const struct acpm_handle *handle, int ret; acpm_pmic_init_write_cmd(cmd, type, reg, chan, value); - acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id); + acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id); ret = acpm_do_xfer(handle, &xfer); if (ret) @@ -199,7 +199,7 @@ int acpm_pmic_bulk_write(const struct acpm_handle *handle, return -EINVAL; acpm_pmic_init_bulk_write_cmd(cmd, type, reg, chan, count, buf); - acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id); + acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id); ret = acpm_do_xfer(handle, &xfer); if (ret) @@ -229,7 +229,7 @@ int acpm_pmic_update_reg(const struct acpm_handle *handle, int ret; acpm_pmic_init_update_cmd(cmd, type, reg, chan, value, mask); - acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id); + acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id); 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 0cb269c70460..c616ac951a0d 100644 --- a/drivers/firmware/samsung/exynos-acpm.c +++ b/drivers/firmware/samsung/exynos-acpm.c @@ -205,7 +205,7 @@ static void acpm_get_saved_rx(struct acpm_chan *achan, rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, rx_data->cmd[0]); if (rx_seqnum == tx_seqnum) { - memcpy(xfer->rxd, rx_data->cmd, xfer->rxlen); + memcpy(xfer->rxd, rx_data->cmd, xfer->rxcnt * sizeof(*xfer->rxd)); clear_bit(rx_seqnum - 1, achan->bitmap_seqnum); } } @@ -258,8 +258,7 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer) if (rx_data->response) { if (rx_seqnum == tx_seqnum) { - __ioread32_copy(xfer->rxd, addr, - xfer->rxlen / 4); + __ioread32_copy(xfer->rxd, addr, xfer->rxcnt); rx_set = true; clear_bit(seqnum, achan->bitmap_seqnum); } else { @@ -269,8 +268,7 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer) * clear yet the bitmap. It will be cleared * after the response is copied to the request. */ - __ioread32_copy(rx_data->cmd, addr, - xfer->rxlen / 4); + __ioread32_copy(rx_data->cmd, addr, xfer->rxcnt); } } else { clear_bit(seqnum, achan->bitmap_seqnum); @@ -425,7 +423,9 @@ int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer) achan = &acpm->chans[xfer->acpm_chan_id]; - if (!xfer->txd || xfer->txlen > achan->mlen || xfer->rxlen > achan->mlen) + if (!xfer->txd || + (xfer->txcnt * sizeof(*xfer->txd) > achan->mlen) || + (xfer->rxcnt * sizeof(*xfer->rxd) > achan->mlen)) return -EINVAL; if (!achan->poll_completion) { @@ -448,7 +448,7 @@ int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer) /* Write TX command. */ __iowrite32_copy(achan->tx.base + achan->mlen * tx_front, - xfer->txd, xfer->txlen / 4); + xfer->txd, xfer->txcnt); /* Advance TX front. */ writel(idx, achan->tx.front); diff --git a/drivers/firmware/samsung/exynos-acpm.h b/drivers/firmware/samsung/exynos-acpm.h index 2d14cb58f98c..422fbcac7284 100644 --- a/drivers/firmware/samsung/exynos-acpm.h +++ b/drivers/firmware/samsung/exynos-acpm.h @@ -10,8 +10,8 @@ struct acpm_xfer { const u32 *txd; u32 *rxd; - size_t txlen; - size_t rxlen; + size_t txcnt; + size_t rxcnt; unsigned int acpm_chan_id; }; From 951b8eee0581bbf39e7b0464d679eee8cb9da3e0 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 19 Feb 2026 12:27:12 +0100 Subject: [PATCH 3/5] firmware: exynos-acpm: Count acpm_xfer buffers with __counted_by_ptr Use __counted_by_ptr() attribute on the acpm_xfer buffers so UBSAN will validate runtime that we do not pass over the buffer size, thus making code safer. Usage of __counted_by_ptr() (or actually __counted_by()) requires that counter is initialized before counted array. Tested-by: Tudor Ambarus Reviewed-by: Tudor Ambarus Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20260219-firmare-acpm-counted-v2-3-e1f7389237d3@oss.qualcomm.com Signed-off-by: Krzysztof Kozlowski --- drivers/firmware/samsung/exynos-acpm-dvfs.c | 4 ++-- drivers/firmware/samsung/exynos-acpm.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.c b/drivers/firmware/samsung/exynos-acpm-dvfs.c index 485fc77ad4b1..17e7be7757b3 100644 --- a/drivers/firmware/samsung/exynos-acpm-dvfs.c +++ b/drivers/firmware/samsung/exynos-acpm-dvfs.c @@ -25,12 +25,12 @@ 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->txd = cmd; xfer->txcnt = cmdlen; + xfer->txd = cmd; if (response) { - xfer->rxd = cmd; xfer->rxcnt = cmdlen; + xfer->rxd = cmd; } } diff --git a/drivers/firmware/samsung/exynos-acpm.h b/drivers/firmware/samsung/exynos-acpm.h index 422fbcac7284..8392fcb91f45 100644 --- a/drivers/firmware/samsung/exynos-acpm.h +++ b/drivers/firmware/samsung/exynos-acpm.h @@ -8,8 +8,8 @@ #define __EXYNOS_ACPM_H__ struct acpm_xfer { - const u32 *txd; - u32 *rxd; + const u32 *txd __counted_by_ptr(txcnt); + u32 *rxd __counted_by_ptr(rxcnt); size_t txcnt; size_t rxcnt; unsigned int acpm_chan_id; From f2e83070febf61fc72765cdc28d2a45c89b77ce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Draszik?= Date: Tue, 10 Feb 2026 12:42:32 +0000 Subject: [PATCH 4/5] dt-bindings: firmware: google,gs101-acpm-ipc: add S2MPG11 secondary PMIC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In a typical system using the Samsung S2MPG10 PMIC, an S2MPG11 is used as a sub-PMIC. The interface for both is the ACPM firmware protocol, so update the binding to allow the relevant node and update the example here to describe the connection for both PMICs. Since we have two PMICs here, but can not use the 'reg' property (as the addressing is based on software, i.e. the ACPM firmware), the node names reflect that with their respective suffix. The existing 'pmic' therefore becomes deprecated in favour of 'pmic-1'. While at it, update the example. Reviewed-by: Krzysztof Kozlowski Signed-off-by: André Draszik Link: https://patch.msgid.link/20260210-s2mpg1x-regulators-v8-1-c429d709c0e0@linaro.org Signed-off-by: Krzysztof Kozlowski --- .../firmware/google,gs101-acpm-ipc.yaml | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml b/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml index 4a1e3e3c0505..e68f9c3ca5e2 100644 --- a/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml +++ b/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml @@ -37,6 +37,7 @@ properties: maxItems: 1 pmic: + deprecated: true description: Child node describing the main PMIC. type: object additionalProperties: true @@ -45,6 +46,24 @@ properties: compatible: const: samsung,s2mpg10-pmic + pmic-1: + description: Child node describing the main PMIC. + type: object + additionalProperties: true + + properties: + compatible: + const: samsung,s2mpg10-pmic + + pmic-2: + description: Child node describing the sub PMIC. + type: object + additionalProperties: true + + properties: + compatible: + const: samsung,s2mpg11-pmic + shmem: description: List of phandle pointing to the shared memory (SHM) area. The memory @@ -62,7 +81,9 @@ additionalProperties: false examples: - | + #include #include + #include power-management { compatible = "google,gs101-acpm-ipc"; @@ -70,10 +91,12 @@ examples: mboxes = <&ap2apm_mailbox>; shmem = <&apm_sram>; - pmic { + pmic-1 { compatible = "samsung,s2mpg10-pmic"; interrupts-extended = <&gpa0 6 IRQ_TYPE_LEVEL_LOW>; + vinl3m-supply = <&buck8m>; + regulators { ldo1m { regulator-name = "vdd_ldo1"; @@ -82,7 +105,13 @@ examples: regulator-always-on; }; - // ... + ldo20m { + regulator-name = "vdd_dmics"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-always-on; + samsung,ext-control = ; + }; buck8m { regulator-name = "vdd_mif"; @@ -93,4 +122,21 @@ examples: }; }; }; + + pmic-2 { + compatible = "samsung,s2mpg11-pmic"; + interrupts-extended = <&gpa0 7 IRQ_TYPE_LEVEL_LOW>; + + vinl1s-supply = <&buck8m>; + vinl2s-supply = <&buck6s>; + + regulators { + buckd { + regulator-name = "vcc_ufs"; + regulator-ramp-delay = <6250>; + enable-gpios = <&gpp0 1 GPIO_ACTIVE_HIGH>; + samsung,ext-control = ; + }; + }; + }; }; From a2be37eedb52ea26938fa4cc9de1ff84963c57ad Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 24 Feb 2026 11:42:04 +0100 Subject: [PATCH 5/5] firmware: exynos-acpm: Drop fake 'const' on handle pointer All the functions operating on the 'handle' pointer are claiming it is a pointer to const thus they should not modify the handle. In fact that's a false statement, because first thing these functions do is drop the cast to const with container_of: struct acpm_info *acpm = handle_to_acpm_info(handle); And with such cast the handle is easily writable with simple: acpm->handle.ops.pmic_ops.read_reg = NULL; The code is not correct logically, either, because functions like acpm_get_by_node() and acpm_handle_put() are meant to modify the handle reference counting, thus they must modify the handle. Modification here happens anyway, even if the reference counting is stored in the container which the handle is part of. The code does not have actual visible bug, but incorrect 'const' annotations could lead to incorrect compiler decisions. Fixes: a88927b534ba ("firmware: add Exynos ACPM protocol driver") Cc: stable@vger.kernel.org Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20260224104203.42950-2-krzysztof.kozlowski@oss.qualcomm.com Signed-off-by: Krzysztof Kozlowski --- drivers/clk/samsung/clk-acpm.c | 4 +- drivers/firmware/samsung/exynos-acpm-dvfs.c | 4 +- drivers/firmware/samsung/exynos-acpm-dvfs.h | 4 +- drivers/firmware/samsung/exynos-acpm-pmic.c | 10 ++--- drivers/firmware/samsung/exynos-acpm-pmic.h | 10 ++--- drivers/firmware/samsung/exynos-acpm.c | 16 ++++---- drivers/firmware/samsung/exynos-acpm.h | 2 +- drivers/mfd/sec-acpm.c | 10 ++--- .../firmware/samsung/exynos-acpm-protocol.h | 40 ++++++++----------- 9 files changed, 48 insertions(+), 52 deletions(-) diff --git a/drivers/clk/samsung/clk-acpm.c b/drivers/clk/samsung/clk-acpm.c index b90809ce3f88..d8944160793a 100644 --- a/drivers/clk/samsung/clk-acpm.c +++ b/drivers/clk/samsung/clk-acpm.c @@ -20,7 +20,7 @@ struct acpm_clk { u32 id; struct clk_hw hw; unsigned int mbox_chan_id; - const struct acpm_handle *handle; + struct acpm_handle *handle; }; struct acpm_clk_variant { @@ -113,7 +113,7 @@ static int acpm_clk_register(struct device *dev, struct acpm_clk *aclk, static int acpm_clk_probe(struct platform_device *pdev) { - const struct acpm_handle *acpm_handle; + struct acpm_handle *acpm_handle; struct clk_hw_onecell_data *clk_data; struct clk_hw **hws; struct device *dev = &pdev->dev; diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.c b/drivers/firmware/samsung/exynos-acpm-dvfs.c index 17e7be7757b3..06bdf62dea1f 100644 --- a/drivers/firmware/samsung/exynos-acpm-dvfs.c +++ b/drivers/firmware/samsung/exynos-acpm-dvfs.c @@ -43,7 +43,7 @@ static void acpm_dvfs_init_set_rate_cmd(u32 cmd[4], unsigned int clk_id, cmd[3] = ktime_to_ms(ktime_get()); } -int acpm_dvfs_set_rate(const struct acpm_handle *handle, +int acpm_dvfs_set_rate(struct acpm_handle *handle, unsigned int acpm_chan_id, unsigned int clk_id, unsigned long rate) { @@ -63,7 +63,7 @@ static void acpm_dvfs_init_get_rate_cmd(u32 cmd[4], unsigned int clk_id) cmd[3] = ktime_to_ms(ktime_get()); } -unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle, +unsigned long acpm_dvfs_get_rate(struct acpm_handle *handle, unsigned int acpm_chan_id, unsigned int clk_id) { struct acpm_xfer xfer; diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.h b/drivers/firmware/samsung/exynos-acpm-dvfs.h index 9f2778e649c9..b37b15426102 100644 --- a/drivers/firmware/samsung/exynos-acpm-dvfs.h +++ b/drivers/firmware/samsung/exynos-acpm-dvfs.h @@ -11,10 +11,10 @@ struct acpm_handle; -int acpm_dvfs_set_rate(const struct acpm_handle *handle, +int acpm_dvfs_set_rate(struct acpm_handle *handle, unsigned int acpm_chan_id, unsigned int id, unsigned long rate); -unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle, +unsigned long acpm_dvfs_get_rate(struct acpm_handle *handle, unsigned int acpm_chan_id, unsigned int clk_id); diff --git a/drivers/firmware/samsung/exynos-acpm-pmic.c b/drivers/firmware/samsung/exynos-acpm-pmic.c index 26a9024d8ed8..0c50993cc9a8 100644 --- a/drivers/firmware/samsung/exynos-acpm-pmic.c +++ b/drivers/firmware/samsung/exynos-acpm-pmic.c @@ -77,7 +77,7 @@ static void acpm_pmic_init_read_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan) cmd[3] = ktime_to_ms(ktime_get()); } -int acpm_pmic_read_reg(const struct acpm_handle *handle, +int acpm_pmic_read_reg(struct acpm_handle *handle, unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, u8 *buf) { @@ -107,7 +107,7 @@ static void acpm_pmic_init_bulk_read_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan, FIELD_PREP(ACPM_PMIC_VALUE, count); } -int acpm_pmic_bulk_read(const struct acpm_handle *handle, +int acpm_pmic_bulk_read(struct acpm_handle *handle, unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, u8 count, u8 *buf) { @@ -150,7 +150,7 @@ static void acpm_pmic_init_write_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan, cmd[3] = ktime_to_ms(ktime_get()); } -int acpm_pmic_write_reg(const struct acpm_handle *handle, +int acpm_pmic_write_reg(struct acpm_handle *handle, unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, u8 value) { @@ -187,7 +187,7 @@ static void acpm_pmic_init_bulk_write_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan, } } -int acpm_pmic_bulk_write(const struct acpm_handle *handle, +int acpm_pmic_bulk_write(struct acpm_handle *handle, unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, u8 count, const u8 *buf) { @@ -220,7 +220,7 @@ static void acpm_pmic_init_update_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan, cmd[3] = ktime_to_ms(ktime_get()); } -int acpm_pmic_update_reg(const struct acpm_handle *handle, +int acpm_pmic_update_reg(struct acpm_handle *handle, unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, u8 value, u8 mask) { diff --git a/drivers/firmware/samsung/exynos-acpm-pmic.h b/drivers/firmware/samsung/exynos-acpm-pmic.h index 078421888a14..88ae9aada2ae 100644 --- a/drivers/firmware/samsung/exynos-acpm-pmic.h +++ b/drivers/firmware/samsung/exynos-acpm-pmic.h @@ -11,19 +11,19 @@ struct acpm_handle; -int acpm_pmic_read_reg(const struct acpm_handle *handle, +int acpm_pmic_read_reg(struct acpm_handle *handle, unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, u8 *buf); -int acpm_pmic_bulk_read(const struct acpm_handle *handle, +int acpm_pmic_bulk_read(struct acpm_handle *handle, unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, u8 count, u8 *buf); -int acpm_pmic_write_reg(const struct acpm_handle *handle, +int acpm_pmic_write_reg(struct acpm_handle *handle, unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, u8 value); -int acpm_pmic_bulk_write(const struct acpm_handle *handle, +int acpm_pmic_bulk_write(struct acpm_handle *handle, unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, u8 count, const u8 *buf); -int acpm_pmic_update_reg(const struct acpm_handle *handle, +int acpm_pmic_update_reg(struct acpm_handle *handle, unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, u8 value, u8 mask); #endif /* __EXYNOS_ACPM_PMIC_H__ */ diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c index c616ac951a0d..16c46ed60837 100644 --- a/drivers/firmware/samsung/exynos-acpm.c +++ b/drivers/firmware/samsung/exynos-acpm.c @@ -410,7 +410,7 @@ static int acpm_wait_for_message_response(struct acpm_chan *achan, * * Return: 0 on success, -errno otherwise. */ -int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer) +int acpm_do_xfer(struct acpm_handle *handle, const struct acpm_xfer *xfer) { struct acpm_info *acpm = handle_to_acpm_info(handle); struct exynos_mbox_msg msg; @@ -674,7 +674,7 @@ static int acpm_probe(struct platform_device *pdev) * acpm_handle_put() - release the handle acquired by acpm_get_by_phandle. * @handle: Handle acquired by acpm_get_by_phandle. */ -static void acpm_handle_put(const struct acpm_handle *handle) +static void acpm_handle_put(struct acpm_handle *handle) { struct acpm_info *acpm = handle_to_acpm_info(handle); struct device *dev = acpm->dev; @@ -700,9 +700,11 @@ static void devm_acpm_release(struct device *dev, void *res) * @np: ACPM device tree node. * * Return: pointer to handle on success, ERR_PTR(-errno) otherwise. + * + * Note: handle CANNOT be pointer to const */ -static const struct acpm_handle *acpm_get_by_node(struct device *dev, - struct device_node *np) +static struct acpm_handle *acpm_get_by_node(struct device *dev, + struct device_node *np) { struct platform_device *pdev; struct device_link *link; @@ -743,10 +745,10 @@ static const struct acpm_handle *acpm_get_by_node(struct device *dev, * * Return: pointer to handle on success, ERR_PTR(-errno) otherwise. */ -const struct acpm_handle *devm_acpm_get_by_node(struct device *dev, - struct device_node *np) +struct acpm_handle *devm_acpm_get_by_node(struct device *dev, + struct device_node *np) { - const struct acpm_handle **ptr, *handle; + struct acpm_handle **ptr, *handle; ptr = devres_alloc(devm_acpm_release, sizeof(*ptr), GFP_KERNEL); if (!ptr) diff --git a/drivers/firmware/samsung/exynos-acpm.h b/drivers/firmware/samsung/exynos-acpm.h index 8392fcb91f45..5df8354dc96c 100644 --- a/drivers/firmware/samsung/exynos-acpm.h +++ b/drivers/firmware/samsung/exynos-acpm.h @@ -17,7 +17,7 @@ struct acpm_xfer { struct acpm_handle; -int acpm_do_xfer(const struct acpm_handle *handle, +int acpm_do_xfer(struct acpm_handle *handle, const struct acpm_xfer *xfer); #endif /* __EXYNOS_ACPM_H__ */ diff --git a/drivers/mfd/sec-acpm.c b/drivers/mfd/sec-acpm.c index 537ea65685bf..0e23b9d9f7ee 100644 --- a/drivers/mfd/sec-acpm.c +++ b/drivers/mfd/sec-acpm.c @@ -367,7 +367,7 @@ static const struct regmap_config s2mpg11_regmap_config_meter = { }; struct sec_pmic_acpm_shared_bus_context { - const struct acpm_handle *acpm; + struct acpm_handle *acpm; unsigned int acpm_chan_id; u8 speedy_channel; }; @@ -390,7 +390,7 @@ static int sec_pmic_acpm_bus_write(void *context, const void *data, size_t count) { struct sec_pmic_acpm_bus_context *ctx = context; - const struct acpm_handle *acpm = ctx->shared->acpm; + struct acpm_handle *acpm = ctx->shared->acpm; const struct acpm_pmic_ops *pmic_ops = &acpm->ops.pmic_ops; size_t val_count = count - BITS_TO_BYTES(ACPM_ADDR_BITS); const u8 *d = data; @@ -410,7 +410,7 @@ static int sec_pmic_acpm_bus_read(void *context, const void *reg_buf, size_t reg void *val_buf, size_t val_size) { struct sec_pmic_acpm_bus_context *ctx = context; - const struct acpm_handle *acpm = ctx->shared->acpm; + struct acpm_handle *acpm = ctx->shared->acpm; const struct acpm_pmic_ops *pmic_ops = &acpm->ops.pmic_ops; const u8 *r = reg_buf; u8 reg; @@ -429,7 +429,7 @@ static int sec_pmic_acpm_bus_reg_update_bits(void *context, unsigned int reg, un unsigned int val) { struct sec_pmic_acpm_bus_context *ctx = context; - const struct acpm_handle *acpm = ctx->shared->acpm; + struct acpm_handle *acpm = ctx->shared->acpm; const struct acpm_pmic_ops *pmic_ops = &acpm->ops.pmic_ops; return pmic_ops->update_reg(acpm, ctx->shared->acpm_chan_id, ctx->type, reg & 0xff, @@ -480,7 +480,7 @@ static int sec_pmic_acpm_probe(struct platform_device *pdev) struct regmap *regmap_common, *regmap_pmic, *regmap; const struct sec_pmic_acpm_platform_data *pdata; struct sec_pmic_acpm_shared_bus_context *shared_ctx; - const struct acpm_handle *acpm; + struct acpm_handle *acpm; struct device *dev = &pdev->dev; int ret, irq; diff --git a/include/linux/firmware/samsung/exynos-acpm-protocol.h b/include/linux/firmware/samsung/exynos-acpm-protocol.h index 2091da965a5a..13f17dc4443b 100644 --- a/include/linux/firmware/samsung/exynos-acpm-protocol.h +++ b/include/linux/firmware/samsung/exynos-acpm-protocol.h @@ -14,30 +14,24 @@ struct acpm_handle; struct device_node; struct acpm_dvfs_ops { - int (*set_rate)(const struct acpm_handle *handle, - unsigned int acpm_chan_id, unsigned int clk_id, - unsigned long rate); - unsigned long (*get_rate)(const struct acpm_handle *handle, + int (*set_rate)(struct acpm_handle *handle, unsigned int acpm_chan_id, + unsigned int clk_id, unsigned long rate); + unsigned long (*get_rate)(struct acpm_handle *handle, unsigned int acpm_chan_id, unsigned int clk_id); }; struct acpm_pmic_ops { - int (*read_reg)(const struct acpm_handle *handle, - unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, - u8 *buf); - int (*bulk_read)(const struct acpm_handle *handle, - unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, - u8 count, u8 *buf); - int (*write_reg)(const struct acpm_handle *handle, - unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, - u8 value); - int (*bulk_write)(const struct acpm_handle *handle, - unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, - u8 count, const u8 *buf); - int (*update_reg)(const struct acpm_handle *handle, - unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, - u8 value, u8 mask); + int (*read_reg)(struct acpm_handle *handle, unsigned int acpm_chan_id, + u8 type, u8 reg, u8 chan, u8 *buf); + int (*bulk_read)(struct acpm_handle *handle, unsigned int acpm_chan_id, + u8 type, u8 reg, u8 chan, u8 count, u8 *buf); + int (*write_reg)(struct acpm_handle *handle, unsigned int acpm_chan_id, + u8 type, u8 reg, u8 chan, u8 value); + int (*bulk_write)(struct acpm_handle *handle, unsigned int acpm_chan_id, + u8 type, u8 reg, u8 chan, u8 count, const u8 *buf); + int (*update_reg)(struct acpm_handle *handle, unsigned int acpm_chan_id, + u8 type, u8 reg, u8 chan, u8 value, u8 mask); }; struct acpm_ops { @@ -56,12 +50,12 @@ struct acpm_handle { struct device; #if IS_ENABLED(CONFIG_EXYNOS_ACPM_PROTOCOL) -const struct acpm_handle *devm_acpm_get_by_node(struct device *dev, - struct device_node *np); +struct acpm_handle *devm_acpm_get_by_node(struct device *dev, + struct device_node *np); #else -static inline const struct acpm_handle *devm_acpm_get_by_node(struct device *dev, - struct device_node *np) +static inline struct acpm_handle *devm_acpm_get_by_node(struct device *dev, + struct device_node *np) { return NULL; }