diff options
-rw-r--r-- | drivers/power/reset/reboot-mode.c | 43 | ||||
-rw-r--r-- | include/linux/reboot-mode.h | 1 |
2 files changed, 44 insertions, 0 deletions
diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c index 5992a2acd9..bf51c00aee 100644 --- a/drivers/power/reset/reboot-mode.c +++ b/drivers/power/reset/reboot-mode.c @@ -52,6 +52,46 @@ static int reboot_mode_add_param(struct device_d *dev, return PTR_ERR_OR_ZERO(param); } +static struct device_node *of_get_node_by_reproducible_name(struct device_node *dstroot, + struct device_node *srcnp) +{ + struct device_node *dstnp; + char *name; + + name = of_get_reproducible_name(srcnp); + dstnp = of_find_node_by_reproducible_name(dstroot, name); + free(name); + + return dstnp; +} + +static int of_reboot_mode_fixup(struct device_node *root, void *ctx) +{ + struct reboot_mode_driver *reboot = ctx; + struct device_node *dstnp, *srcnp, *dstparent; + + srcnp = reboot->dev->device_node; + dstnp = of_get_node_by_reproducible_name(root, srcnp); + + /* nothing to do when called on barebox-internal tree */ + if (srcnp == dstnp) + return 0; + + if (dstnp) { + dstparent = dstnp->parent; + of_delete_node(dstnp); + } else { + dstparent = of_get_node_by_reproducible_name(root, srcnp->parent); + } + + if (!dstparent) + return -EINVAL; + + of_copy_node(dstparent, srcnp); + + return 0; +} + static int reboot_mode_add_globalvar(void) { struct reboot_mode_driver *reboot = __boot_mode; @@ -59,6 +99,9 @@ static int reboot_mode_add_globalvar(void) if (!reboot) return 0; + if (!reboot->no_fixup) + of_register_fixup(of_reboot_mode_fixup, reboot); + return reboot_mode_add_param(&global_device, "system.reboot_mode.", reboot); } late_initcall(reboot_mode_add_globalvar); diff --git a/include/linux/reboot-mode.h b/include/linux/reboot-mode.h index 92a1da7b55..bc57f1d72d 100644 --- a/include/linux/reboot-mode.h +++ b/include/linux/reboot-mode.h @@ -11,6 +11,7 @@ struct reboot_mode_driver { struct device_d *dev; int (*write)(struct reboot_mode_driver *reboot, u32 magic); int priority; + bool no_fixup; /* filled by reboot_mode_register */ int reboot_mode_prev, reboot_mode_next; |