Hi, On Wed, Mar 04, 2026 at 11:33:03PM +0530, Shivendra Pratap wrote: > reboot-mode based drivers can define a reboot-mode by adding it under > the reboot-mode node in device tree. This limits such drivers, to define > any predefined reboot-modes statically within the driver and creates a > dependency on device-tree. > > Introduce a list for predefined modes in the reboot-mode framework and > process the predefined reboot-modes along with the device-tree defined > reboot-modes. Modify existing reboot-mode based drivers to initialize > the predefined list-head as empty. > > This patch enables a reboot mode driver to define reboot-modes through a > predefined static list, in addition to the device-tree based reboot-modes. > > Signed-off-by: Shivendra Pratap > --- Reviewed-by: Sebastian Reichel -- Sebastian > drivers/power/reset/nvmem-reboot-mode.c | 1 + > drivers/power/reset/qcom-pon.c | 1 + > drivers/power/reset/reboot-mode.c | 28 ++++++++++++++++++++++------ > drivers/power/reset/syscon-reboot-mode.c | 1 + > include/linux/reboot-mode.h | 9 +++++++++ > 5 files changed, 34 insertions(+), 6 deletions(-) > > diff --git a/drivers/power/reset/nvmem-reboot-mode.c b/drivers/power/reset/nvmem-reboot-mode.c > index bd05d660490c686b43134f82f1eadd7665403d20..83a8d80fd7d1ccb1b736aee5f2d675246a63b8f8 100644 > --- a/drivers/power/reset/nvmem-reboot-mode.c > +++ b/drivers/power/reset/nvmem-reboot-mode.c > @@ -53,6 +53,7 @@ static int nvmem_reboot_mode_probe(struct platform_device *pdev) > > nvmem_rbm->reboot.dev = &pdev->dev; > nvmem_rbm->reboot.write = nvmem_reboot_mode_write; > + INIT_LIST_HEAD(&nvmem_rbm->reboot.predefined_modes); > > nvmem_rbm->cell = devm_nvmem_cell_get(&pdev->dev, "reboot-mode"); > if (IS_ERR(nvmem_rbm->cell)) { > diff --git a/drivers/power/reset/qcom-pon.c b/drivers/power/reset/qcom-pon.c > index 57b36e6186f80aff947fd7f5aae5ce280c65dc6b..9d0e3fc621a6173438c6da4cce38394199451881 100644 > --- a/drivers/power/reset/qcom-pon.c > +++ b/drivers/power/reset/qcom-pon.c > @@ -73,6 +73,7 @@ static int qcom_pon_probe(struct platform_device *pdev) > pon->reboot_mode.dev = &pdev->dev; > pon->reason_shift = reason_shift; > pon->reboot_mode.write = qcom_pon_reboot_mode_write; > + INIT_LIST_HEAD(&pon->reboot_mode.predefined_modes); > error = devm_reboot_mode_register(&pdev->dev, &pon->reboot_mode); > if (error) { > dev_err(&pdev->dev, "can't register reboot mode\n"); > diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c > index f5ab6eab210bcd9670441a4d2a301d9efdf2f322..a0cd463cad42cc08c55a9d1cc11174b513995104 100644 > --- a/drivers/power/reset/reboot-mode.c > +++ b/drivers/power/reset/reboot-mode.c > @@ -17,12 +17,6 @@ > > #define PREFIX "mode-" > > -struct mode_info { > - const char *mode; > - u64 magic; > - struct list_head list; > -}; > - > static u64 get_reboot_mode_magic(struct reboot_mode_driver *reboot, const char *cmd) > { > const char *normal = "normal"; > @@ -73,6 +67,7 @@ static int reboot_mode_notify(struct notifier_block *this, > */ > int reboot_mode_register(struct reboot_mode_driver *reboot) > { > + struct mode_info *info_predef; > struct mode_info *info; > struct property *prop; > struct device_node *np = reboot->dev->of_node; > @@ -82,6 +77,9 @@ int reboot_mode_register(struct reboot_mode_driver *reboot) > > INIT_LIST_HEAD(&reboot->head); > > + if (!np) > + goto predefined_modes; > + > for_each_property_of_node(np, prop) { > if (strncmp(prop->name, PREFIX, len)) > continue; > @@ -115,6 +113,24 @@ int reboot_mode_register(struct reboot_mode_driver *reboot) > list_add_tail(&info->list, &reboot->head); > } > > +predefined_modes: > + list_for_each_entry(info_predef, &reboot->predefined_modes, list) { > + info = kzalloc_obj(*info, GFP_KERNEL); > + if (!info) { > + ret = -ENOMEM; > + goto error; > + } > + > + info->mode = kstrdup_const(info_predef->mode, GFP_KERNEL); > + if (!info->mode) { > + ret = -ENOMEM; > + goto error; > + } > + > + info->magic = info_predef->magic; > + list_add_tail(&info->list, &reboot->head); > + } > + > reboot->reboot_notifier.notifier_call = reboot_mode_notify; > register_reboot_notifier(&reboot->reboot_notifier); > > diff --git a/drivers/power/reset/syscon-reboot-mode.c b/drivers/power/reset/syscon-reboot-mode.c > index 9f4b18c5e46f6a8bf197773ceceb80b250f57541..0218b71541a0cefe1534e306f956ae51ea9ee870 100644 > --- a/drivers/power/reset/syscon-reboot-mode.c > +++ b/drivers/power/reset/syscon-reboot-mode.c > @@ -48,6 +48,7 @@ static int syscon_reboot_mode_probe(struct platform_device *pdev) > syscon_rbm->reboot.dev = &pdev->dev; > syscon_rbm->reboot.write = syscon_reboot_mode_write; > syscon_rbm->mask = 0xffffffff; > + INIT_LIST_HEAD(&syscon_rbm->reboot.predefined_modes); > > syscon_rbm->map = syscon_node_to_regmap(pdev->dev.parent->of_node); > if (IS_ERR(syscon_rbm->map)) > diff --git a/include/linux/reboot-mode.h b/include/linux/reboot-mode.h > index 2ce189fdfff4b396d7cc6f175b30016781ae4fe9..f07696f9439063a04fc180e953114ea09475805c 100644 > --- a/include/linux/reboot-mode.h > +++ b/include/linux/reboot-mode.h > @@ -4,6 +4,7 @@ > > #include > #include > +#include > #include > > /* Construct 64-bit reboot magic: arg2 in upper 32 bits, arg1 in lower 32 */ > @@ -15,9 +16,17 @@ > /* Get 32 bit arg2 from 64 bit magic */ > #define REBOOT_MODE_ARG2(magic) FIELD_GET(GENMASK_ULL(63, 32), magic) > > +struct mode_info { > + const char *mode; > + u64 magic; > + struct list_head list; > +}; > + > struct reboot_mode_driver { > struct device *dev; > struct list_head head; > + /* List of predefined reboot-modes, a reboot-mode-driver may populate. */ > + struct list_head predefined_modes; > int (*write)(struct reboot_mode_driver *reboot, u64 magic); > struct notifier_block reboot_notifier; > }; > > -- > 2.34.1 >