aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/cppc_acpi.c
diff options
context:
space:
mode:
authorPrashanth Prakash <pprakash@codeaurora.org>2018-04-04 14:14:51 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-04-24 06:33:28 -0400
commit6fa12d584dcba18f67425ce17e9317311a624f81 (patch)
treedeeea62992f02ba49125e04a198e136c9c487122 /drivers/acpi/cppc_acpi.c
parent4773e77cdc9b3af93ee1ae7bcf2acf94fde17166 (diff)
ACPI / CPPC: Check for valid PCC subspace only if PCC is used
Changes the behavior where we return error if there are no valid PCC subspace for a given performance domain. The ACPI spec does not mandate the use PCC, so it is possible to have platforms where a PCC subspace may not be present, so we need to check for a valid PCC subspace ID only if the register is a PCC register. Signed-off-by: Prashanth Prakash <pprakash@codeaurora.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/cppc_acpi.c')
-rw-r--r--drivers/acpi/cppc_acpi.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index 8fa3d3a6e5b6..4446fa6c820e 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -1075,15 +1075,14 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
1075 *low_freq_reg = NULL, *nom_freq_reg = NULL; 1075 *low_freq_reg = NULL, *nom_freq_reg = NULL;
1076 u64 high, low, nom, min_nonlinear, low_f = 0, nom_f = 0; 1076 u64 high, low, nom, min_nonlinear, low_f = 0, nom_f = 0;
1077 int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); 1077 int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum);
1078 struct cppc_pcc_data *pcc_ss_data; 1078 struct cppc_pcc_data *pcc_ss_data = NULL;
1079 int ret = 0, regs_in_pcc = 0; 1079 int ret = 0, regs_in_pcc = 0;
1080 1080
1081 if (!cpc_desc || pcc_ss_id < 0) { 1081 if (!cpc_desc) {
1082 pr_debug("No CPC descriptor for CPU:%d\n", cpunum); 1082 pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
1083 return -ENODEV; 1083 return -ENODEV;
1084 } 1084 }
1085 1085
1086 pcc_ss_data = pcc_data[pcc_ss_id];
1087 highest_reg = &cpc_desc->cpc_regs[HIGHEST_PERF]; 1086 highest_reg = &cpc_desc->cpc_regs[HIGHEST_PERF];
1088 lowest_reg = &cpc_desc->cpc_regs[LOWEST_PERF]; 1087 lowest_reg = &cpc_desc->cpc_regs[LOWEST_PERF];
1089 lowest_non_linear_reg = &cpc_desc->cpc_regs[LOW_NON_LINEAR_PERF]; 1088 lowest_non_linear_reg = &cpc_desc->cpc_regs[LOW_NON_LINEAR_PERF];
@@ -1095,6 +1094,11 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
1095 if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) || 1094 if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) ||
1096 CPC_IN_PCC(lowest_non_linear_reg) || CPC_IN_PCC(nominal_reg) || 1095 CPC_IN_PCC(lowest_non_linear_reg) || CPC_IN_PCC(nominal_reg) ||
1097 CPC_IN_PCC(low_freq_reg) || CPC_IN_PCC(nom_freq_reg)) { 1096 CPC_IN_PCC(low_freq_reg) || CPC_IN_PCC(nom_freq_reg)) {
1097 if (pcc_ss_id < 0) {
1098 pr_debug("Invalid pcc_ss_id\n");
1099 return -ENODEV;
1100 }
1101 pcc_ss_data = pcc_data[pcc_ss_id];
1098 regs_in_pcc = 1; 1102 regs_in_pcc = 1;
1099 down_write(&pcc_ss_data->pcc_lock); 1103 down_write(&pcc_ss_data->pcc_lock);
1100 /* Ring doorbell once to update PCC subspace */ 1104 /* Ring doorbell once to update PCC subspace */
@@ -1150,16 +1154,15 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
1150 struct cpc_register_resource *delivered_reg, *reference_reg, 1154 struct cpc_register_resource *delivered_reg, *reference_reg,
1151 *ref_perf_reg, *ctr_wrap_reg; 1155 *ref_perf_reg, *ctr_wrap_reg;
1152 int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); 1156 int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum);
1153 struct cppc_pcc_data *pcc_ss_data; 1157 struct cppc_pcc_data *pcc_ss_data = NULL;
1154 u64 delivered, reference, ref_perf, ctr_wrap_time; 1158 u64 delivered, reference, ref_perf, ctr_wrap_time;
1155 int ret = 0, regs_in_pcc = 0; 1159 int ret = 0, regs_in_pcc = 0;
1156 1160
1157 if (!cpc_desc || pcc_ss_id < 0) { 1161 if (!cpc_desc) {
1158 pr_debug("No CPC descriptor for CPU:%d\n", cpunum); 1162 pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
1159 return -ENODEV; 1163 return -ENODEV;
1160 } 1164 }
1161 1165
1162 pcc_ss_data = pcc_data[pcc_ss_id];
1163 delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR]; 1166 delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR];
1164 reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR]; 1167 reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR];
1165 ref_perf_reg = &cpc_desc->cpc_regs[REFERENCE_PERF]; 1168 ref_perf_reg = &cpc_desc->cpc_regs[REFERENCE_PERF];
@@ -1175,6 +1178,11 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
1175 /* Are any of the regs PCC ?*/ 1178 /* Are any of the regs PCC ?*/
1176 if (CPC_IN_PCC(delivered_reg) || CPC_IN_PCC(reference_reg) || 1179 if (CPC_IN_PCC(delivered_reg) || CPC_IN_PCC(reference_reg) ||
1177 CPC_IN_PCC(ctr_wrap_reg) || CPC_IN_PCC(ref_perf_reg)) { 1180 CPC_IN_PCC(ctr_wrap_reg) || CPC_IN_PCC(ref_perf_reg)) {
1181 if (pcc_ss_id < 0) {
1182 pr_debug("Invalid pcc_ss_id\n");
1183 return -ENODEV;
1184 }
1185 pcc_ss_data = pcc_data[pcc_ss_id];
1178 down_write(&pcc_ss_data->pcc_lock); 1186 down_write(&pcc_ss_data->pcc_lock);
1179 regs_in_pcc = 1; 1187 regs_in_pcc = 1;
1180 /* Ring doorbell once to update PCC subspace */ 1188 /* Ring doorbell once to update PCC subspace */
@@ -1225,15 +1233,14 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
1225 struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); 1233 struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
1226 struct cpc_register_resource *desired_reg; 1234 struct cpc_register_resource *desired_reg;
1227 int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); 1235 int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
1228 struct cppc_pcc_data *pcc_ss_data; 1236 struct cppc_pcc_data *pcc_ss_data = NULL;
1229 int ret = 0; 1237 int ret = 0;
1230 1238
1231 if (!cpc_desc || pcc_ss_id < 0) { 1239 if (!cpc_desc) {
1232 pr_debug("No CPC descriptor for CPU:%d\n", cpu); 1240 pr_debug("No CPC descriptor for CPU:%d\n", cpu);
1233 return -ENODEV; 1241 return -ENODEV;
1234 } 1242 }
1235 1243
1236 pcc_ss_data = pcc_data[pcc_ss_id];
1237 desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; 1244 desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF];
1238 1245
1239 /* 1246 /*
@@ -1244,6 +1251,11 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
1244 * achieve that goal here 1251 * achieve that goal here
1245 */ 1252 */
1246 if (CPC_IN_PCC(desired_reg)) { 1253 if (CPC_IN_PCC(desired_reg)) {
1254 if (pcc_ss_id < 0) {
1255 pr_debug("Invalid pcc_ss_id\n");
1256 return -ENODEV;
1257 }
1258 pcc_ss_data = pcc_data[pcc_ss_id];
1247 down_read(&pcc_ss_data->pcc_lock); /* BEGIN Phase-I */ 1259 down_read(&pcc_ss_data->pcc_lock); /* BEGIN Phase-I */
1248 if (pcc_ss_data->platform_owns_pcc) { 1260 if (pcc_ss_data->platform_owns_pcc) {
1249 ret = check_pcc_chan(pcc_ss_id, false); 1261 ret = check_pcc_chan(pcc_ss_id, false);