aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/cppc_acpi.c
diff options
context:
space:
mode:
authorPrakash, Prashanth <pprakash@codeaurora.org>2017-03-29 15:50:00 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-04-18 17:37:50 -0400
commit2c74d8473d19c159a3c3eabaa4819e110c97e8ec (patch)
tree96e7bf41aea73ffb20f2fd2148d456a1f0d0762d /drivers/acpi/cppc_acpi.c
parent368520a6b2dd232ea5743a6acd9f056bc30e05b4 (diff)
ACPI / CPPC: add sysfs entries for CPPC perf capabilities
Computed delivered performance using CPPC feedback counters are in the CPPC abstract scale, whereas cppc_cpufreq driver operates in KHz scale. Exposing the CPPC performance capabilities (highest,lowest, nominal, lowest non-linear) will allow userspace to figure out the conversion factor from CPPC abstract scale to KHz. Also rename ctr_wrap_time to wraparound_time so that show_cppc_data() macro will work with it. 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.c61
1 files changed, 33 insertions, 28 deletions
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index ee00a1c94ff6..6cbe6036da99 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -132,49 +132,54 @@ __ATTR(_name, 0444, show_##_name, NULL)
132 132
133#define to_cpc_desc(a) container_of(a, struct cpc_desc, kobj) 133#define to_cpc_desc(a) container_of(a, struct cpc_desc, kobj)
134 134
135#define show_cppc_data(access_fn, struct_name, member_name) \
136 static ssize_t show_##member_name(struct kobject *kobj, \
137 struct attribute *attr, char *buf) \
138 { \
139 struct cpc_desc *cpc_ptr = to_cpc_desc(kobj); \
140 struct struct_name st_name = {0}; \
141 int ret; \
142 \
143 ret = access_fn(cpc_ptr->cpu_id, &st_name); \
144 if (ret) \
145 return ret; \
146 \
147 return scnprintf(buf, PAGE_SIZE, "%llu\n", \
148 (u64)st_name.member_name); \
149 } \
150 define_one_cppc_ro(member_name)
151
152show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, highest_perf);
153show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_perf);
154show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_perf);
155show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_nonlinear_perf);
156show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, reference_perf);
157show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time);
158
135static ssize_t show_feedback_ctrs(struct kobject *kobj, 159static ssize_t show_feedback_ctrs(struct kobject *kobj,
136 struct attribute *attr, char *buf) 160 struct attribute *attr, char *buf)
137{ 161{
138 struct cpc_desc *cpc_ptr = to_cpc_desc(kobj); 162 struct cpc_desc *cpc_ptr = to_cpc_desc(kobj);
139 struct cppc_perf_fb_ctrs fb_ctrs = {0}; 163 struct cppc_perf_fb_ctrs fb_ctrs = {0};
164 int ret;
140 165
141 cppc_get_perf_ctrs(cpc_ptr->cpu_id, &fb_ctrs); 166 ret = cppc_get_perf_ctrs(cpc_ptr->cpu_id, &fb_ctrs);
167 if (ret)
168 return ret;
142 169
143 return scnprintf(buf, PAGE_SIZE, "ref:%llu del:%llu\n", 170 return scnprintf(buf, PAGE_SIZE, "ref:%llu del:%llu\n",
144 fb_ctrs.reference, fb_ctrs.delivered); 171 fb_ctrs.reference, fb_ctrs.delivered);
145} 172}
146define_one_cppc_ro(feedback_ctrs); 173define_one_cppc_ro(feedback_ctrs);
147 174
148static ssize_t show_reference_perf(struct kobject *kobj,
149 struct attribute *attr, char *buf)
150{
151 struct cpc_desc *cpc_ptr = to_cpc_desc(kobj);
152 struct cppc_perf_fb_ctrs fb_ctrs = {0};
153
154 cppc_get_perf_ctrs(cpc_ptr->cpu_id, &fb_ctrs);
155
156 return scnprintf(buf, PAGE_SIZE, "%llu\n",
157 fb_ctrs.reference_perf);
158}
159define_one_cppc_ro(reference_perf);
160
161static ssize_t show_wraparound_time(struct kobject *kobj,
162 struct attribute *attr, char *buf)
163{
164 struct cpc_desc *cpc_ptr = to_cpc_desc(kobj);
165 struct cppc_perf_fb_ctrs fb_ctrs = {0};
166
167 cppc_get_perf_ctrs(cpc_ptr->cpu_id, &fb_ctrs);
168
169 return scnprintf(buf, PAGE_SIZE, "%llu\n", fb_ctrs.ctr_wrap_time);
170
171}
172define_one_cppc_ro(wraparound_time);
173
174static struct attribute *cppc_attrs[] = { 175static struct attribute *cppc_attrs[] = {
175 &feedback_ctrs.attr, 176 &feedback_ctrs.attr,
176 &reference_perf.attr, 177 &reference_perf.attr,
177 &wraparound_time.attr, 178 &wraparound_time.attr,
179 &highest_perf.attr,
180 &lowest_perf.attr,
181 &lowest_nonlinear_perf.attr,
182 &nominal_perf.attr,
178 NULL 183 NULL
179}; 184};
180 185
@@ -1086,7 +1091,7 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
1086 perf_fb_ctrs->delivered = delivered; 1091 perf_fb_ctrs->delivered = delivered;
1087 perf_fb_ctrs->reference = reference; 1092 perf_fb_ctrs->reference = reference;
1088 perf_fb_ctrs->reference_perf = ref_perf; 1093 perf_fb_ctrs->reference_perf = ref_perf;
1089 perf_fb_ctrs->ctr_wrap_time = ctr_wrap_time; 1094 perf_fb_ctrs->wraparound_time = ctr_wrap_time;
1090out_err: 1095out_err:
1091 if (regs_in_pcc) 1096 if (regs_in_pcc)
1092 up_write(&pcc_data.pcc_lock); 1097 up_write(&pcc_data.pcc_lock);