From d53da57eb3dc95062a73559f9e886f72031d1b03 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Sun, 3 Apr 2016 19:52:38 +0530 Subject: [PATCH] plugin-manager: Add support for partial and GE match Currently the matching of board ID on board is done with exact match. Add support for partial and >=fab ID support. Partial match: ============== If matching string start with '^' or having the '*' in id string then apply partial match with board ID based on how string provided. Example: Suppose Board ID is 3310-1000-100, then the matching is done by saying ^3310-1000, 3310-1000-*, 3310-* etc. ^3310-1000 or 3310-1000-* means all fab ID of 3310-1000-, 3310-* means all SKU and fab ID of 3310. Greater than-equal to match: =========================== If matching string start with ">=" then it is applied for all board of same type of module having fab ID >= sting fab ID. Example: ">=3310-1000-100" means all fab 3310-1000-100 and later like 3310-1000-200, 3310-1000-300 etc. bug 1750159 Change-Id: I1223d7c8add653cd54505e0d98693f72a5c3c824 Signed-off-by: Laxman Dewangan Reviewed-on: http://git-master/r/1119438 (cherry picked from commit d3a7f2399b1617a61f7cf2d5abb159ecf6fbf44d from dev-kernel-3.18 in linux-3.18) Reviewed-on: http://git-master/r/1120768 (cherry picked from commit b0cb5e66ed570cf06ee3560fcf616930ba61cbf9) Reviewed-on: http://git-master/r/1128341 Reviewed-by: Bibek Basu Tested-by: Bibek Basu Reviewed-by: Winnie Hsu --- drivers/of/plugin-manager.c | 104 +++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/drivers/of/plugin-manager.c b/drivers/of/plugin-manager.c index 440031f5947..2017aeb9946 100644 --- a/drivers/of/plugin-manager.c +++ b/drivers/of/plugin-manager.c @@ -21,6 +21,12 @@ #include #include +enum plugin_manager_match_type { + PLUGIN_MANAGER_MATCH_EXACT, + PLUGIN_MANAGER_MATCH_PARTIAL, + PLUGIN_MANAGER_MATCH_GE, +}; + static struct property *__of_copy_property(const struct property *prop, gfp_t flags) { @@ -106,6 +112,102 @@ static int __init update_target_node_from_overlay( return 0; } +static int plugin_manager_get_fabid(const char *id_str) +{ + int fabid = 0; + int i; + + if (strlen(id_str) < 13) + return -EINVAL; + + for (i = 0; i < 3; ++i) { + if ((id_str[10 + i] >= '0') && (id_str[10 + i] <= '9')) + fabid = fabid * 10 + id_str[10 + i] - '0'; + else + return -EINVAL; + } + + return fabid; +} + +static bool plugin_manager_match_id(struct device_node *np, const char *id_name) +{ + struct property *prop; + const char *in_str = id_name; + int match_type = PLUGIN_MANAGER_MATCH_EXACT; + int valid_str_len = strlen(id_name); + int fabid = 0, prop_fabid; + int i; + + if ((valid_str_len > 2) && (in_str[0] == '>') && (in_str[1] == '=')) { + in_str += 2; + valid_str_len -= 2; + match_type = PLUGIN_MANAGER_MATCH_GE; + goto match_type_done; + } + + if ((valid_str_len > 1) && (in_str[0] == '^')) { + in_str += 1; + valid_str_len -= 1; + match_type = PLUGIN_MANAGER_MATCH_PARTIAL; + goto match_type_done; + } + + for (i = 0; i < valid_str_len; ++i) { + if (in_str[i] == '*') { + valid_str_len = i; + match_type = PLUGIN_MANAGER_MATCH_PARTIAL; + break; + } + } + +match_type_done: + if (match_type == PLUGIN_MANAGER_MATCH_GE) { + fabid = plugin_manager_get_fabid(in_str); + if (fabid < 0) + return false; + } + + for_each_property_of_node(np, prop) { + /* Skip those we do not want to proceed */ + if (!strcmp(prop->name, "name") || + !strcmp(prop->name, "phandle") || + !strcmp(prop->name, "linux,phandle")) + continue; + switch (match_type) { + case PLUGIN_MANAGER_MATCH_EXACT: + if (strlen(prop->name) != valid_str_len) + break; + if (!memcmp(in_str, prop->name, valid_str_len)) + return true; + break; + + case PLUGIN_MANAGER_MATCH_PARTIAL: + if (strlen(prop->name) < valid_str_len) + break; + if (!memcmp(in_str, prop->name, valid_str_len)) + return true; + break; + + case PLUGIN_MANAGER_MATCH_GE: + if (strlen(prop->name) < 13) + break; + if (memcmp(in_str, prop->name, 10)) + break; + prop_fabid = plugin_manager_get_fabid(prop->name); + if (prop_fabid < 0) + break; + if (prop_fabid >= fabid) + return true; + break; + default: + break; + } + } + + return false; +} + static int __init update_target_node(struct device_node *target, struct device_node *overlay) { @@ -172,7 +274,7 @@ static int __init parse_fragment(struct device_node *np) if ((board_count > 0) && board_np) { of_property_for_each_string(np, "ids", prop, bname) { - found = of_property_read_bool(board_np, bname); + found = plugin_manager_match_id(board_np, bname); if (found) { pr_info("node %s match with board %s\n", np->full_name, bname); -- 2.39.2