Beispiel #1
0
/**
 * ipa_rm_dep_graph_delete_dependency() - deleted dependency between
 *				two nodes in graph
 * @graph: [in] dependency graph
 * @resource_name: [in] resource to delete
 * @depends_on_name: [in] resource to delete
 *
 * Returns: 0 on success, negative on failure
 *
 */
int ipa_rm_dep_graph_delete_dependency(struct ipa_rm_dep_graph *graph,
				enum ipa_rm_resource_name resource_name,
				enum ipa_rm_resource_name depends_on_name)
{
	struct ipa_rm_resource *dependant = NULL;
	struct ipa_rm_resource *dependency = NULL;
	int result;
	if (!graph ||
		!IPA_RM_RESORCE_IS_PROD(resource_name) ||
		!IPA_RM_RESORCE_IS_CONS(depends_on_name)) {
		result = -EINVAL;
		goto bail;
	}
	if (ipa_rm_dep_graph_get_resource(graph,
					  resource_name,
					  &dependant)) {
		result = -EINVAL;
		goto bail;
	}
	if (ipa_rm_dep_graph_get_resource(graph,
					  depends_on_name,
					  &dependency)) {
		result = -EINVAL;
		goto bail;
	}
	result = ipa_rm_resource_delete_dependency(dependant, dependency);
bail:
	return result;
}
static void ipa_rm_wq_handler(struct work_struct *work)
{
	struct ipa_rm_resource *resource;
	struct ipa_rm_wq_work_type *ipa_rm_work =
			container_of(work,
					struct ipa_rm_wq_work_type,
					work);
	IPA_RM_DBG("%s cmd=%d event=%d notify_registered_only=%d\n",
		ipa_rm_resource_str(ipa_rm_work->resource_name),
		ipa_rm_work->wq_cmd,
		ipa_rm_work->event,
		ipa_rm_work->notify_registered_only);
	switch (ipa_rm_work->wq_cmd) {
	case IPA_RM_WQ_NOTIFY_PROD:
		if (!IPA_RM_RESORCE_IS_PROD(ipa_rm_work->resource_name)) {
			IPA_RM_ERR("resource is not PROD\n");
			return;
		}
		read_lock(&ipa_rm_ctx->lock);
		if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
						ipa_rm_work->resource_name,
						&resource) != 0){
			IPA_RM_ERR("resource does not exists\n");
			read_unlock(&ipa_rm_ctx->lock);
			return;
		}
		ipa_rm_resource_producer_notify_clients(
				(struct ipa_rm_resource_prod *)resource,
				ipa_rm_work->event,
				ipa_rm_work->notify_registered_only);
		read_unlock(&ipa_rm_ctx->lock);
		break;
	case IPA_RM_WQ_NOTIFY_CONS:
		break;
	case IPA_RM_WQ_RESOURCE_CB:
		read_lock(&ipa_rm_ctx->lock);
		if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
						ipa_rm_work->resource_name,
						&resource) != 0){
			IPA_RM_ERR("resource does not exists\n");
			read_unlock(&ipa_rm_ctx->lock);
			return;
		}
		ipa_rm_resource_consumer_handle_cb(
				(struct ipa_rm_resource_cons *)resource,
				ipa_rm_work->event);
		read_unlock(&ipa_rm_ctx->lock);
		break;
	default:
		break;
	}

	kfree((void *) work);
}
int ipa_rm_delete_resource(enum ipa_rm_resource_name resource_name)
{
	struct ipa_rm_resource *resource;
	int result;

	IPADBG("IPA RM ::ipa_rm_delete_resource num[%d] ENTER\n",
			resource_name);
	write_lock(&ipa_rm_ctx->lock);
	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
					resource_name,
						&resource) != 0) {
		IPADBG("ipa_rm_delete_resource param are bad********\n");
		result = -EINVAL;
		goto bail;
	}
	result = ipa_rm_resource_delete(resource);
	if (result) {
		IPADBG("error in ipa_rm_resource_delete\n");
		goto bail;
	}
	result = ipa_rm_dep_graph_remove(ipa_rm_ctx->dep_graph,
								resource_name);
	IPADBG("IPA RM ::ipa_rm_delete_resource [%d] SUCCESS\n",
								resource_name);
bail:
	write_unlock(&ipa_rm_ctx->lock);
	return result;
}
int ipa_rm_stat(char *buf, int size)
{
	int i, cnt = 0, result = EINVAL;
	struct ipa_rm_resource *resource = NULL;

	if (!buf || size < 0)
		goto bail;

	read_lock(&ipa_rm_ctx->lock);
	for (i = 0; i < IPA_RM_RESOURCE_PROD_MAX; ++i) {
		result = ipa_rm_dep_graph_get_resource(
				ipa_rm_ctx->dep_graph,
				i,
				&resource);
		if (!result) {
			result = ipa_rm_resource_producer_print_stat(
							resource, buf + cnt,
							size-cnt);
			if (result < 0)
				goto bail;
			cnt += result;
		}
	}
	result = cnt;

bail:
	read_unlock(&ipa_rm_ctx->lock);
	return result;
}
int ipa_rm_create_resource(struct ipa_rm_create_params *create_params)
{
	struct ipa_rm_resource *resource;
	int result;

	if (!create_params)
		return -EINVAL;
	write_lock(&ipa_rm_ctx->lock);
	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
					  create_params->name,
					  &resource) == 0) {
		result = -EEXIST;
		goto bail;
	}
	result = ipa_rm_resource_create(create_params,
			&resource);
	if (result)
		goto bail;
	result = ipa_rm_dep_graph_add(ipa_rm_ctx->dep_graph, resource);
	if (result)
		ipa_rm_resource_delete(resource);
bail:
	write_unlock(&ipa_rm_ctx->lock);
	return result;
}
/**
 * ipa_rm_deregister() - cancel the registration
 * @resource_name: resource name
 * @reg_params: [in] registration parameters
 *
 * Returns: 0 on success, negative on failure
 *
 * Registration parameters provided here should be the same
 * as provided in  ipa_rm_register() call.
 */
int ipa_rm_deregister(enum ipa_rm_resource_name resource_name,
			struct ipa_rm_register_params *reg_params)
{
	int result;
	struct ipa_rm_resource *resource;

	IPA_RM_DBG("%s\n", ipa_rm_resource_str(resource_name));

	if (!IPA_RM_RESORCE_IS_PROD(resource_name)) {
		IPA_RM_ERR("can be called on PROD only\n");
		return -EINVAL;
	}
	read_lock(&ipa_rm_ctx->lock);
	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
			resource_name,
			&resource) != 0) {
		IPA_RM_ERR("resource does not exists\n");
		result = -EPERM;
		goto bail;
	}
	result = ipa_rm_resource_producer_deregister(
			(struct ipa_rm_resource_prod *)resource,
			reg_params);
bail:
	read_unlock(&ipa_rm_ctx->lock);
	IPA_RM_DBG("EXIT with %d\n", result);

	return result;
}
/**
 * ipa_rm_release_resource() - release resource
 * @resource_name: [in] name of the requested resource
 *
 * Returns: 0 on success, negative on failure
 *
 * All registered callbacks are called with IPA_RM_RESOURCE_RELEASED
 * on successful completion of this operation.
 */
int ipa_rm_release_resource(enum ipa_rm_resource_name resource_name)
{
	struct ipa_rm_resource *resource;
	int result;

	if (!IPA_RM_RESORCE_IS_PROD(resource_name)) {
		IPA_RM_ERR("can be called on PROD only\n");
		return -EINVAL;
	}
	read_lock(&ipa_rm_ctx->lock);
	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
					  resource_name,
					  &resource) != 0) {
		IPA_RM_ERR("resource does not exists\n");
		result = -EPERM;
		goto bail;
	}
	result = ipa_rm_resource_producer_release(
		    (struct ipa_rm_resource_prod *)resource);

bail:
	read_unlock(&ipa_rm_ctx->lock);

	return result;
}
/**
 * ipa_rm_delete_resource() - delete resource
 * @resource_name: name of resource to be deleted
 *
 * Returns: 0 on success, negative on failure
 *
 * This function is called by IPA RM client to delete client's resources.
 *
 */
int ipa_rm_delete_resource(enum ipa_rm_resource_name resource_name)
{
	struct ipa_rm_resource *resource;
	int result;

	IPA_RM_DBG("%s\n", ipa_rm_resource_str(resource_name));
	write_lock(&ipa_rm_ctx->lock);
	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
					resource_name,
						&resource) != 0) {
		IPA_RM_ERR("resource does not exist\n");
		result = -EINVAL;
		goto bail;
	}
	result = ipa_rm_resource_delete(resource);
	if (result) {
		IPA_RM_ERR("ipa_rm_resource_delete() failed\n");
		goto bail;
	}
	result = ipa_rm_dep_graph_remove(ipa_rm_ctx->dep_graph,
								resource_name);
	if (result) {
		IPA_RM_ERR("ipa_rm_dep_graph_remove() failed\n");
		goto bail;
	}
bail:
	write_unlock(&ipa_rm_ctx->lock);
	IPA_RM_DBG("EXIT with %d\n", result);

	return result;
}
/**
 * ipa_rm_dep_graph_delete_dependency() - deleted dependency between
 *				two nodes in graph
 * @graph: [in] dependency graph
 * @resource_name: [in] resource to delete
 * @depends_on_name: [in] resource to delete
 *
 * Returns: 0 on success, negative on failure
 *
 */
int ipa_rm_dep_graph_delete_dependency(struct ipa_rm_dep_graph *graph,
				enum ipa_rm_resource_name resource_name,
				enum ipa_rm_resource_name depends_on_name)
{
	struct ipa_rm_resource *dependant = NULL;
	struct ipa_rm_resource *dependency = NULL;
	int result;

	if (!graph ||
		!IPA_RM_RESORCE_IS_PROD(resource_name) ||
		!IPA_RM_RESORCE_IS_CONS(depends_on_name)) {
		IPA_RM_ERR("invalid params\n");
		result = -EINVAL;
		goto bail;
	}

	if (ipa_rm_dep_graph_get_resource(graph,
					  resource_name,
					  &dependant)) {
		IPA_RM_ERR("%s does not exist\n",
					ipa_rm_resource_str(resource_name));
		result = -EINVAL;
		goto bail;
	}

	if (ipa_rm_dep_graph_get_resource(graph,
					  depends_on_name,
					  &dependency)) {
		IPA_RM_ERR("%s does not exist\n",
					ipa_rm_resource_str(depends_on_name));
		result = -EINVAL;
		goto bail;
	}

	result = ipa_rm_resource_delete_dependency(dependant, dependency);
bail:
	IPA_RM_DBG("EXIT with %d\n", result);

	return result;
}
int ipa_rm_deregister(enum ipa_rm_resource_name resource_name,
			struct ipa_rm_register_params *reg_params)
{
	int result;
	struct ipa_rm_resource *resource;

	if (!IPA_RM_RESORCE_IS_PROD(resource_name))
		return -EINVAL;
	read_lock(&ipa_rm_ctx->lock);
	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
			resource_name,
			&resource) != 0) {
		result = -EPERM;
		goto bail;
	}
	result = ipa_rm_resource_producer_deregister(
			(struct ipa_rm_resource_prod *)resource,
			reg_params);
bail:
	read_unlock(&ipa_rm_ctx->lock);
	return result;
}
int ipa_rm_release_resource(enum ipa_rm_resource_name resource_name)
{
	struct ipa_rm_resource *resource;
	int result;
	IPADBG("IPA RM ::ipa_rm_release_resource ENTER\n");

	if (!IPA_RM_RESORCE_IS_PROD(resource_name))
		return -EINVAL;
	read_lock(&ipa_rm_ctx->lock);
	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
					  resource_name,
					  &resource) != 0) {
		result = -EPERM;
		goto bail;
	}
	result = ipa_rm_resource_producer_release(
		    (struct ipa_rm_resource_prod *)resource);

bail:
	IPADBG("IPA RM ::ipa_rm_release_resource EXIT [%d]\n", result);
	read_unlock(&ipa_rm_ctx->lock);
	return result;
}
/**
 * ipa_rm_create_resource() - create resource
 * @create_params: [in] parameters needed
 *                  for resource initialization
 *
 * Returns: 0 on success, negative on failure
 *
 * This function is called by IPA RM client to initialize client's resources.
 * This API should be called before any other IPA RM API
 * on given resource name.
 *
 */
int ipa_rm_create_resource(struct ipa_rm_create_params *create_params)
{
	struct ipa_rm_resource *resource;
	int result;

	if (!create_params) {
		IPA_RM_ERR("invalid args\n");
		return -EINVAL;
	}
	IPA_RM_DBG("%s\n", ipa_rm_resource_str(create_params->name));

	write_lock(&ipa_rm_ctx->lock);
	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
					  create_params->name,
					  &resource) == 0) {
		IPA_RM_ERR("resource already exists\n");
		result = -EEXIST;
		goto bail;
	}
	result = ipa_rm_resource_create(create_params,
			&resource);
	if (result) {
		IPA_RM_ERR("ipa_rm_resource_create() failed\n");
		goto bail;
	}
	result = ipa_rm_dep_graph_add(ipa_rm_ctx->dep_graph, resource);
	if (result) {
		IPA_RM_ERR("ipa_rm_dep_graph_add() failed\n");
		ipa_rm_resource_delete(resource);
		goto bail;
	}
bail:
	write_unlock(&ipa_rm_ctx->lock);
	IPA_RM_DBG("EXIT with %d\n", result);

	return result;
}