return 0;
}
-static int __init parse_fragment(struct device_node *np)
+static int update_target_node(struct device_node *target,
+ struct device_node *overlay)
{
struct device_node *tchild, *ochild;
- struct device_node *board_np, *overlay, *target;
+ int ret;
+
+ ret = update_target_node_from_overlay(target, overlay);
+ if (ret < 0) {
+ pr_err("Target %s update with overlay %s failed: %d\n",
+ target->name, overlay->name, ret);
+ return ret;
+ }
+
+ for_each_child_of_node(overlay, ochild) {
+ tchild = of_get_child_by_name(target, ochild->name);
+ if (!tchild) {
+ pr_err("Overlay child %s not found on target %s\n",
+ ochild->full_name, tchild->full_name);
+ continue;
+ }
+
+ ret = update_target_node(tchild, ochild);
+ if (ret < 0) {
+ pr_err("Target %s update with overlay %s failed: %d\n",
+ tchild->name, ochild->name, ret);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static int __init parse_fragment(struct device_node *np)
+{
+ struct device_node *board_np, *odm_np, *overlay, *target, *cnp;
const char *bname;
struct property *prop;
int board_count;
+ int odm_count;
+ int nchild;
bool found = false;
int ret;
- overlay = of_get_child_by_name(np, "_overlay_");
- if (!overlay) {
- pr_err("Node %s does not have Overlay\n", np->name);
+ board_count = of_property_count_strings(np, "ids");
+ odm_count = of_property_count_strings(np, "odm-data");
+ if ((board_count <= 0) && (odm_count <= 0)) {
+ pr_err("Node %s does not have property ids and odm data\n",
+ np->name);
return -EINVAL;
}
- board_count = of_property_count_strings(np, "board-ids");
- if (!board_count) {
- pr_err("Node %s does not have property board-ids\n", np->name);
+ nchild = of_get_child_count(np);
+ if (!nchild) {
+ pr_err("Node %s does not have Overlay child\n", np->name);
return -EINVAL;
}
- target = of_parse_phandle(np, "target", 0);
- if (!target) {
- pr_err("Node %s does not have targer node\n", np->name);
+ /* Match the IDs or odm data */
+ board_np = of_find_node_by_path("/chosen/plugin-manager/ids");
+ odm_np = of_find_node_by_path("/chosen/plugin-manager/odm-data");
+ if (!board_np && !odm_np) {
+ pr_err("chosen/plugin-manager does'nt have ids and odm-data\n");
return -EINVAL;
}
- board_np = of_find_node_by_path("/chosen/board-id");
- if (!board_np) {
- pr_err("Chosen node does not have Board-id listed\n");
- return -EINVAL;
+ if ((board_count > 0) && board_np) {
+ of_property_for_each_string(np, "ids", prop, bname) {
+ found = of_property_read_bool(board_np, bname);
+ if (found) {
+ pr_info("node %s match with board %s\n",
+ np->full_name, bname);
+ break;
+ }
+ }
}
- of_property_for_each_string(np, "board-ids", prop, bname) {
- found = of_property_read_bool(board_np, bname);
- if (found) {
- pr_info("node %s match with board %s\n",
- np->full_name, bname);
- break;
+ if (!found && (odm_count > 0) && odm_np) {
+ of_property_for_each_string(np, "odm-data", prop, bname) {
+ found = of_property_read_bool(odm_np, bname);
+ if (found) {
+ pr_info("node %s match with odm-data %s\n",
+ np->full_name, bname);
+ break;
+ }
}
}
+
if (!found)
return 0;
- ret = update_target_node_from_overlay(target, overlay);
- if (ret < 0) {
- pr_err("Target %s update with overlay %s failed: %d\n",
- target->name, overlay->name, ret);
- return ret;
- }
+ for_each_child_of_node(np, cnp) {
+ target = of_parse_phandle(cnp, "target", 0);
+ if (!target) {
+ pr_err("Node %s does not have targer node\n",
+ cnp->name);
+ continue;
+ }
- for_each_child_of_node(overlay, ochild) {
- tchild = of_get_child_by_name(target, ochild->name);
- if (!tchild) {
- pr_err("Overlay child %s not found on target %s\n",
- ochild->full_name, tchild->full_name);
+ overlay = of_get_child_by_name(cnp, "_overlay_");
+ if (!overlay) {
+ pr_err("Node %s does not have Overlay\n", cnp->name);
continue;
}
- ret = update_target_node_from_overlay(tchild, ochild);
+ ret = update_target_node(target, overlay);
if (ret < 0) {
pr_err("Target %s update with overlay %s failed: %d\n",
- tchild->name, ochild->name, ret);
- return ret;
+ target->name, overlay->name, ret);
+ continue;
}
}
return 0;
static int __init plugin_manager_init(void)
{
- struct device_node *root;
struct device_node *pm_node;
struct device_node *child;
int ret;
pr_info("Initializing plugin-manager\n");
- root = of_find_node_by_path("/");
- if (!root) {
- pr_info("Root node not found\n");
+ pm_node = of_find_node_by_path("/plugin-manager");
+ if (!pm_node) {
+ pr_info("Plugin-manager not available\n");
return 0;
}
- pm_node = of_find_node_by_name(root, "plugin-manager");
- if (!pm_node) {
- pr_info("Plugin-manager not available\n");
+ if (!of_device_is_available(pm_node)) {
+ pr_info("Plugin-manager status disabled\n");
return 0;
}
for_each_child_of_node(pm_node, child) {
+ if (!of_device_is_available(child)) {
+ pr_info("Plugin-manager child %s status disabled\n",
+ child->name);
+ continue;
+ }
ret = parse_fragment(child);
if (ret < 0)
pr_err("Error in parsing node %s: %d\n",