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

Commit 6d9712c5 authored by Yuanfang Zhang's avatar Yuanfang Zhang Committed by Gerrit - the friendly Code Review server
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>
Signed-off-by: default avatarMao Jinlong <jinlmao@codeaurora.org>
parent 6595f8f6
Loading
Loading
Loading
Loading
+28 −8
Original line number Diff line number Diff line
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2017, 2019 The Linux Foundation. All rights reserved.
 *
 * 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
@@ -382,20 +382,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
@@ -466,20 +473,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.
@@ -562,8 +576,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);
@@ -631,8 +647,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);
@@ -694,8 +712,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:
+5 −3
Original line number Diff line number Diff line
@@ -120,14 +120,14 @@ static void coresight_reset_all_sink(void)
	bus_for_each_dev(&coresight_bustype, NULL, NULL, coresight_reset_sink);
}

void coresight_enable_reg_clk(struct coresight_device *csdev)
int coresight_enable_reg_clk(struct coresight_device *csdev)
{
	struct coresight_reg_clk *reg_clk = csdev->reg_clk;
	int ret;
	int i, j;

	if (IS_ERR_OR_NULL(reg_clk))
		return;
		return -EINVAL;

	for (i = 0; i < reg_clk->nr_reg; i++) {
		ret = regulator_enable(reg_clk->reg[i]);
@@ -141,7 +141,7 @@ void coresight_enable_reg_clk(struct coresight_device *csdev)
			goto err_clks;
	}

	return;
	return 0;

err_clks:
	for (j--; j >= 0; j--)
@@ -149,6 +149,8 @@ void coresight_enable_reg_clk(struct coresight_device *csdev)
err_regs:
	for (i--; i >= 0; i--)
		regulator_disable(reg_clk->reg[i]);

	return ret;
}
EXPORT_SYMBOL(coresight_enable_reg_clk);

+5 −2
Original line number Diff line number Diff line
@@ -278,7 +278,7 @@ extern int coresight_timeout(void __iomem *addr, u32 offset,
			     int position, int value);
extern void coresight_abort(void);
extern void coresight_disable_reg_clk(struct coresight_device *csdev);
extern void coresight_enable_reg_clk(struct coresight_device *csdev);
extern int coresight_enable_reg_clk(struct coresight_device *csdev);
#else
static inline struct coresight_device *
coresight_register(struct coresight_desc *desc) { return NULL; }
@@ -290,7 +290,10 @@ static inline int coresight_timeout(void __iomem *addr, u32 offset,
				     int position, int value) { return 1; }
static inline void coresight_abort(void) {}
static inline void coresight_disable_reg_clk(struct coresight_device *csdev) {}
static inline void coresight_enable_reg_clk(struct coresight_device *csdev) {}
static inline int coresight_enable_reg_clk(struct coresight_device *csdev)
{
	return -EINVAL;
}
#endif

#if defined(CONFIG_OF) && defined(CONFIG_CORESIGHT)