Currently the list of aliases is not updated when an overlay that modifies /aliases is added or removed. This breaks drivers (e.g. serial) that rely on of_alias_get_id(). Update the list of aliases when a property of the /aliases node is added, removed, or updated by registering a notifier. Co-developed-by: Geert Uytterhoeven <geert@xxxxxxxxxxxxxx> Signed-off-by: Geert Uytterhoeven <geert@xxxxxxxxxxxxxx> Signed-off-by: Ayush Singh <ayush@xxxxxxxxxxxxxxx> --- drivers/of/base.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/of/base.c b/drivers/of/base.c index 1cfb3cd4493e17d16868981288115798c6a6a151..5c061fdca885973d4389c0f6afe459a751d850b8 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -235,11 +235,50 @@ static void of_alias_destroy(const char *name, void (*dt_free)(void *)) } } +static void *alias_alloc(u64 size, u64 align) +{ + return kzalloc(size, GFP_KERNEL); +} + +static void alias_free(void *p) +{ + /* Leak memory */ +} + +static int alias_OF_notifier(struct notifier_block *np, unsigned long action, + void *data) +{ + struct of_reconfig_data *reconf_data = data; + + if (reconf_data->dn != of_aliases) + return NOTIFY_DONE; + + switch (action) { + case OF_RECONFIG_ADD_PROPERTY: + of_alias_create(reconf_data->prop, alias_alloc); + break; + case OF_RECONFIG_REMOVE_PROPERTY: + of_alias_destroy(reconf_data->prop->name, alias_free); + break; + case OF_RECONFIG_UPDATE_PROPERTY: + of_alias_destroy(reconf_data->old_prop->name, alias_free); + of_alias_create(reconf_data->prop, alias_alloc); + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block alias_of_nb = { + .notifier_call = alias_OF_notifier, +}; + void __init of_core_init(void) { struct device_node *np; of_platform_register_reconfig_notifier(); + of_reconfig_notifier_register(&alias_of_nb); /* Create the kset, and register existing nodes */ mutex_lock(&of_mutex); -- 2.47.0