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

Commit 9c1c3dfc authored by Jilai Wang's avatar Jilai Wang
Browse files

msm: npu: Prevent unpaired power vote/unvote via sysfs node



If there are unpaired power vote/unvote operations via sysfs node,
it is possible that npu power will be turned off unexpected while
npu firmware is still active. This change is to prevent this case.

Change-Id: Icd98b87522ec12ba599dec518fe522056ca40eec
Signed-off-by: default avatarJilai Wang <jilaiw@codeaurora.org>
parent 4e4f1f3b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -176,6 +176,7 @@ struct npu_reg {
 */
struct npu_pwrctrl {
	int32_t pwr_vote_num;
	int32_t pwr_vote_num_sysfs;

	struct npu_pwrlevel pwrlevels[NPU_MAX_PWRLEVELS];
	uint32_t active_pwrlevel;
+19 −1
Original line number Diff line number Diff line
@@ -260,14 +260,32 @@ static ssize_t pwr_store(struct device *dev,
					  const char *buf, size_t count)
{
	struct npu_device *npu_dev = dev_get_drvdata(dev);
	struct npu_pwrctrl *pwr = &npu_dev->pwrctrl;
	bool pwr_on = false;

	if (strtobool(buf, &pwr_on) < 0)
		return -EINVAL;

	mutex_lock(&npu_dev->dev_lock);
	if (pwr_on) {
		if (npu_enable_core_power(npu_dev))
		pwr->pwr_vote_num_sysfs++;
	} else {
		if (!pwr->pwr_vote_num_sysfs) {
			NPU_WARN("Invalid unvote from sysfs\n");
			mutex_unlock(&npu_dev->dev_lock);
			return -EINVAL;
		}
		pwr->pwr_vote_num_sysfs--;
	}
	mutex_unlock(&npu_dev->dev_lock);

	if (pwr_on) {
		if (npu_enable_core_power(npu_dev)) {
			mutex_lock(&npu_dev->dev_lock);
			pwr->pwr_vote_num_sysfs--;
			mutex_unlock(&npu_dev->dev_lock);
			return -EPERM;
		}
	} else {
		npu_disable_core_power(npu_dev);
	}