Skip to content

Commit 67af3cd

Browse files
andredkrzk
authored andcommitted
firmware: exynos-acpm: fix reading longer results
ACPM commands that return more than 8 bytes currently don't work correctly, as this driver ignores any such returned bytes. This is evident in at least acpm_pmic_bulk_read(), where up to 8 registers can be read back and those 8 register values are placed starting at &xfer->rxd[8]. The reason is that xfter->rxlen is initialized with the size of a pointer (8 bytes), rather than the size of the byte array that pointer points to (16 bytes) Update the code such that we set the number of bytes expected to be the size of the rx buffer. Note1: While different commands have different lengths rx buffers, we have to specify the same length for all rx buffers since acpm_get_rx() assumes they're all the same length. Note2: The different commands also have different lengths tx buffers, but before switching the code to use the minimum possible length, some more testing would have to be done to ensure this works correctly in all situations. It seems wiser to just apply this fix here without additional logic changes for now. Fixes: a88927b ("firmware: add Exynos ACPM protocol driver") Reviewed-by: Tudor Ambarus <[email protected]> Signed-off-by: André Draszik <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Krzysztof Kozlowski <[email protected]>
1 parent 935e5bd commit 67af3cd

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

drivers/firmware/samsung/exynos-acpm-pmic.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@ static inline u32 acpm_pmic_get_bulk(u32 data, unsigned int i)
4343
return (data >> (ACPM_PMIC_BULK_SHIFT * i)) & ACPM_PMIC_BULK_MASK;
4444
}
4545

46-
static void acpm_pmic_set_xfer(struct acpm_xfer *xfer, u32 *cmd,
46+
static void acpm_pmic_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen,
4747
unsigned int acpm_chan_id)
4848
{
4949
xfer->txd = cmd;
5050
xfer->rxd = cmd;
51-
xfer->txlen = sizeof(cmd);
52-
xfer->rxlen = sizeof(cmd);
51+
xfer->txlen = cmdlen;
52+
xfer->rxlen = cmdlen;
5353
xfer->acpm_chan_id = acpm_chan_id;
5454
}
5555

@@ -71,7 +71,7 @@ int acpm_pmic_read_reg(const struct acpm_handle *handle,
7171
int ret;
7272

7373
acpm_pmic_init_read_cmd(cmd, type, reg, chan);
74-
acpm_pmic_set_xfer(&xfer, cmd, acpm_chan_id);
74+
acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
7575

7676
ret = acpm_do_xfer(handle, &xfer);
7777
if (ret)
@@ -104,7 +104,7 @@ int acpm_pmic_bulk_read(const struct acpm_handle *handle,
104104
return -EINVAL;
105105

106106
acpm_pmic_init_bulk_read_cmd(cmd, type, reg, chan, count);
107-
acpm_pmic_set_xfer(&xfer, cmd, acpm_chan_id);
107+
acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
108108

109109
ret = acpm_do_xfer(handle, &xfer);
110110
if (ret)
@@ -144,7 +144,7 @@ int acpm_pmic_write_reg(const struct acpm_handle *handle,
144144
int ret;
145145

146146
acpm_pmic_init_write_cmd(cmd, type, reg, chan, value);
147-
acpm_pmic_set_xfer(&xfer, cmd, acpm_chan_id);
147+
acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
148148

149149
ret = acpm_do_xfer(handle, &xfer);
150150
if (ret)
@@ -184,7 +184,7 @@ int acpm_pmic_bulk_write(const struct acpm_handle *handle,
184184
return -EINVAL;
185185

186186
acpm_pmic_init_bulk_write_cmd(cmd, type, reg, chan, count, buf);
187-
acpm_pmic_set_xfer(&xfer, cmd, acpm_chan_id);
187+
acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
188188

189189
ret = acpm_do_xfer(handle, &xfer);
190190
if (ret)
@@ -214,7 +214,7 @@ int acpm_pmic_update_reg(const struct acpm_handle *handle,
214214
int ret;
215215

216216
acpm_pmic_init_update_cmd(cmd, type, reg, chan, value, mask);
217-
acpm_pmic_set_xfer(&xfer, cmd, acpm_chan_id);
217+
acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
218218

219219
ret = acpm_do_xfer(handle, &xfer);
220220
if (ret)

0 commit comments

Comments
 (0)