int engine_register(struct engine *engine, const char *name, const char *precedence, const char* ref) { if (engine == NULL || name == NULL) { return kr_error(EINVAL); } /* Make sure module is unloaded */ (void) engine_unregister(engine, name); /* Find the index of referenced module. */ module_array_t *mod_list = &engine->modules; size_t ref_pos = mod_list->len; if (precedence && ref) { ref_pos = module_find(mod_list, ref); if (ref_pos >= mod_list->len) { return kr_error(EIDRM); } } /* Attempt to load binary module */ struct kr_module *module = malloc(sizeof(*module)); if (!module) { return kr_error(ENOMEM); } module->data = engine; int ret = kr_module_load(module, name, NULL); /* Load Lua module if not a binary */ if (ret == kr_error(ENOENT)) { ret = ffimodule_register_lua(engine, module, name); } if (ret != 0) { free(module); return ret; } if (array_push(engine->modules, module) < 0) { engine_unload(engine, module); return kr_error(ENOMEM); } /* Evaluate precedence operator */ if (precedence) { struct kr_module **arr = mod_list->at; size_t emplacement = mod_list->len; if (strcasecmp(precedence, ">") == 0) { if (ref_pos + 1 < mod_list->len) emplacement = ref_pos + 1; /* Insert after target */ } if (strcasecmp(precedence, "<") == 0) { emplacement = ref_pos; /* Insert at target */ } /* Move the tail if it has some elements. */ if (emplacement + 1 < mod_list->len) { memmove(&arr[emplacement + 1], &arr[emplacement], sizeof(*arr) * (mod_list->len - (emplacement + 1))); arr[emplacement] = module; } } /* Register properties */ if (module->props || module->config) { return register_properties(engine, module); } return kr_ok(); }
static int ioctl_engine_close(struct drm_device *dev, void *data, struct drm_file *file) { struct dce_file_priv *priv = omap_drm_file_priv(file, dce_mapper_id); struct drm_omap_dce_engine_close *arg = data; uint32_t engine; int ret; ret = engine_get(priv, arg->eng_handle, &engine); if (ret) return ret; engine_unregister(priv, arg->eng_handle); return engine_close(priv, engine); }
/** Unload module. */ static int mod_unload(lua_State *L) { /* Check parameters */ int n = lua_gettop(L); if (n != 1 || !lua_isstring(L, 1)) { format_error(L, "expected 'unload(string name)'"); lua_error(L); } /* Unload engine module */ struct engine *engine = engine_luaget(L); int ret = engine_unregister(engine, lua_tostring(L, 1)); if (ret != 0) { format_error(L, kr_strerror(ret)); lua_error(L); } lua_pushboolean(L, 1); return 1; }
static int dce_release(struct drm_device *dev, struct drm_file *file) { struct dce_file_priv *priv = omap_drm_file_priv(file, dce_mapper_id); int i; // XXX not sure if this is legit.. maybe we end up with this scenario // when drm device file is opened prior to dce module being loaded?? WARN_ON(!priv); if (!priv) return 0; /* cleanup any remaining codecs and engines on behalf of the process, * in case the process crashed or didn't clean up properly for itself: */ for (i = 0; i < ARRAY_SIZE(priv->codecs); i++) { uint32_t codec = priv->codecs[i].codec; if (codec) { enum omap_dce_codec codec_id = priv->codecs[i].codec_id; codec_unregister(priv, i+1); codec_delete(priv, codec, codec_id); } } for (i = 0; i < ARRAY_SIZE(priv->engines); i++) { uint32_t engine = priv->engines[i].engine; if (engine) { engine_unregister(priv, i+1); engine_close(priv, engine); } } for (i = 0; i < ARRAY_SIZE(txns); i++) { if (txns[i].priv == priv) { txn_cleanup(&txns[i]); memset(&txns[i], 0, sizeof(txns[i])); } } kfree(priv); return 0; }