From b1078c355d76769b5ddefc67d143fbd9b6e52c05 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 20 Sep 2018 13:41:52 +0200 Subject: of: base: Introduce of_alias_get_alias_list() to check alias IDs The function travels the lookup table to record alias ids for the given device match structures and alias stem. This function will be used by serial drivers to check if requested alias is allocated or free to use. Signed-off-by: Michal Simek Reviewed-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/of/base.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'drivers/of/base.c') diff --git a/drivers/of/base.c b/drivers/of/base.c index 74eaedd5b860..33011b88ed3f 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -16,6 +16,7 @@ #define pr_fmt(fmt) "OF: " fmt +#include #include #include #include @@ -1942,6 +1943,57 @@ int of_alias_get_id(struct device_node *np, const char *stem) } EXPORT_SYMBOL_GPL(of_alias_get_id); +/** + * of_alias_get_alias_list - Get alias list for the given device driver + * @matches: Array of OF device match structures to search in + * @stem: Alias stem of the given device_node + * @bitmap: Bitmap field pointer + * @nbits: Maximum number of alias ID which can be recorded it bitmap + * + * The function travels the lookup table to record alias ids for the given + * device match structures and alias stem. + * + * Return: 0 or -ENOSYS when !CONFIG_OF + */ +int of_alias_get_alias_list(const struct of_device_id *matches, + const char *stem, unsigned long *bitmap, + unsigned int nbits) +{ + struct alias_prop *app; + + /* Zero bitmap field to make sure that all the time it is clean */ + bitmap_zero(bitmap, nbits); + + mutex_lock(&of_mutex); + pr_debug("%s: Looking for stem: %s\n", __func__, stem); + list_for_each_entry(app, &aliases_lookup, link) { + pr_debug("%s: stem: %s, id: %d\n", + __func__, app->stem, app->id); + + if (strcmp(app->stem, stem) != 0) { + pr_debug("%s: stem comparison doesn't passed %s\n", + __func__, app->stem); + continue; + } + + if (app->id >= nbits) { + pr_debug("%s: ID %d greater then bitmap field %d\n", + __func__, app->id, nbits); + continue; + } + + if (of_match_node(matches, app->np)) { + pr_debug("%s: Allocated ID %d\n", __func__, app->id); + set_bit(app->id, bitmap); + } + /* Alias exist but it not compatible with matches */ + } + mutex_unlock(&of_mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(of_alias_get_alias_list); + /** * of_alias_get_highest_id - Get highest alias id for the given stem * @stem: Alias stem to be examined -- cgit v1.2.3 From 7acf79b6b2160540af87f47a55d7e3e5637ddeb5 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 8 Oct 2018 13:58:47 +0200 Subject: of: base: Fix english spelling in of_alias_get_alias_list() Fix english spelling in of_alias_get_alias_list(). Reported-by: Geert Uytterhoeven Reported-by: Randy Dunlap Fixes: b1078c355d76 ("of: base: Introduce of_alias_get_alias_list() to check alias IDs") Signed-off-by: Michal Simek Acked-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/of/base.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/of/base.c') diff --git a/drivers/of/base.c b/drivers/of/base.c index 33011b88ed3f..908de45f966b 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1948,7 +1948,7 @@ EXPORT_SYMBOL_GPL(of_alias_get_id); * @matches: Array of OF device match structures to search in * @stem: Alias stem of the given device_node * @bitmap: Bitmap field pointer - * @nbits: Maximum number of alias ID which can be recorded it bitmap + * @nbits: Maximum number of alias IDs which can be recorded in bitmap * * The function travels the lookup table to record alias ids for the given * device match structures and alias stem. @@ -1971,7 +1971,7 @@ int of_alias_get_alias_list(const struct of_device_id *matches, __func__, app->stem, app->id); if (strcmp(app->stem, stem) != 0) { - pr_debug("%s: stem comparison doesn't passed %s\n", + pr_debug("%s: stem comparison didn't pass %s\n", __func__, app->stem); continue; } @@ -1986,7 +1986,7 @@ int of_alias_get_alias_list(const struct of_device_id *matches, pr_debug("%s: Allocated ID %d\n", __func__, app->id); set_bit(app->id, bitmap); } - /* Alias exist but it not compatible with matches */ + /* Alias exists but is not compatible with matches */ } mutex_unlock(&of_mutex); -- cgit v1.2.3 From 59eaeba63a171127a90bb76187536ba66076af40 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 12 Oct 2018 07:43:11 +0200 Subject: of: base: Change logic in of_alias_get_alias_list() Check compatible string first before setting up bit in bitmap to also cover cases that allocated bitfield is not big enough. Show warning about it but let driver to continue to work with allocated bitfield to keep at least some devices (included console which is commonly close to serial0) to work. Fixes: b1078c355d76 ("of: base: Introduce of_alias_get_alias_list() to check alias IDs") Fixes: ae1cca3fa347 ("serial: uartps: Change uart ID port allocation") Signed-off-by: Michal Simek Reviewed-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/of/base.c | 22 ++++++++++++---------- drivers/tty/serial/xilinx_uartps.c | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) (limited to 'drivers/of/base.c') diff --git a/drivers/of/base.c b/drivers/of/base.c index 908de45f966b..6418205a05f5 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1953,13 +1953,15 @@ EXPORT_SYMBOL_GPL(of_alias_get_id); * The function travels the lookup table to record alias ids for the given * device match structures and alias stem. * - * Return: 0 or -ENOSYS when !CONFIG_OF + * Return: 0 or -ENOSYS when !CONFIG_OF or + * -EOVERFLOW if alias ID is greater then allocated nbits */ int of_alias_get_alias_list(const struct of_device_id *matches, const char *stem, unsigned long *bitmap, unsigned int nbits) { struct alias_prop *app; + int ret = 0; /* Zero bitmap field to make sure that all the time it is clean */ bitmap_zero(bitmap, nbits); @@ -1976,21 +1978,21 @@ int of_alias_get_alias_list(const struct of_device_id *matches, continue; } - if (app->id >= nbits) { - pr_debug("%s: ID %d greater then bitmap field %d\n", - __func__, app->id, nbits); - continue; - } - if (of_match_node(matches, app->np)) { pr_debug("%s: Allocated ID %d\n", __func__, app->id); - set_bit(app->id, bitmap); + + if (app->id >= nbits) { + pr_warn("%s: ID %d >= than bitmap field %d\n", + __func__, app->id, nbits); + ret = -EOVERFLOW; + } else { + set_bit(app->id, bitmap); + } } - /* Alias exists but is not compatible with matches */ } mutex_unlock(&of_mutex); - return 0; + return ret; } EXPORT_SYMBOL_GPL(of_alias_get_alias_list); diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index c3f6cce300aa..57c66d2c3471 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -1394,7 +1394,7 @@ static int cdns_get_id(struct platform_device *pdev) if (!alias_bitmap_initialized) { ret = of_alias_get_alias_list(cdns_uart_of_match, "serial", alias_bitmap, MAX_UART_INSTANCES); - if (ret) { + if (ret && ret != -EOVERFLOW) { mutex_unlock(&bitmap_lock); return ret; } -- cgit v1.2.3