예제 #1
0
/**
 * 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;
}
예제 #2
0
/**
 * 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;
}
예제 #3
0
/**
 * ipa_rm_exit() - free all IPA RM resources
 */
void ipa_rm_exit(void)
{
	IPA_RM_DBG("ENTER\n");
	ipa_rm_dep_graph_delete(ipa_rm_ctx->dep_graph);
	destroy_workqueue(ipa_rm_ctx->ipa_rm_wq);
	kfree(ipa_rm_ctx);
	ipa_rm_ctx = NULL;
	IPA_RM_DBG("EXIT\n");
}
예제 #4
0
/**
 * ipa_rm_initialize() - initialize IPA RM component
 *
 * Returns: 0 on success, negative otherwise
 */
int ipa_rm_initialize(void)
{
	int result;

	ipa_rm_ctx = kzalloc(sizeof(*ipa_rm_ctx), GFP_KERNEL);
	if (!ipa_rm_ctx) {
		IPA_RM_ERR("no mem\n");
		result = -ENOMEM;
		goto bail;
	}
	ipa_rm_ctx->ipa_rm_wq = create_singlethread_workqueue("ipa_rm_wq");
	if (!ipa_rm_ctx->ipa_rm_wq) {
		IPA_RM_ERR("create workqueue failed\n");
		result = -ENOMEM;
		goto create_wq_fail;
	}
	result = ipa_rm_dep_graph_create(&(ipa_rm_ctx->dep_graph));
	if (result) {
		IPA_RM_ERR("create dependency graph failed\n");
		goto graph_alloc_fail;
	}
	rwlock_init(&ipa_rm_ctx->lock);
	IPA_RM_DBG("SUCCESS\n");

	return 0;
graph_alloc_fail:
	destroy_workqueue(ipa_rm_ctx->ipa_rm_wq);
create_wq_fail:
	kfree(ipa_rm_ctx);
bail:
	return result;
}
예제 #5
0
/**
 * ipa_rm_delete_dependency() - create dependency
 *					between 2 resources
 * @resource_name: name of dependent resource
 * @depends_on_name: name of its dependency
 *
 * Returns: 0 on success, negative on failure
 *
 * Side effects: IPA_RM_RESORCE_GRANTED could be generated
 * in case client registered with IPA RM
 */
int ipa_rm_delete_dependency(enum ipa_rm_resource_name resource_name,
			enum ipa_rm_resource_name depends_on_name)
{
	int result;

	IPA_RM_DBG("%s -> %s\n", ipa_rm_resource_str(resource_name),
				 ipa_rm_resource_str(depends_on_name));
	write_lock(&ipa_rm_ctx->lock);
	result = ipa_rm_dep_graph_delete_dependency(
			  ipa_rm_ctx->dep_graph,
			  resource_name,
			  depends_on_name);
	write_unlock(&ipa_rm_ctx->lock);
	IPA_RM_DBG("EXIT with %d\n", result);

	return result;
}
예제 #6
0
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);
}
예제 #7
0
/**
 * ipa_rm_notify_completion() -
 *	consumer driver notification for
 *	request_resource / release_resource operations
 *	completion
 * @event: notified event
 * @resource_name: resource name
 *
 * Returns: 0 on success, negative on failure
 */
int ipa_rm_notify_completion(enum ipa_rm_event event,
		enum ipa_rm_resource_name resource_name)
{
	int result;

	IPA_RM_DBG("event %d on %s\n", event,
				ipa_rm_resource_str(resource_name));
	if (!IPA_RM_RESORCE_IS_CONS(resource_name)) {
		IPA_RM_ERR("can be called on CONS only\n");
		result = -EINVAL;
		goto bail;
	}
	ipa_rm_wq_send_cmd(IPA_RM_WQ_RESOURCE_CB,
			resource_name,
			event,
			false);
	result = 0;
bail:
	IPA_RM_DBG("EXIT with %d\n", result);

	return result;
}
예제 #8
0
/**
 * 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;
}
/**
 * ipa3_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 ipa3_rm_dep_graph_delete_dependency(struct ipa3_rm_dep_graph *graph,
				enum ipa_rm_resource_name resource_name,
				enum ipa_rm_resource_name depends_on_name)
{
	struct ipa_rm_resource *dependent = 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 (ipa3_rm_dep_graph_get_resource(graph,
					  resource_name,
					  &dependent)) {
		IPA_RM_ERR("%s does not exist\n",
					ipa3_rm_resource_str(resource_name));
		result = -EINVAL;
		goto bail;
	}

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

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

	return result;
}