diff options
Diffstat (limited to 'drivers/power/reset/reboot-mode.c')
-rw-r--r-- | drivers/power/reset/reboot-mode.c | 63 |
1 files changed, 32 insertions, 31 deletions
diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c index 01709e0019..7f940a2d88 100644 --- a/drivers/power/reset/reboot-mode.c +++ b/drivers/power/reset/reboot-mode.c @@ -12,8 +12,6 @@ #include <globalvar.h> #include <magicvar.h> -#define PREFIX "mode-" - static int __priority; static struct reboot_mode_driver *__boot_mode; @@ -25,7 +23,7 @@ static int reboot_mode_param_set(struct param_d *p, void *priv) return reboot->write(reboot, &reboot->magics[i]); } -static int reboot_mode_add_param(struct device_d *dev, +static int reboot_mode_add_param(struct device *dev, const char *prefix, struct reboot_mode_driver *reboot) { @@ -50,25 +48,12 @@ 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; + srcnp = reboot->dev->of_node; dstnp = of_get_node_by_reproducible_name(root, srcnp); if (dstnp) { @@ -111,6 +96,19 @@ static void reboot_mode_print(struct reboot_mode_driver *reboot, __pr_printk(7, "\n"); } +static const char *get_mode_name(const struct property *prop) +{ + unsigned prefix_len; + + prefix_len = str_has_prefix(prop->name, "mode-"); + if (!prefix_len) + prefix_len = str_has_prefix(prop->name, "barebox,mode-"); + if (!prefix_len) + return NULL; + + return prop->name + prefix_len; +} + /** * reboot_mode_register - register a reboot mode driver * @reboot: reboot mode driver @@ -122,8 +120,7 @@ int reboot_mode_register(struct reboot_mode_driver *reboot, const u32 *reboot_mode, size_t nelems) { struct property *prop; - struct device_node *np = reboot->dev->device_node; - size_t len = strlen(PREFIX); + struct device_node *np = reboot->dev->of_node; const char *alias; size_t nmodes = 0; int i = 0; @@ -132,7 +129,7 @@ int reboot_mode_register(struct reboot_mode_driver *reboot, for_each_property_of_node(np, prop) { u32 magic; - if (strncmp(prop->name, PREFIX, len)) + if (!get_mode_name(prop)) continue; if (of_property_read_u32(np, prop->name, &magic)) continue; @@ -142,8 +139,13 @@ int reboot_mode_register(struct reboot_mode_driver *reboot, reboot->nmodes = nmodes; reboot->nelems = nelems; - reboot->magics = xzalloc(nmodes * nelems * sizeof(u32)); - reboot->modes = xzalloc(nmodes * sizeof(const char *)); + + /* + * Allocate one entry more than necessary, because in the loop below + * we use an entry before we realize that the property is not valid. + */ + reboot->magics = xzalloc((nmodes + 1) * nelems * sizeof(u32)); + reboot->modes = xzalloc((nmodes + 1) * sizeof(const char *)); reboot_mode_print(reboot, "registering magic", reboot_mode); @@ -154,16 +156,9 @@ int reboot_mode_register(struct reboot_mode_driver *reboot, magic = &reboot->magics[i * nelems]; mode = &reboot->modes[i]; - if (strncmp(prop->name, PREFIX, len)) + *mode = get_mode_name(prop); + if (!*mode) continue; - - if (of_property_read_u32_array(np, prop->name, magic, nelems)) { - dev_err(reboot->dev, "reboot mode %s without magic number\n", - *mode); - continue; - } - - *mode = prop->name + len; if (*mode[0] == '\0') { ret = -EINVAL; dev_err(reboot->dev, "invalid mode name(%s): too short!\n", @@ -174,6 +169,12 @@ int reboot_mode_register(struct reboot_mode_driver *reboot, if (!strcmp(*mode, "normal")) normal = i; + if (of_property_read_u32_array(np, prop->name, magic, nelems)) { + dev_err(reboot->dev, "reboot mode %s without magic number\n", + *mode); + continue; + } + reboot_mode_print(reboot, *mode, magic); i++; |