summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Koskovich <AKoskovich@pm.me>2025-12-14 22:16:18 +0300
committerSebastian Reichel <sebastian.reichel@collabora.com>2026-01-12 04:52:31 +0300
commit36b05629226413836cfbb3fbe6689cd188bca156 (patch)
treed93fbc7d005b1cbd1a064f3bb4c4e4b712305e81
parent8d59cf3887fbabacef53bfba473e33e8a8d9d07b (diff)
downloadlinux-36b05629226413836cfbb3fbe6689cd188bca156.tar.xz
power: reset: nvmem-reboot-mode: respect cell size for nvmem_cell_write
Some platforms expose reboot mode cells that are smaller than an unsigned int, in which cases lead to write failures. Read the cell first to determine actual size and only write the number of bytes the cell can hold. Fixes: 7a78a7f7695b ("power: reset: nvmem-reboot-mode: use NVMEM as reboot mode write interface") Signed-off-by: Alexander Koskovich <akoskovich@pm.me> Link: https://patch.msgid.link/20251214191529.2470580-1-akoskovich@pm.me Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
-rw-r--r--drivers/power/reset/nvmem-reboot-mode.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/power/reset/nvmem-reboot-mode.c b/drivers/power/reset/nvmem-reboot-mode.c
index 41530b70cfc4..d260715fccf6 100644
--- a/drivers/power/reset/nvmem-reboot-mode.c
+++ b/drivers/power/reset/nvmem-reboot-mode.c
@@ -10,6 +10,7 @@
#include <linux/nvmem-consumer.h>
#include <linux/platform_device.h>
#include <linux/reboot-mode.h>
+#include <linux/slab.h>
struct nvmem_reboot_mode {
struct reboot_mode_driver reboot;
@@ -19,12 +20,22 @@ struct nvmem_reboot_mode {
static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot,
unsigned int magic)
{
- int ret;
struct nvmem_reboot_mode *nvmem_rbm;
+ size_t buf_len;
+ void *buf;
+ int ret;
nvmem_rbm = container_of(reboot, struct nvmem_reboot_mode, reboot);
- ret = nvmem_cell_write(nvmem_rbm->cell, &magic, sizeof(magic));
+ buf = nvmem_cell_read(nvmem_rbm->cell, &buf_len);
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+ kfree(buf);
+
+ if (buf_len > sizeof(magic))
+ return -EINVAL;
+
+ ret = nvmem_cell_write(nvmem_rbm->cell, &magic, buf_len);
if (ret < 0)
dev_err(reboot->dev, "update reboot mode bits failed\n");