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

Commit 7526bb0b authored by Ravit Katzav's avatar Ravit Katzav
Browse files

msm: ipa: improve SUSPEND interrupt handling



When a packet arrives to a suspended endpoint in IPA,
IPA generates a SUSPEND interrupt. IPA driver handles it by
requesting the corresponding CONSUMER resource from IPA RM for
1 second and then releases it. In case this resource is requested
by another resource in IPA RM and released, the resource will be
released only after the 1 second timeout expires.
This change improves this by releasing the resource immediately
without the need to wait for 1 second timeout.

Change-Id: I033d9c3c7d332b3271a4d7e27ef1c5364a847b5c
Acked-by: default avatarAdy Abraham <adya@qti.qualcomm.com>
Signed-off-by: default avatarRavit Katzav <rkatzav@codeaurora.org>
parent 003a7b03
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -281,7 +281,8 @@ void delayed_release_work_func(struct work_struct *work)
	}

	ipa_rm_resource_consumer_release(
		(struct ipa_rm_resource_cons *)resource, rwork->needed_bw);
		(struct ipa_rm_resource_cons *)resource, rwork->needed_bw,
		rwork->dec_usage_count);

bail:
	spin_unlock_irqrestore(&ipa_rm_ctx->ipa_rm_lock, flags);
@@ -317,7 +318,7 @@ int ipa_rm_request_resource_with_timer(enum ipa_rm_resource_name resource_name)
		goto bail;
	}
	result = ipa_rm_resource_consumer_request(
			(struct ipa_rm_resource_cons *)resource, 0);
			(struct ipa_rm_resource_cons *)resource, 0, false);
	if (result != 0 && result != -EINPROGRESS) {
		IPA_RM_ERR("consumer request returned error %d\n", result);
		result = -EPERM;
@@ -331,6 +332,7 @@ int ipa_rm_request_resource_with_timer(enum ipa_rm_resource_name resource_name)
	}
	release_work->resource_name = resource->name;
	release_work->needed_bw = 0;
	release_work->dec_usage_count = false;
	INIT_DELAYED_WORK(&release_work->work, delayed_release_work_func);
	schedule_delayed_work(&release_work->work,
			msecs_to_jiffies(IPA_RM_RELEASE_DELAY_IN_MSEC));
+2 −0
Original line number Diff line number Diff line
@@ -42,11 +42,13 @@ int ipa_rm_cons_index(enum ipa_rm_resource_name resource_name);
 * @delayed_work: work struct
 * @ipa_rm_resource_name: name of the resource on which this work should be done
 * @needed_bw: bandwidth required for resource in Mbps
 * @dec_usage_count: decrease usage count on release ?
 */
struct ipa_rm_delayed_release_work_type {
	struct delayed_work		work;
	enum ipa_rm_resource_name	resource_name;
	u32				needed_bw;
	bool				dec_usage_count;

};

+17 −14
Original line number Diff line number Diff line
@@ -139,7 +139,8 @@ int ipa_rm_resource_consumer_request_work(struct ipa_rm_resource_cons *consumer,

int ipa_rm_resource_consumer_request(
		struct ipa_rm_resource_cons *consumer,
		u32 prod_needed_bw)
		u32 prod_needed_bw,
		bool inc_usage_count)
{
	int result = 0;
	enum ipa_rm_resource_state prev_state;
@@ -180,6 +181,7 @@ int ipa_rm_resource_consumer_request(
		result = -EPERM;
		goto bail;
	}
	if (inc_usage_count)
		consumer->usage_count++;
bail:
	IPA_RM_DBG("%s new state: %d\n",
@@ -192,7 +194,8 @@ bail:

int ipa_rm_resource_consumer_release(
		struct ipa_rm_resource_cons *consumer,
		u32 prod_needed_bw)
		u32 prod_needed_bw,
		bool dec_usage_count)
{
	int result = 0;
	enum ipa_rm_resource_state save_state;
@@ -207,11 +210,7 @@ int ipa_rm_resource_consumer_release(
		break;
	case IPA_RM_GRANTED:
	case IPA_RM_REQUEST_IN_PROGRESS:
		if (consumer->usage_count == 0) {
			IPA_RM_ERR("consumer not used\n");
			result = -EPERM;
			break;
		}
		if (dec_usage_count && consumer->usage_count > 0)
			consumer->usage_count--;
		if (consumer->usage_count == 0) {
			consumer->resource.state = IPA_RM_RELEASE_IN_PROGRESS;
@@ -233,7 +232,7 @@ int ipa_rm_resource_consumer_release(
		}
		break;
	case IPA_RM_RELEASE_IN_PROGRESS:
		if (consumer->usage_count > 0)
		if (dec_usage_count && consumer->usage_count > 0)
			consumer->usage_count--;
		result = -EINPROGRESS;
		break;
@@ -623,7 +622,8 @@ int ipa_rm_resource_add_dependency(struct ipa_rm_resource *resource,
					resource)->pending_request++;
		consumer_result = ipa_rm_resource_consumer_request(
				(struct ipa_rm_resource_cons *)depends_on,
				resource->max_bw);
				resource->max_bw,
				true);
		if (consumer_result != -EINPROGRESS) {
			resource->state = prev_state;
			((struct ipa_rm_resource_prod *)
@@ -737,7 +737,8 @@ int ipa_rm_resource_delete_dependency(struct ipa_rm_resource *resource,
	if (release_consumer)
		(void) ipa_rm_resource_consumer_release(
				(struct ipa_rm_resource_cons *)depends_on,
				resource->max_bw);
				resource->max_bw,
				true);
bail:
	IPA_RM_DBG("EXIT with %d\n", result);

@@ -785,7 +786,8 @@ int ipa_rm_resource_producer_request(struct ipa_rm_resource_prod *producer)
			producer->pending_request++;
			consumer_result = ipa_rm_resource_consumer_request(
				(struct ipa_rm_resource_cons *)consumer,
				producer->resource.max_bw);
				producer->resource.max_bw,
				true);
			if (consumer_result == -EINPROGRESS) {
				result = -EINPROGRESS;
			} else {
@@ -859,7 +861,8 @@ int ipa_rm_resource_producer_release(struct ipa_rm_resource_prod *producer)
			producer->pending_release++;
			consumer_result = ipa_rm_resource_consumer_release(
				(struct ipa_rm_resource_cons *)consumer,
				producer->resource.max_bw);
				producer->resource.max_bw,
				true);
			producer->pending_release--;
		}
	}
+4 −2
Original line number Diff line number Diff line
@@ -123,10 +123,12 @@ int ipa_rm_resource_producer_request(struct ipa_rm_resource_prod *producer);
int ipa_rm_resource_producer_release(struct ipa_rm_resource_prod *producer);

int ipa_rm_resource_consumer_request(struct ipa_rm_resource_cons *consumer,
				u32 needed_bw);
				u32 needed_bw,
				bool inc_usage_count);

int ipa_rm_resource_consumer_release(struct ipa_rm_resource_cons *consumer,
				u32 needed_bw);
				u32 needed_bw,
				bool dec_usage_count);

int ipa_rm_resource_set_perf_profile(struct ipa_rm_resource *resource,
				     struct ipa_rm_perf_profile *profile);