The reboot-mode driver does not have a strict requirement for
device-based registration. It primarily uses the device's of_node
to read mode-<cmd> properties and the device pointer for logging.
Remove the dependency on struct device and introduce support for
Device Tree (DT) node-based registration. This enables drivers
that are not associated with a struct device to leverage the
reboot-mode framework.
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
---
drivers/power/reset/reboot-mode.c | 23 +++++++++++++----------
include/linux/reboot-mode.h | 2 +-
2 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c
index fba53f638da04655e756b5f8b7d2d666d1379535..61f647b23959789a313f3af0bd967abcad45fa43 100644
--- a/drivers/power/reset/reboot-mode.c
+++ b/drivers/power/reset/reboot-mode.c
@@ -12,6 +12,7 @@
#include <linux/reboot-mode.h>
#define PREFIX "mode-"
+#define pr_fmt(fmt) "reboot-mode: " fmt
struct mode_info {
const char *mode;
@@ -65,14 +66,14 @@ static int reboot_mode_notify(struct notifier_block *this,
/**
* reboot_mode_register - register a reboot mode driver
* @reboot: reboot mode driver
+ * @np: Pointer to device tree node
*
* Returns: 0 on success or a negative error code on failure.
*/
-int reboot_mode_register(struct reboot_mode_driver *reboot)
+int reboot_mode_register(struct reboot_mode_driver *reboot, struct device_node *np)
{
struct mode_info *info;
struct property *prop;
- struct device_node *np = reboot->dev->of_node;
size_t len = strlen(PREFIX);
int ret;
@@ -82,16 +83,15 @@ 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);
+ 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);
+ pr_err("reboot mode %s without magic number\n", info->mode);
+ kfree(info);
continue;
}
@@ -102,8 +102,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;
}
@@ -130,11 +129,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) {
kfree_const(info->mode);
+ list_del(&info->list);
+ kfree(info);
+ }
return 0;
}
@@ -162,7 +165,7 @@ int devm_reboot_mode_register(struct device *dev,
if (!dr)
return -ENOMEM;
- rc = reboot_mode_register(reboot);
+ rc = reboot_mode_register(reboot, reboot->dev->of_node);
if (rc) {
devres_free(dr);
return rc;
diff --git a/include/linux/reboot-mode.h b/include/linux/reboot-mode.h
index 4a2abb38d1d612ec0fdf05eb18c98b210f631b7f..36f071f4b82e1fc255d8dd679a18e537655c3179 100644
--- a/include/linux/reboot-mode.h
+++ b/include/linux/reboot-mode.h
@@ -9,7 +9,7 @@ struct reboot_mode_driver {
struct notifier_block reboot_notifier;
};
-int reboot_mode_register(struct reboot_mode_driver *reboot);
+int reboot_mode_register(struct reboot_mode_driver *reboot, struct device_node *np);
int reboot_mode_unregister(struct reboot_mode_driver *reboot);
int devm_reboot_mode_register(struct device *dev,
struct reboot_mode_driver *reboot);
--
2.34.1
On Thu, Jul 10, 2025 at 02:45:43PM +0530, Shivendra Pratap wrote:
> The reboot-mode driver does not have a strict requirement for
> device-based registration. It primarily uses the device's of_node
> to read mode-<cmd> properties and the device pointer for logging.
>
> Remove the dependency on struct device and introduce support for
> Device Tree (DT) node-based registration. This enables drivers
> that are not associated with a struct device to leverage the
> reboot-mode framework.
>
> Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
> ---
> drivers/power/reset/reboot-mode.c | 23 +++++++++++++----------
> include/linux/reboot-mode.h | 2 +-
> 2 files changed, 14 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c
> index fba53f638da04655e756b5f8b7d2d666d1379535..61f647b23959789a313f3af0bd967abcad45fa43 100644
> --- a/drivers/power/reset/reboot-mode.c
> +++ b/drivers/power/reset/reboot-mode.c
> @@ -12,6 +12,7 @@
> #include <linux/reboot-mode.h>
>
> #define PREFIX "mode-"
> +#define pr_fmt(fmt) "reboot-mode: " fmt
This wasn't really tested. If I remember correctly, it should be defined
before the first include.
>
> struct mode_info {
> const char *mode;
--
With best wishes
Dmitry
On 7/15/2025 4:41 AM, Dmitry Baryshkov wrote:
> On Thu, Jul 10, 2025 at 02:45:43PM +0530, Shivendra Pratap wrote:
>> The reboot-mode driver does not have a strict requirement for
>> device-based registration. It primarily uses the device's of_node
>> to read mode-<cmd> properties and the device pointer for logging.
>>
>> Remove the dependency on struct device and introduce support for
>> Device Tree (DT) node-based registration. This enables drivers
>> that are not associated with a struct device to leverage the
>> reboot-mode framework.
>>
>> Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
>> ---
>> drivers/power/reset/reboot-mode.c | 23 +++++++++++++----------
>> include/linux/reboot-mode.h | 2 +-
>> 2 files changed, 14 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c
>> index fba53f638da04655e756b5f8b7d2d666d1379535..61f647b23959789a313f3af0bd967abcad45fa43 100644
>> --- a/drivers/power/reset/reboot-mode.c
>> +++ b/drivers/power/reset/reboot-mode.c
>> @@ -12,6 +12,7 @@
>> #include <linux/reboot-mode.h>
>>
>> #define PREFIX "mode-"
>> +#define pr_fmt(fmt) "reboot-mode: " fmt
>
> This wasn't really tested. If I remember correctly, it should be defined
> before the first include.
yes. fixing this in next patch.
>
>>
>> struct mode_info {
>> const char *mode;
>
Hi Shivendra,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 58ba80c4740212c29a1cf9b48f588e60a7612209]
url: https://github.com/intel-lab-lkp/linux/commits/Shivendra-Pratap/power-reset-reboot-mode-Add-device-tree-node-based-registration/20250710-172104
base: 58ba80c4740212c29a1cf9b48f588e60a7612209
patch link: https://lore.kernel.org/r/20250710-arm-psci-system_reset2-vendor-reboots-v10-1-b2d3b882be85%40oss.qualcomm.com
patch subject: [PATCH v10 01/10] power: reset: reboot-mode: Add device tree node-based registration
config: riscv-randconfig-002-20250711 (https://download.01.org/0day-ci/archive/20250711/202507111052.smU9DwLS-lkp@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 12.4.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250711/202507111052.smU9DwLS-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202507111052.smU9DwLS-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/power/reset/reboot-mode.c:15: warning: "pr_fmt" redefined
15 | #define pr_fmt(fmt) "reboot-mode: " fmt
|
In file included from include/asm-generic/bug.h:28,
from arch/riscv/include/asm/bug.h:83,
from include/linux/bug.h:5,
from arch/riscv/include/asm/current.h:13,
from include/linux/sched.h:12,
from include/linux/ratelimit.h:6,
from include/linux/dev_printk.h:16,
from include/linux/device.h:15,
from drivers/power/reset/reboot-mode.c:6:
include/linux/printk.h:397: note: this is the location of the previous definition
397 | #define pr_fmt(fmt) fmt
|
vim +/pr_fmt +15 drivers/power/reset/reboot-mode.c
13
14 #define PREFIX "mode-"
> 15 #define pr_fmt(fmt) "reboot-mode: " fmt
16
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Shivendra,
kernel test robot noticed the following build errors:
[auto build test ERROR on 58ba80c4740212c29a1cf9b48f588e60a7612209]
url: https://github.com/intel-lab-lkp/linux/commits/Shivendra-Pratap/power-reset-reboot-mode-Add-device-tree-node-based-registration/20250710-172104
base: 58ba80c4740212c29a1cf9b48f588e60a7612209
patch link: https://lore.kernel.org/r/20250710-arm-psci-system_reset2-vendor-reboots-v10-1-b2d3b882be85%40oss.qualcomm.com
patch subject: [PATCH v10 01/10] power: reset: reboot-mode: Add device tree node-based registration
config: i386-buildonly-randconfig-006-20250711 (https://download.01.org/0day-ci/archive/20250711/202507110849.ahNmViin-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250711/202507110849.ahNmViin-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202507110849.ahNmViin-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
>> drivers/power/reset/reboot-mode.c:15:9: warning: 'pr_fmt' macro redefined [-Wmacro-redefined]
15 | #define pr_fmt(fmt) "reboot-mode: " fmt
| ^
include/linux/printk.h:397:9: note: previous definition is here
397 | #define pr_fmt(fmt) fmt
| ^
>> drivers/power/reset/reboot-mode.c:86:10: error: call to undeclared function 'kzalloc'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
86 | info = kzalloc(sizeof(*info), GFP_KERNEL);
| ^
>> drivers/power/reset/reboot-mode.c:86:8: error: incompatible integer to pointer conversion assigning to 'struct mode_info *' from 'int' [-Wint-conversion]
86 | info = kzalloc(sizeof(*info), GFP_KERNEL);
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/power/reset/reboot-mode.c:94:4: error: call to undeclared function 'kfree'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
94 | kfree(info);
| ^
drivers/power/reset/reboot-mode.c:139:3: error: call to undeclared function 'kfree'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
139 | kfree(info);
| ^
1 warning and 4 errors generated.
vim +/kzalloc +86 drivers/power/reset/reboot-mode.c
13
14 #define PREFIX "mode-"
> 15 #define pr_fmt(fmt) "reboot-mode: " fmt
16
17 struct mode_info {
18 const char *mode;
19 u32 magic;
20 struct list_head list;
21 };
22
23 static unsigned int get_reboot_mode_magic(struct reboot_mode_driver *reboot,
24 const char *cmd)
25 {
26 const char *normal = "normal";
27 struct mode_info *info;
28 char cmd_[110];
29
30 if (!cmd)
31 cmd = normal;
32
33 list_for_each_entry(info, &reboot->head, list)
34 if (!strcmp(info->mode, cmd))
35 return info->magic;
36
37 /* try to match again, replacing characters impossible in DT */
38 if (strscpy(cmd_, cmd, sizeof(cmd_)) == -E2BIG)
39 return 0;
40
41 strreplace(cmd_, ' ', '-');
42 strreplace(cmd_, ',', '-');
43 strreplace(cmd_, '/', '-');
44
45 list_for_each_entry(info, &reboot->head, list)
46 if (!strcmp(info->mode, cmd_))
47 return info->magic;
48
49 return 0;
50 }
51
52 static int reboot_mode_notify(struct notifier_block *this,
53 unsigned long mode, void *cmd)
54 {
55 struct reboot_mode_driver *reboot;
56 unsigned int magic;
57
58 reboot = container_of(this, struct reboot_mode_driver, reboot_notifier);
59 magic = get_reboot_mode_magic(reboot, cmd);
60 if (magic)
61 reboot->write(reboot, magic);
62
63 return NOTIFY_DONE;
64 }
65
66 /**
67 * reboot_mode_register - register a reboot mode driver
68 * @reboot: reboot mode driver
69 * @np: Pointer to device tree node
70 *
71 * Returns: 0 on success or a negative error code on failure.
72 */
73 int reboot_mode_register(struct reboot_mode_driver *reboot, struct device_node *np)
74 {
75 struct mode_info *info;
76 struct property *prop;
77 size_t len = strlen(PREFIX);
78 int ret;
79
80 INIT_LIST_HEAD(&reboot->head);
81
82 for_each_property_of_node(np, prop) {
83 if (strncmp(prop->name, PREFIX, len))
84 continue;
85
> 86 info = kzalloc(sizeof(*info), GFP_KERNEL);
87 if (!info) {
88 ret = -ENOMEM;
89 goto error;
90 }
91
92 if (of_property_read_u32(np, prop->name, &info->magic)) {
93 pr_err("reboot mode %s without magic number\n", info->mode);
> 94 kfree(info);
95 continue;
96 }
97
98 info->mode = kstrdup_const(prop->name + len, GFP_KERNEL);
99 if (!info->mode) {
100 ret = -ENOMEM;
101 goto error;
102 } else if (info->mode[0] == '\0') {
103 kfree_const(info->mode);
104 ret = -EINVAL;
105 pr_err("invalid mode name(%s): too short!\n", prop->name);
106 goto error;
107 }
108
109 list_add_tail(&info->list, &reboot->head);
110 }
111
112 reboot->reboot_notifier.notifier_call = reboot_mode_notify;
113 register_reboot_notifier(&reboot->reboot_notifier);
114
115 return 0;
116
117 error:
118 list_for_each_entry(info, &reboot->head, list)
119 kfree_const(info->mode);
120
121 return ret;
122 }
123 EXPORT_SYMBOL_GPL(reboot_mode_register);
124
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
© 2016 - 2026 Red Hat, Inc.