mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-28 04:03:23 -04:00
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.
To ensure correct lifetime handling, avoid using devres-based
allocations in the reboot-mode and explicitly handle allocation and
cleanup of resources.
Fixes: cfaf0a9078 ("power: reset: reboot-mode: Expose sysfs for registered reboot_modes")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202607191025.h6bQp891-lkp@intel.com/
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
Link: https://patch.msgid.link/20260724-arm-psci-system_reset2-vendor-reboots-v24-1-ed5125785ef6@oss.qualcomm.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
This commit is contained in:
committed by
Sebastian Reichel
parent
657cd3a42e
commit
42326d5939
@@ -10,6 +10,7 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/reboot-mode.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -168,10 +169,11 @@ static int reboot_mode_create_device(struct reboot_mode_driver *reboot)
|
||||
*/
|
||||
int reboot_mode_register(struct reboot_mode_driver *reboot)
|
||||
{
|
||||
struct mode_info *info;
|
||||
struct mode_info *info = NULL;
|
||||
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);
|
||||
@@ -180,22 +182,22 @@ 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 (device_property_read_u32(reboot->dev, prop->name, &magic)) {
|
||||
dev_dbg(reboot->dev, "reboot mode %s without magic number\n",
|
||||
prop->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
info = kzalloc_obj(*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->magic = magic;
|
||||
info->mode = kstrdup_const(prop->name + len, GFP_KERNEL);
|
||||
if (!info->mode) {
|
||||
ret = -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
} else if (info->mode[0] == '\0') {
|
||||
kfree_const(info->mode);
|
||||
@@ -206,6 +208,7 @@ int reboot_mode_register(struct reboot_mode_driver *reboot)
|
||||
}
|
||||
|
||||
list_add_tail(&info->list, &reboot->head);
|
||||
info = NULL;
|
||||
}
|
||||
|
||||
reboot->reboot_notifier.notifier_call = reboot_mode_notify;
|
||||
@@ -218,6 +221,7 @@ int reboot_mode_register(struct reboot_mode_driver *reboot)
|
||||
return 0;
|
||||
|
||||
error:
|
||||
kfree(info);
|
||||
reboot_mode_unregister(reboot);
|
||||
return ret;
|
||||
}
|
||||
@@ -261,12 +265,16 @@ static inline void reboot_mode_unregister_device(struct reboot_mode_driver *rebo
|
||||
int reboot_mode_unregister(struct reboot_mode_driver *reboot)
|
||||
{
|
||||
struct mode_info *info;
|
||||
struct mode_info *next;
|
||||
|
||||
unregister_reboot_notifier(&reboot->reboot_notifier);
|
||||
reboot_mode_unregister_device(reboot);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user