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

Commit 092c7ce9 authored by Jishnu Prakash's avatar Jishnu Prakash
Browse files

thermal: qpnp-adc-tm: Improve check for pending tasks before suspend



Replace wq_cnt with pm_wakeup_event with 2 seconds to prevent platform
suspend and also add flush workqueue as a part of platform suspend_noirq
to make sure all work is completed prior to platform suspend.

Change-Id: I2741727a2cf00520246497633958da022acfe10d
Signed-off-by: default avatarJishnu Prakash <jprakash@codeaurora.org>
parent 75654f2c
Loading
Loading
Loading
Loading
+24 −32
Original line number Diff line number Diff line
@@ -219,6 +219,8 @@
#define QPNP_BTM_Mn_DATA1(n)			((n * 2) + 0xa1)
#define QPNP_BTM_CHANNELS			8

#define QPNP_ADC_WAKEUP_SRC_TIMEOUT_MS          2000

/* QPNP ADC TM HC end */

struct qpnp_adc_thr_info {
@@ -273,7 +275,6 @@ struct qpnp_adc_tm_chip {
	bool				adc_tm_initialized;
	bool				adc_tm_recalib_check;
	int				max_channels_available;
	atomic_t			wq_cnt;
	struct qpnp_vadc_chip		*vadc_dev;
	struct workqueue_struct		*high_thr_wq;
	struct workqueue_struct		*low_thr_wq;
@@ -1889,7 +1890,6 @@ static void notify_adc_tm_fn(struct work_struct *work)
{
	struct qpnp_adc_tm_sensor *adc_tm = container_of(work,
		struct qpnp_adc_tm_sensor, work);
	struct qpnp_adc_tm_chip *chip = adc_tm->chip;

	if (adc_tm->thermal_node) {
		pr_debug("notifying uspace client\n");
@@ -1900,8 +1900,6 @@ static void notify_adc_tm_fn(struct work_struct *work)
		else
			notify_clients(adc_tm);
	}

	atomic_dec(&chip->wq_cnt);
}

static int qpnp_adc_tm_recalib_request_check(struct qpnp_adc_tm_chip *chip,
@@ -2145,11 +2143,8 @@ static int qpnp_adc_tm_disable_rearm_high_thresholds(
		return rc;
	}

	if (!queue_work(chip->sensor[sensor_num].req_wq,
				&chip->sensor[sensor_num].work)) {
		/* The item is already queued, reduce the count */
		atomic_dec(&chip->wq_cnt);
	}
	queue_work(chip->sensor[sensor_num].req_wq,
		&chip->sensor[sensor_num].work);

	return rc;
}
@@ -2256,11 +2251,8 @@ static int qpnp_adc_tm_disable_rearm_low_thresholds(
		return rc;
	}

	if (!queue_work(chip->sensor[sensor_num].req_wq,
				&chip->sensor[sensor_num].work)) {
		/* The item is already queued, reduce the count */
		atomic_dec(&chip->wq_cnt);
	}
	queue_work(chip->sensor[sensor_num].req_wq,
				&chip->sensor[sensor_num].work);

	return rc;
}
@@ -2324,8 +2316,6 @@ static int qpnp_adc_tm_read_status(struct qpnp_adc_tm_chip *chip)

fail:
	mutex_unlock(&chip->adc->adc_lock);
	if (rc < 0)
		atomic_dec(&chip->wq_cnt);

	return rc;
}
@@ -2378,10 +2368,6 @@ static int qpnp_adc_tm_hc_read_status(struct qpnp_adc_tm_chip *chip)
fail:
	mutex_unlock(&chip->adc->adc_lock);

	if (rc < 0 || (!chip->th_info.adc_tm_high_enable &&
					!chip->th_info.adc_tm_low_enable))
		atomic_dec(&chip->wq_cnt);

	return rc;
}

@@ -2491,7 +2477,6 @@ static irqreturn_t qpnp_adc_tm_high_thr_isr(int irq, void *data)
		}
	}

	atomic_inc(&chip->wq_cnt);
	queue_work(chip->high_thr_wq, &chip->trigger_high_thr_work);

	return IRQ_HANDLED;
@@ -2600,7 +2585,6 @@ static irqreturn_t qpnp_adc_tm_low_thr_isr(int irq, void *data)
		}
	}

	atomic_inc(&chip->wq_cnt);
	queue_work(chip->low_thr_wq, &chip->trigger_low_thr_work);

	return IRQ_HANDLED;
@@ -2729,14 +2713,16 @@ static irqreturn_t qpnp_adc_tm_rc_thr_isr(int irq, void *data)
	}

	if (sensor_low_notify_num) {
		if (queue_work(chip->low_thr_wq, &chip->trigger_low_thr_work))
			atomic_inc(&chip->wq_cnt);
		pm_wakeup_event(chip->dev,
				QPNP_ADC_WAKEUP_SRC_TIMEOUT_MS);
		queue_work(chip->low_thr_wq, &chip->trigger_low_thr_work);
	}

	if (sensor_high_notify_num) {
		if (queue_work(chip->high_thr_wq,
				&chip->trigger_high_thr_work))
			atomic_inc(&chip->wq_cnt);
		pm_wakeup_event(chip->dev,
				QPNP_ADC_WAKEUP_SRC_TIMEOUT_MS);
		queue_work(chip->high_thr_wq,
				&chip->trigger_high_thr_work);
	}

	return IRQ_HANDLED;
@@ -3224,7 +3210,6 @@ static int qpnp_adc_tm_probe(struct platform_device *pdev)

	INIT_WORK(&chip->trigger_high_thr_work, qpnp_adc_tm_high_thr_work);
	INIT_WORK(&chip->trigger_low_thr_work, qpnp_adc_tm_low_thr_work);
	atomic_set(&chip->wq_cnt, 0);

	if (!chip->adc_tm_hc) {
		rc = qpnp_adc_tm_initial_setup(chip);
@@ -3331,11 +3316,18 @@ static void qpnp_adc_tm_shutdown(struct platform_device *pdev)
static int qpnp_adc_tm_suspend_noirq(struct device *dev)
{
	struct qpnp_adc_tm_chip *chip = dev_get_drvdata(dev);
	struct device_node *node = dev->of_node, *child;
	int i = 0;

	flush_workqueue(chip->high_thr_wq);
	flush_workqueue(chip->low_thr_wq);

	if (atomic_read(&chip->wq_cnt) != 0) {
		pr_err(
			"Aborting suspend, adc_tm notification running while suspending\n");
		return -EBUSY;
	for_each_child_of_node(node, child) {
		if (chip->sensor[i].req_wq) {
			pr_debug("flushing queue for sensor %d\n", i);
			flush_workqueue(chip->sensor[i].req_wq);
		}
		i++;
	}
	return 0;
}