diff options
author | Prakash, Prashanth <pprakash@codeaurora.org> | 2017-03-29 15:50:00 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-04-18 17:37:50 -0400 |
commit | 2c74d8473d19c159a3c3eabaa4819e110c97e8ec (patch) | |
tree | 96e7bf41aea73ffb20f2fd2148d456a1f0d0762d /drivers/acpi/cppc_acpi.c | |
parent | 368520a6b2dd232ea5743a6acd9f056bc30e05b4 (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.c | 61 |
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 | |||
152 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, highest_perf); | ||
153 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_perf); | ||
154 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_perf); | ||
155 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_nonlinear_perf); | ||
156 | show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, reference_perf); | ||
157 | show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time); | ||
158 | |||
135 | static ssize_t show_feedback_ctrs(struct kobject *kobj, | 159 | static 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 | } |
146 | define_one_cppc_ro(feedback_ctrs); | 173 | define_one_cppc_ro(feedback_ctrs); |
147 | 174 | ||
148 | static 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 | } | ||
159 | define_one_cppc_ro(reference_perf); | ||
160 | |||
161 | static 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 | } | ||
172 | define_one_cppc_ro(wraparound_time); | ||
173 | |||
174 | static struct attribute *cppc_attrs[] = { | 175 | static 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; |
1090 | out_err: | 1095 | out_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); |