Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27e0a46d authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa: rm: add add_dependency_sync API"

parents c3b02802 0e7dd4bc
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
@@ -191,6 +191,62 @@ int ipa_rm_add_dependency(enum ipa_rm_resource_name resource_name,
}
EXPORT_SYMBOL(ipa_rm_add_dependency);

/**
 * ipa_rm_add_dependency_sync() - Create a dependency between 2 resources
 * in a synchronized fashion. In case a producer resource is in GRANTED state
 * and the newly added consumer resource is in RELEASED state, the consumer
 * entity will be requested and the function will block until the consumer
 * is granted.
 * @resource_name: name of dependent resource
 * @depends_on_name: name of its dependency
 *
 * Returns: 0 on success, negative on failure
 *
 * Side effects: May block. See documentation above.
 */
int ipa_rm_add_dependency_sync(enum ipa_rm_resource_name resource_name,
		enum ipa_rm_resource_name depends_on_name)
{
	int result;
	struct ipa_rm_resource *consumer;
	unsigned long time;
	unsigned long flags;

	IPA_RM_DBG("%s -> %s\n", ipa_rm_resource_str(resource_name),
				 ipa_rm_resource_str(depends_on_name));
	spin_lock_irqsave(&ipa_rm_ctx->ipa_rm_lock, flags);
	result = ipa_rm_dep_graph_add_dependency(
						ipa_rm_ctx->dep_graph,
						resource_name,
						depends_on_name);
	spin_unlock_irqrestore(&ipa_rm_ctx->ipa_rm_lock, flags);
	if (result == -EINPROGRESS) {
		ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
				depends_on_name,
				&consumer);
		IPA_RM_DBG("%s waits for GRANT of %s.\n",
				ipa_rm_resource_str(resource_name),
				ipa_rm_resource_str(depends_on_name));
		time = wait_for_completion_timeout(
				&((struct ipa_rm_resource_cons *)consumer)->
				request_consumer_in_progress,
				HZ);
		result = 0;
		if (!time) {
			IPA_RM_ERR("TIMEOUT waiting for %s GRANT event.",
					ipa_rm_resource_str(depends_on_name));
			result = -ETIME;
		}
		IPA_RM_DBG("%s waited for %s GRANT %lu time.\n",
				ipa_rm_resource_str(resource_name),
				ipa_rm_resource_str(depends_on_name),
				time);
	}
	IPA_RM_DBG("EXIT with %d\n", result);

	return result;
}
EXPORT_SYMBOL(ipa_rm_add_dependency_sync);

/**
 * ipa_rm_delete_dependency() - create dependency
+4 −0
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ int ipa_rm_resource_consumer_release_work(
		else
			consumer->resource.state = IPA_RM_RELEASED;
	}
	complete_all(&consumer->request_consumer_in_progress);

	ipa_rm_perf_profile_change(consumer->resource.name);
bail:
@@ -156,6 +157,7 @@ int ipa_rm_resource_consumer_request(
	switch (consumer->resource.state) {
	case IPA_RM_RELEASED:
	case IPA_RM_RELEASE_IN_PROGRESS:
		reinit_completion(&consumer->request_consumer_in_progress);
		consumer->resource.state = IPA_RM_REQUEST_IN_PROGRESS;
		if (prev_state == IPA_RM_RELEASE_IN_PROGRESS ||
				ipa_inc_client_enable_clks_no_block() != 0) {
@@ -353,6 +355,7 @@ static int ipa_rm_resource_consumer_create(struct ipa_rm_resource **resource,
	(*consumer)->release_resource = create_params->release_resource;
	(*resource) = (struct ipa_rm_resource *) (*consumer);
	(*resource)->type = IPA_RM_CONSUMER;
	init_completion(&((*consumer)->request_consumer_in_progress));
	*max_peers = IPA_RM_RESOURCE_PROD_MAX;
bail:
	return result;
@@ -973,6 +976,7 @@ void ipa_rm_resource_consumer_handle_cb(struct ipa_rm_resource_cons *consumer,
		consumer->resource.state = IPA_RM_GRANTED;
		ipa_rm_perf_profile_change(consumer->resource.name);
		ipa_resume_resource(consumer->resource.name);
		complete_all(&consumer->request_consumer_in_progress);
		break;
	case IPA_RM_RELEASE_IN_PROGRESS:
		if (event == IPA_RM_RESOURCE_GRANTED)
+4 −1
Original line number Diff line number Diff line
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -72,6 +72,8 @@ struct ipa_rm_resource {
 * @resource: resource
 * @usage_count: number of producers in GRANTED / REQUESTED state
 *		using this consumer
 * @request_consumer_in_progress: when set, the consumer is during its request
 *		phase
 * @request_resource: function which should be called to request resource
 *			from resource manager
 * @release_resource: function which should be called to release resource
@@ -81,6 +83,7 @@ struct ipa_rm_resource {
struct ipa_rm_resource_cons {
	struct ipa_rm_resource resource;
	int usage_count;
	struct completion request_consumer_in_progress;
	int (*request_resource)(void);
	int (*release_resource)(void);
};
+10 −0
Original line number Diff line number Diff line
@@ -1289,6 +1289,9 @@ int ipa_rm_set_perf_profile(enum ipa_rm_resource_name resource_name,
int ipa_rm_add_dependency(enum ipa_rm_resource_name resource_name,
			enum ipa_rm_resource_name depends_on_name);

int ipa_rm_add_dependency_sync(enum ipa_rm_resource_name resource_name,
		enum ipa_rm_resource_name depends_on_name);

int ipa_rm_delete_dependency(enum ipa_rm_resource_name resource_name,
			enum ipa_rm_resource_name depends_on_name);

@@ -1845,6 +1848,13 @@ static inline int ipa_rm_add_dependency(
	return -EPERM;
}

static inline int ipa_rm_add_dependency_sync(
		enum ipa_rm_resource_name resource_name,
		enum ipa_rm_resource_name depends_on_name)
{
	return -EPERM;
}

static inline int ipa_rm_delete_dependency(
		enum ipa_rm_resource_name resource_name,
		enum ipa_rm_resource_name depends_on_name)