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

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

Merge "msm: ipa3: rm: enhance inactivity timer logic"

parents 13848461 aed54f5d
Loading
Loading
Loading
Loading
+34 −21
Original line number Diff line number Diff line
@@ -28,8 +28,10 @@
 * @resource_name - resource name
 * @work: delayed work object for running delayed releas
 *	function
 * @release_in_prog: boolean flag indicates if release resource
 *			is scheduled for happen in the future.
 * @resource_requested: boolean flag indicates if resource was requested
 * @reschedule_work: boolean flag indicates to not release and to
 *	reschedule the release work.
 * @work_in_progress: boolean flag indicates is release work was scheduled.
 * @jiffies: number of jiffies for timeout
 *
 * WWAN private - holds all relevant info about WWAN driver
@@ -39,7 +41,9 @@ struct ipa3_rm_it_private {
	enum ipa_rm_resource_name resource_name;
	spinlock_t lock;
	struct delayed_work work;
	bool release_in_prog;
	bool resource_requested;
	bool reschedule_work;
	bool work_in_progress;
	unsigned long jiffies;
};

@@ -47,13 +51,11 @@ static struct ipa3_rm_it_private ipa3_rm_it_handles[IPA_RM_RESOURCE_MAX];

/**
 * ipa3_rm_inactivity_timer_func() - called when timer expired in
 * the context of the shared workqueue. Checks internally is
 * release_in_prog flag is set and calls to
 * ipa3_rm_release_resource(). release_in_prog is cleared when
 * calling to ipa3_rm_inactivity_timer_request_resource(). In
 * this situation this function shall not call to
 * ipa3_rm_release_resource() since the resource needs to remain
 * up
 * the context of the shared workqueue. Checks internally if
 * reschedule_work flag is set. In case it is not set this function calls to
 * ipa_rm_release_resource(). In case reschedule_work is set this function
 * reschedule the work. This flag is cleared cleared when
 * calling to ipa_rm_inactivity_timer_release_resource().
 *
 * @work: work object provided by the work queue
 *
@@ -71,14 +73,22 @@ static void ipa3_rm_inactivity_timer_func(struct work_struct *work)
	IPADBG("%s: timer expired for resource %d!\n", __func__,
	    me->resource_name);

	/* check that release still need to be performed */
	spin_lock_irqsave(
		&ipa3_rm_it_handles[me->resource_name].lock, flags);
	if (ipa3_rm_it_handles[me->resource_name].release_in_prog) {
	if (ipa3_rm_it_handles[me->resource_name].reschedule_work) {
		IPADBG("%s: setting delayed work\n", __func__);
		ipa3_rm_it_handles[me->resource_name].reschedule_work = false;
		schedule_delayed_work(
			&ipa3_rm_it_handles[me->resource_name].work,
			ipa3_rm_it_handles[me->resource_name].jiffies);
	} else if (ipa3_rm_it_handles[me->resource_name].resource_requested) {
		IPADBG("%s: not calling release\n", __func__);
		ipa3_rm_it_handles[me->resource_name].work_in_progress = false;
	} else {
		IPADBG("%s: calling release_resource on resource %d!\n",
			__func__, me->resource_name);
		ipa3_rm_release_resource(me->resource_name);
		ipa3_rm_it_handles[me->resource_name].release_in_prog = false;
		ipa3_rm_it_handles[me->resource_name].work_in_progress = false;
	}
	spin_unlock_irqrestore(
		&ipa3_rm_it_handles[me->resource_name].lock, flags);
@@ -117,7 +127,9 @@ int ipa3_rm_inactivity_timer_init(enum ipa_rm_resource_name resource_name,
	spin_lock_init(&ipa3_rm_it_handles[resource_name].lock);
	ipa3_rm_it_handles[resource_name].resource_name = resource_name;
	ipa3_rm_it_handles[resource_name].jiffies = msecs_to_jiffies(msecs);
	ipa3_rm_it_handles[resource_name].release_in_prog = false;
	ipa3_rm_it_handles[resource_name].resource_requested = false;
	ipa3_rm_it_handles[resource_name].reschedule_work = false;
	ipa3_rm_it_handles[resource_name].work_in_progress = false;

	INIT_DELAYED_WORK(&ipa3_rm_it_handles[resource_name].work,
			  ipa3_rm_inactivity_timer_func);
@@ -192,8 +204,7 @@ int ipa3_rm_inactivity_timer_request_resource(
	}

	spin_lock_irqsave(&ipa3_rm_it_handles[resource_name].lock, flags);
	cancel_delayed_work(&ipa3_rm_it_handles[resource_name].work);
	ipa3_rm_it_handles[resource_name].release_in_prog = false;
	ipa3_rm_it_handles[resource_name].resource_requested = true;
	spin_unlock_irqrestore(&ipa3_rm_it_handles[resource_name].lock, flags);
	ret = ipa3_rm_request_resource(resource_name);
	IPADBG("%s: resource %d: returning %d\n", __func__, resource_name, ret);
@@ -235,19 +246,21 @@ int ipa3_rm_inactivity_timer_release_resource(
	}

	spin_lock_irqsave(&ipa3_rm_it_handles[resource_name].lock, flags);
	if (ipa3_rm_it_handles[resource_name].release_in_prog) {
	ipa3_rm_it_handles[resource_name].resource_requested = false;
	if (ipa3_rm_it_handles[resource_name].work_in_progress) {
		IPADBG("%s: Timer already set, not scheduling again %d\n",
		    __func__, resource_name);
		ipa3_rm_it_handles[resource_name].reschedule_work = true;
		spin_unlock_irqrestore(
			&ipa3_rm_it_handles[resource_name].lock, flags);
		return 0;
	}
	ipa3_rm_it_handles[resource_name].release_in_prog = true;
	spin_unlock_irqrestore(&ipa3_rm_it_handles[resource_name].lock, flags);

	ipa3_rm_it_handles[resource_name].work_in_progress = true;
	ipa3_rm_it_handles[resource_name].reschedule_work = false;
	IPADBG("%s: setting delayed work\n", __func__);
	schedule_delayed_work(&ipa3_rm_it_handles[resource_name].work,
			      ipa3_rm_it_handles[resource_name].jiffies);
	spin_unlock_irqrestore(&ipa3_rm_it_handles[resource_name].lock, flags);

	return 0;
}