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

Commit 3d109ee5 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "clk: msm: clock-cpu-8996: Workaround a concurrent access bug"

parents c464098a 8c0f5c6c
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -534,8 +534,9 @@ static int cpu_clk_8996_set_rate(struct clk *c, unsigned long rate)
			if (cpuclk->alt_pll_freqs[i] < rate &&
			    cpuclk->alt_pll_freqs[i+1] >= rate)
				alt_pll_rate = cpuclk->alt_pll_freqs[i];

		mutex_lock(&scm_lmh_lock);
		ret = clk_set_rate(cpuclk->alt_pll, alt_pll_rate);
		mutex_unlock(&scm_lmh_lock);
		if (ret) {
			pr_err("failed to set rate %lu on alt_pll when setting %lu on %s (%d)\n",
			alt_pll_rate, rate, c->dbg_name, ret);
@@ -555,7 +556,9 @@ static int cpu_clk_8996_set_rate(struct clk *c, unsigned long rate)
	 * CPU frequency to ramp up from 384MHz to 550MHz.
	 */
	if (c->rate > 600000000 && rate < 600000000) {
		mutex_lock(&scm_lmh_lock);
		ret = clk_set_rate(c->parent, c->rate/2);
		mutex_unlock(&scm_lmh_lock);
		if (ret) {
			pr_err("failed to set rate %lu on %s (%d)\n",
				c->rate/2, c->dbg_name, ret);
@@ -563,7 +566,9 @@ static int cpu_clk_8996_set_rate(struct clk *c, unsigned long rate)
		}
	}

	mutex_lock(&scm_lmh_lock);
	ret = clk_set_rate(c->parent, rate);
	mutex_unlock(&scm_lmh_lock);
	if (ret) {
		pr_err("failed to set rate %lu on %s (%d)\n",
			rate, c->dbg_name, ret);
@@ -578,7 +583,9 @@ static int cpu_clk_8996_set_rate(struct clk *c, unsigned long rate)
set_rate_fail:
	/* Restore parent rate if we halved it */
	if (c->rate > 600000000 && rate < 600000000) {
		mutex_lock(&scm_lmh_lock);
		err_ret = clk_set_rate(c->parent, c->rate);
		mutex_unlock(&scm_lmh_lock);
		if (err_ret)
			pr_err("failed to restore %s rate to %lu\n",
			       c->dbg_name, c->rate);
@@ -586,7 +593,9 @@ set_rate_fail:

fail:
	if (cpuclk->alt_pll && (n_alt_freqs > 0)) {
		mutex_lock(&scm_lmh_lock);
		err_ret = clk_set_rate(cpuclk->alt_pll, alt_pll_prev_rate);
		mutex_unlock(&scm_lmh_lock);
		if (err_ret)
			pr_err("failed to reset rate to %lu on alt pll after failing to  set %lu on %s (%d)\n",
				alt_pll_prev_rate, rate, c->dbg_name, err_ret);
+14 −0
Original line number Diff line number Diff line
@@ -35,6 +35,13 @@

static DEFINE_MUTEX(scm_lock);

/*
 * MSM8996 V2 requires a lock to protect against
 * concurrent accesses between the limits management
 * driver and the clock controller
 */
DEFINE_MUTEX(scm_lmh_lock);

#define SCM_EBUSY_WAIT_MS 30
#define SCM_EBUSY_MAX_RETRY 20

@@ -634,6 +641,9 @@ int scm_call2(u32 fn_id, struct scm_desc *desc)
	do {
		mutex_lock(&scm_lock);

		if (SCM_SVC_ID(fn_id) == SCM_SVC_LMH)
			mutex_lock(&scm_lmh_lock);

		desc->ret[0] = desc->ret[1] = desc->ret[2] = 0;

		pr_debug("scm_call: func id %#llx, args: %#x, %#llx, %#llx, %#llx, %#llx\n",
@@ -652,6 +662,10 @@ int scm_call2(u32 fn_id, struct scm_desc *desc)
						  desc->args[2], desc->x5,
						  &desc->ret[0], &desc->ret[1],
						  &desc->ret[2]);

		if (SCM_SVC_ID(fn_id) == SCM_SVC_LMH)
			mutex_unlock(&scm_lmh_lock);

		mutex_unlock(&scm_lock);

		if (ret == SCM_V2_EBUSY)
+3 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ static char __n[PAGE_SIZE] __aligned(PAGE_SIZE);
#define SCM_SIP_FNID(s, c) (((((s) & 0xFF) << 8) | ((c) & 0xFF)) | 0x02000000)
#define SCM_QSEEOS_FNID(s, c) (((((s) & 0xFF) << 8) | ((c) & 0xFF)) | \
			      0x32000000)
#define SCM_SVC_ID(s) (((s) & 0xFF00) >> 8)

#define MAX_SCM_ARGS 10
#define MAX_SCM_RETS 3
@@ -130,6 +131,8 @@ struct scm_hdcp_req {
	u32 val;
};

extern struct mutex scm_lmh_lock;

#else

static inline int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf,