Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 1 Dec 2018 21:37:47 +0000 (UTC)
From:      Conrad Meyer <cem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r341389 - head/sys/powerpc/cpufreq
Message-ID:  <201812012137.wB1Lbljo001622@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cem
Date: Sat Dec  1 21:37:47 2018
New Revision: 341389
URL: https://svnweb.freebsd.org/changeset/base/341389

Log:
  pmcr: Fix pstate setting on Power8
  
  Fix p-state setting on Power8 by removing the accidental double-indirection of
  the pstate_ids table.
  
  The pstate_ids table comes from the OF property "ibm,pstate-ids."  On Power9,
  the values happen to be identical to the indices, so the extra indirection was
  harmless.  On Power8, the values were out of the range [0, npstates], so
  pmcr_set() would fail the spec[0] range check with EINVAL.
  
  While here, include both the value and index in the driver-specific register
  array as spec[0] and spec[1] respectively.  They're redundant, but relatively
  harmless, and it may aid debugging.
  
  While here, fix the range check to exclude the index npstates, which is one
  past the last valid index.
  
  PR:		233693
  Reported and tested by:	sbruno
  Reviewed by:	jhibbits

Modified:
  head/sys/powerpc/cpufreq/pmcr.c

Modified: head/sys/powerpc/cpufreq/pmcr.c
==============================================================================
--- head/sys/powerpc/cpufreq/pmcr.c	Sat Dec  1 21:28:05 2018	(r341388)
+++ head/sys/powerpc/cpufreq/pmcr.c	Sat Dec  1 21:37:47 2018	(r341389)
@@ -174,6 +174,7 @@ pmcr_settings(device_t dev, struct cf_setting *sets, i
 	for (i = 0; i < npstates; i++) {
 		sets[i].freq = pstate_freqs[i];
 		sets[i].spec[0] = pstate_ids[i];
+		sets[i].spec[1] = i;
 		sets[i].dev = dev;
 	}
 	*count = npstates;
@@ -189,13 +190,11 @@ pmcr_set(device_t dev, const struct cf_setting *set)
 	if (set == NULL)
 		return (EINVAL);
 
-	if (set->spec[0] < 0 || set->spec[0] > npstates)
+	if (set->spec[1] < 0 || set->spec[1] >= npstates)
 		return (EINVAL);
 
-	pmcr = ((long)pstate_ids[set->spec[0]] << PMCR_LOWERPS_SHIFT) &
-	    PMCR_LOWERPS_MASK;
-	pmcr |= ((long)pstate_ids[set->spec[0]] << PMCR_UPPERPS_SHIFT) &
-	    PMCR_UPPERPS_MASK;
+	pmcr = ((long)set->spec[0] << PMCR_LOWERPS_SHIFT) & PMCR_LOWERPS_MASK;
+	pmcr |= ((long)set->spec[0] << PMCR_UPPERPS_SHIFT) & PMCR_UPPERPS_MASK;
 	pmcr |= PMCR_VERSION_1;
 
 	mtspr(SPR_PMCR, pmcr);
@@ -228,6 +227,7 @@ pmcr_get(device_t dev, struct cf_setting *set)
 		return (EINVAL);
 
 	set->spec[0] = pstate;
+	set->spec[1] = i;
 	set->freq = pstate_freqs[i];
 
 	set->dev = dev;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201812012137.wB1Lbljo001622>