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

Commit 3a950f51 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: enhance inactivity timer logic"

parents 97828516 680d6fcb
Loading
Loading
Loading
Loading
+35 −22
Original line number Original line 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
 * 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
 * it under the terms of the GNU General Public License version 2 and
@@ -28,8 +28,10 @@
 * @resource_name - resource name
 * @resource_name - resource name
 * @work: delayed work object for running delayed releas
 * @work: delayed work object for running delayed releas
 *	function
 *	function
 * @release_in_prog: boolean flag indicates if release resource
 * @resource_requested: boolean flag indicates if resource was requested
 *			is scheduled for happen in the future.
 * @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
 * @jiffies: number of jiffies for timeout
 *
 *
 * WWAN private - holds all relevant info about WWAN driver
 * WWAN private - holds all relevant info about WWAN driver
@@ -39,7 +41,9 @@ struct ipa_rm_it_private {
	enum ipa_rm_resource_name resource_name;
	enum ipa_rm_resource_name resource_name;
	spinlock_t lock;
	spinlock_t lock;
	struct delayed_work work;
	struct delayed_work work;
	bool release_in_prog;
	bool resource_requested;
	bool reschedule_work;
	bool work_in_progress;
	unsigned long jiffies;
	unsigned long jiffies;
};
};


@@ -47,13 +51,11 @@ static struct ipa_rm_it_private ipa_rm_it_handles[IPA_RM_RESOURCE_MAX];


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


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


	INIT_DELAYED_WORK(&ipa_rm_it_handles[resource_name].work,
	INIT_DELAYED_WORK(&ipa_rm_it_handles[resource_name].work,
			  ipa_rm_inactivity_timer_func);
			  ipa_rm_inactivity_timer_func);
@@ -193,8 +205,7 @@ int ipa_rm_inactivity_timer_request_resource(
	}
	}


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


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

	IPADBG("%s: setting delayed work\n", __func__);
	IPADBG("%s: setting delayed work\n", __func__);
	schedule_delayed_work(&ipa_rm_it_handles[resource_name].work,
	schedule_delayed_work(&ipa_rm_it_handles[resource_name].work,
			      ipa_rm_it_handles[resource_name].jiffies);
			      ipa_rm_it_handles[resource_name].jiffies);
	spin_unlock_irqrestore(&ipa_rm_it_handles[resource_name].lock, flags);


	return 0;
	return 0;
}
}