Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

firmware: exynos-acpm: fix PMIC returned errno

ACPM PMIC command handlers returned a u8 value when they should
have returned either zero or negative error codes.
Translate the APM PMIC errno to linux errno.

Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Closes: https://lore.kernel.org/linux-input/aElHlTApXj-W_o1r@stanley.mountain/
Fixes: a88927b534ba ("firmware: add Exynos ACPM protocol driver")
Cc: stable@vger.kernel.org
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

authored by

Tudor Ambarus and committed by
Krzysztof Kozlowski
1da4cbef 187a3426

+20 -5
+20 -5
drivers/firmware/samsung/exynos-acpm-pmic.c
··· 4 4 * Copyright 2020 Google LLC. 5 5 * Copyright 2024 Linaro Ltd. 6 6 */ 7 + #include <linux/array_size.h> 7 8 #include <linux/bitfield.h> 9 + #include <linux/errno.h> 8 10 #include <linux/firmware/samsung/exynos-acpm-protocol.h> 9 11 #include <linux/ktime.h> 10 12 #include <linux/types.h> ··· 34 32 ACPM_PMIC_BULK_READ, 35 33 ACPM_PMIC_BULK_WRITE, 36 34 }; 35 + 36 + static const int acpm_pmic_linux_errmap[] = { 37 + [0] = 0, /* ACPM_PMIC_SUCCESS */ 38 + [1] = -EACCES, /* Read register can't be accessed or issues to access it. */ 39 + [2] = -EACCES, /* Write register can't be accessed or issues to access it. */ 40 + }; 41 + 42 + static int acpm_pmic_to_linux_err(int err) 43 + { 44 + if (err >= 0 && err < ARRAY_SIZE(acpm_pmic_linux_errmap)) 45 + return acpm_pmic_linux_errmap[err]; 46 + return -EIO; 47 + } 37 48 38 49 static inline u32 acpm_pmic_set_bulk(u32 data, unsigned int i) 39 50 { ··· 94 79 95 80 *buf = FIELD_GET(ACPM_PMIC_VALUE, xfer.rxd[1]); 96 81 97 - return FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]); 82 + return acpm_pmic_to_linux_err(FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1])); 98 83 } 99 84 100 85 static void acpm_pmic_init_bulk_read_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan, ··· 125 110 if (ret) 126 111 return ret; 127 112 128 - ret = FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]); 113 + ret = acpm_pmic_to_linux_err(FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1])); 129 114 if (ret) 130 115 return ret; 131 116 ··· 165 150 if (ret) 166 151 return ret; 167 152 168 - return FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]); 153 + return acpm_pmic_to_linux_err(FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1])); 169 154 } 170 155 171 156 static void acpm_pmic_init_bulk_write_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan, ··· 205 190 if (ret) 206 191 return ret; 207 192 208 - return FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]); 193 + return acpm_pmic_to_linux_err(FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1])); 209 194 } 210 195 211 196 static void acpm_pmic_init_update_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan, ··· 235 220 if (ret) 236 221 return ret; 237 222 238 - return FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]); 223 + return acpm_pmic_to_linux_err(FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1])); 239 224 }