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

Commit b8a0629d authored by Yuanfang Zhang's avatar Yuanfang Zhang
Browse files

Coresight-cti: add support to enable/disable multiple clks and regulators



Some CTIs can go into power collapse when accessing CTI's register space,
hence require a bunch of clks and regulators to be configured. This change
add support in CIT driver to enable them when CTI is used for first time
and disable them when CTI isn't used.

Change-Id: Ia8a54cbc0f8363d19811c3a0712f5b8c23530b32
Signed-off-by: default avatarYuanfang Zhang <zhangyuanfang@codeaurora.org>
parent 54f3590a
Loading
Loading
Loading
Loading
+28 −8
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
 */

#include <linux/kernel.h>
@@ -375,20 +375,27 @@ int coresight_cti_map_trigin(struct coresight_cti *cti, int trig, int ch)
		ret = pm_runtime_get_sync(drvdata->dev);
		if (ret)
			goto err1;
		ret = coresight_enable_reg_clk(drvdata->csdev);
		if (ret)
			goto err2;
	}

	spin_lock_irqsave(&drvdata->spinlock, flag);
	ret = cti_cpu_verify_access(drvdata);
	if (ret)
		goto err2;
		goto err3;

	__cti_map_trigin(drvdata, trig, ch);
	spin_unlock_irqrestore(&drvdata->spinlock, flag);

	mutex_unlock(&drvdata->mutex);
	return 0;
err2:
err3:
	spin_unlock_irqrestore(&drvdata->spinlock, flag);

	if (drvdata->refcnt == 0)
		coresight_disable_reg_clk(drvdata->csdev);
err2:
	/*
	 * We come here before refcnt is potentially modified in
	 * __cti_map_trigin so it is safe to check it against 0 without
@@ -459,20 +466,27 @@ int coresight_cti_map_trigout(struct coresight_cti *cti, int trig, int ch)
		ret = pm_runtime_get_sync(drvdata->dev);
		if (ret)
			goto err1;
		ret = coresight_enable_reg_clk(drvdata->csdev);
		if (ret)
			goto err2;
	}

	spin_lock_irqsave(&drvdata->spinlock, flag);
	ret = cti_cpu_verify_access(drvdata);
	if (ret)
		goto err2;
		goto err3;

	__cti_map_trigout(drvdata, trig, ch);
	spin_unlock_irqrestore(&drvdata->spinlock, flag);

	mutex_unlock(&drvdata->mutex);
	return 0;
err2:
err3:
	spin_unlock_irqrestore(&drvdata->spinlock, flag);

	if (drvdata->refcnt == 0)
		coresight_disable_reg_clk(drvdata->csdev);
err2:
	/*
	 * We come here before refcnt is potentially incremented in
	 * __cti_map_trigout so it is safe to check it against 0.
@@ -555,8 +569,10 @@ void coresight_cti_unmap_trigin(struct coresight_cti *cti, int trig, int ch)
	 * refcnt can be used here since in all cases its value is modified only
	 * within the mutex lock region in addition to within the spinlock.
	 */
	if (drvdata->refcnt == 0)
	if (drvdata->refcnt == 0) {
		pm_runtime_put(drvdata->dev);
		coresight_disable_reg_clk(drvdata->csdev);
	}

	if (drvdata->gpio_trigin->trig == trig)
		cti_trigin_gpio_disable(drvdata);
@@ -624,8 +640,10 @@ void coresight_cti_unmap_trigout(struct coresight_cti *cti, int trig, int ch)
	 * refcnt can be used here since in all cases its value is modified only
	 * within the mutex lock region in addition to within the spinlock.
	 */
	if (drvdata->refcnt == 0)
	if (drvdata->refcnt == 0) {
		pm_runtime_put(drvdata->dev);
		coresight_disable_reg_clk(drvdata->csdev);
	}

	if (drvdata->gpio_trigout->trig == trig)
		cti_trigout_gpio_disable(drvdata);
@@ -687,8 +705,10 @@ void coresight_cti_reset(struct coresight_cti *cti)
			cti_trigout_gpio_disable(drvdata);
	}

	if (refcnt)
	if (refcnt) {
		pm_runtime_put(drvdata->dev);
		coresight_disable_reg_clk(drvdata->csdev);
	}
	mutex_unlock(&drvdata->mutex);
	return;
err: