[PATCH v10 01/10] power: reset: reboot-mode: Add device tree node-based registration

Shivendra Pratap posted 10 patches 2 months, 4 weeks ago
There is a newer version of this series
[PATCH v10 01/10] power: reset: reboot-mode: Add device tree node-based registration
Posted by Shivendra Pratap 2 months, 4 weeks ago
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
Re: [PATCH v10 01/10] power: reset: reboot-mode: Add device tree node-based registration
Posted by Dmitry Baryshkov 2 months, 3 weeks ago
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
Re: [PATCH v10 01/10] power: reset: reboot-mode: Add device tree node-based registration
Posted by Shivendra Pratap 2 months, 3 weeks ago

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;
>
Re: [PATCH v10 01/10] power: reset: reboot-mode: Add device tree node-based registration
Posted by kernel test robot 2 months, 4 weeks ago
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
Re: [PATCH v10 01/10] power: reset: reboot-mode: Add device tree node-based registration
Posted by kernel test robot 2 months, 4 weeks ago
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