return ret;
 }
 
+#if defined(CONFIG_OF_DYNAMIC)
+static int venus_add_video_core(struct venus_core *core, const char *node_name,
+                               const char *compat)
+{
+       struct of_changeset *ocs = core->ocs;
+       struct device *dev = core->dev;
+       struct device_node *np, *enp;
+       int ret;
+
+       if (!node_name)
+               return 0;
+
+       enp = of_find_node_by_name(dev->of_node, node_name);
+       if (enp) {
+               of_node_put(enp);
+               return 0;
+       }
+
+       np = of_changeset_create_node(ocs, dev->of_node, node_name);
+       if (!np) {
+               dev_err(dev, "Unable to create new node\n");
+               return -ENODEV;
+       }
+
+       ret = of_changeset_add_prop_string(ocs, np, "compatible", compat);
+       if (ret)
+               dev_err(dev, "unable to add %s\n", compat);
+
+       of_node_put(np);
+
+       return ret;
+}
+
+static int venus_add_dynamic_nodes(struct venus_core *core)
+{
+       struct device *dev = core->dev;
+       int ret;
+
+       core->ocs = kmalloc(sizeof(*core->ocs), GFP_KERNEL);
+       if (!core->ocs)
+               return -ENOMEM;
+
+       of_changeset_init(core->ocs);
+
+       ret = venus_add_video_core(core, core->res->dec_nodename, "venus-decoder");
+       if (ret)
+               goto err;
+
+       ret = venus_add_video_core(core, core->res->enc_nodename, "venus-encoder");
+       if (ret)
+               goto err;
+
+       ret = of_changeset_apply(core->ocs);
+       if (ret) {
+               dev_err(dev, "applying changeset fail ret %d\n", ret);
+               goto err;
+       }
+
+       return 0;
+err:
+       of_changeset_destroy(core->ocs);
+       kfree(core->ocs);
+       core->ocs = NULL;
+       return ret;
+}
+
+static void venus_remove_dynamic_nodes(struct venus_core *core)
+{
+       if (core->ocs) {
+               of_changeset_revert(core->ocs);
+               of_changeset_destroy(core->ocs);
+               kfree(core->ocs);
+       }
+}
+#else
+static int venus_add_dynamic_nodes(struct venus_core *core)
+{
+       return 0;
+}
+
+static void venus_remove_dynamic_nodes(struct venus_core *core) {}
+#endif
+
 static int venus_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        if (ret < 0)
                goto err_runtime_disable;
 
+       if (core->res->dec_nodename || core->res->enc_nodename) {
+               ret = venus_add_dynamic_nodes(core);
+               if (ret)
+                       goto err_runtime_disable;
+       }
+
        ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
        if (ret)
-               goto err_runtime_disable;
+               goto err_remove_dynamic_nodes;
 
        ret = venus_firmware_init(core);
        if (ret)
        venus_firmware_deinit(core);
 err_of_depopulate:
        of_platform_depopulate(dev);
+err_remove_dynamic_nodes:
+       venus_remove_dynamic_nodes(core);
 err_runtime_disable:
        pm_runtime_put_noidle(dev);
        pm_runtime_disable(dev);
 
        venus_firmware_deinit(core);
 
+       venus_remove_dynamic_nodes(core);
+
        pm_runtime_put_sync(dev);
        pm_runtime_disable(dev);