[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251223-arm-psci-system_reset2-vendor-reboots-v18-1-32fa9e76efc3@oss.qualcomm.com>
Date: Tue, 23 Dec 2025 22:37:32 +0530
From: Shivendra Pratap <shivendra.pratap@....qualcomm.com>
To: Lorenzo Pieralisi <lpieralisi@...nel.org>, Arnd Bergmann <arnd@...db.de>,
Bjorn Andersson <andersson@...nel.org>,
Sebastian Reichel <sre@...nel.org>, Rob Herring <robh@...nel.org>,
Sudeep Holla <sudeep.holla@....com>,
Souvik Chakravarty <Souvik.Chakravarty@....com>,
Krzysztof Kozlowski <krzk+dt@...nel.org>,
Andy Yan <andy.yan@...k-chips.com>,
Bartosz Golaszewski <brgl@...nel.org>
Cc: Florian Fainelli <florian.fainelli@...adcom.com>,
Krzysztof Kozlowski <krzk@...nel.org>,
Dmitry Baryshkov <dmitry.baryshkov@....qualcomm.com>,
Mukesh Ojha <mukesh.ojha@....qualcomm.com>,
Andre Draszik <andre.draszik@...aro.org>,
Kathiravan Thirumoorthy <kathiravan.thirumoorthy@....qualcomm.com>,
linux-pm@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org, linux-arm-msm@...r.kernel.org,
Shivendra Pratap <shivendra.pratap@....qualcomm.com>,
Srinivas Kandagatla <srini@...nel.org>
Subject: [PATCH v18 01/10] power: reset: reboot-mode: Remove devres based
allocations
Devres APIs are intended for use in drivers, where the managed lifetime
of resources is tied directly to the driver attach/detach cycle. In
shared subsystem code, there is no guarantee that the subsystem
functions will only be called after a driver has been attached, nor that
they will not be referenced after the managed resources have been
released during driver detach.
To ensure correct lifetime handling, avoid using devres-based
allocations in the reboot-mode and explicitly handle allocation and
cleanup of resources.
Fixes: 4fcd504edbf7 ("power: reset: add reboot mode driver")
Signed-off-by: Shivendra Pratap <shivendra.pratap@....qualcomm.com>
---
drivers/power/reset/reboot-mode.c | 33 +++++++++++++++++++++------------
1 file changed, 21 insertions(+), 12 deletions(-)
diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c
index fba53f638da04655e756b5f8b7d2d666d1379535..4b6ae4007c4f6fb7d51520b4be2bf3cb1dff518e 100644
--- a/drivers/power/reset/reboot-mode.c
+++ b/drivers/power/reset/reboot-mode.c
@@ -3,6 +3,8 @@
* Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
*/
+#define pr_fmt(fmt) "reboot-mode: " fmt
+
#include <linux/device.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -71,9 +73,11 @@ static int reboot_mode_notify(struct notifier_block *this,
int reboot_mode_register(struct reboot_mode_driver *reboot)
{
struct mode_info *info;
+ struct mode_info *next;
struct property *prop;
struct device_node *np = reboot->dev->of_node;
size_t len = strlen(PREFIX);
+ u32 magic;
int ret;
INIT_LIST_HEAD(&reboot->head);
@@ -82,19 +86,17 @@ int reboot_mode_register(struct reboot_mode_driver *reboot)
if (strncmp(prop->name, PREFIX, len))
continue;
- info = devm_kzalloc(reboot->dev, sizeof(*info), GFP_KERNEL);
+ if (of_property_read_u32(np, prop->name, &magic)) {
+ pr_err("reboot mode %s without magic number\n", prop->name);
+ continue;
+ }
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
ret = -ENOMEM;
goto error;
}
- if (of_property_read_u32(np, prop->name, &info->magic)) {
- dev_err(reboot->dev, "reboot mode %s without magic number\n",
- info->mode);
- devm_kfree(reboot->dev, info);
- continue;
- }
-
info->mode = kstrdup_const(prop->name + len, GFP_KERNEL);
if (!info->mode) {
ret = -ENOMEM;
@@ -102,8 +104,7 @@ int reboot_mode_register(struct reboot_mode_driver *reboot)
} else if (info->mode[0] == '\0') {
kfree_const(info->mode);
ret = -EINVAL;
- dev_err(reboot->dev, "invalid mode name(%s): too short!\n",
- prop->name);
+ pr_err("invalid mode name(%s): too short!\n", prop->name);
goto error;
}
@@ -116,8 +117,12 @@ int reboot_mode_register(struct reboot_mode_driver *reboot)
return 0;
error:
- list_for_each_entry(info, &reboot->head, list)
+ kfree(info);
+ list_for_each_entry_safe(info, next, &reboot->head, list) {
+ list_del(&info->list);
kfree_const(info->mode);
+ kfree(info);
+ }
return ret;
}
@@ -130,11 +135,15 @@ EXPORT_SYMBOL_GPL(reboot_mode_register);
int reboot_mode_unregister(struct reboot_mode_driver *reboot)
{
struct mode_info *info;
+ struct mode_info *next;
unregister_reboot_notifier(&reboot->reboot_notifier);
- list_for_each_entry(info, &reboot->head, list)
+ list_for_each_entry_safe(info, next, &reboot->head, list) {
+ list_del(&info->list);
kfree_const(info->mode);
+ kfree(info);
+ }
return 0;
}
--
2.34.1
Powered by blists - more mailing lists