ACPI / CPPC: add sysfs entries for CPPC perf capabilities
authorPrakash, Prashanth <pprakash@codeaurora.org>
Wed, 29 Mar 2017 19:50:00 +0000 (13:50 -0600)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 18 Apr 2017 21:37:50 +0000 (23:37 +0200)
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>
drivers/acpi/cppc_acpi.c
include/acpi/cppc_acpi.h

index ee00a1c94ff66e87ec14edd2f7d025e832651009..6cbe6036da998faabfd9977ccc5af1594d7af7d0 100644 (file)
@@ -132,49 +132,54 @@ __ATTR(_name, 0444, show_##_name, NULL)
 
 #define to_cpc_desc(a) container_of(a, struct cpc_desc, kobj)
 
+#define show_cppc_data(access_fn, struct_name, member_name)            \
+       static ssize_t show_##member_name(struct kobject *kobj,         \
+                                       struct attribute *attr, char *buf) \
+       {                                                               \
+               struct cpc_desc *cpc_ptr = to_cpc_desc(kobj);           \
+               struct struct_name st_name = {0};                       \
+               int ret;                                                \
+                                                                       \
+               ret = access_fn(cpc_ptr->cpu_id, &st_name);             \
+               if (ret)                                                \
+                       return ret;                                     \
+                                                                       \
+               return scnprintf(buf, PAGE_SIZE, "%llu\n",              \
+                               (u64)st_name.member_name);              \
+       }                                                               \
+       define_one_cppc_ro(member_name)
+
+show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, highest_perf);
+show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_perf);
+show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_perf);
+show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_nonlinear_perf);
+show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, reference_perf);
+show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time);
+
 static ssize_t show_feedback_ctrs(struct kobject *kobj,
                struct attribute *attr, char *buf)
 {
        struct cpc_desc *cpc_ptr = to_cpc_desc(kobj);
        struct cppc_perf_fb_ctrs fb_ctrs = {0};
+       int ret;
 
-       cppc_get_perf_ctrs(cpc_ptr->cpu_id, &fb_ctrs);
+       ret = cppc_get_perf_ctrs(cpc_ptr->cpu_id, &fb_ctrs);
+       if (ret)
+               return ret;
 
        return scnprintf(buf, PAGE_SIZE, "ref:%llu del:%llu\n",
                        fb_ctrs.reference, fb_ctrs.delivered);
 }
 define_one_cppc_ro(feedback_ctrs);
 
-static ssize_t show_reference_perf(struct kobject *kobj,
-               struct attribute *attr, char *buf)
-{
-       struct cpc_desc *cpc_ptr = to_cpc_desc(kobj);
-       struct cppc_perf_fb_ctrs fb_ctrs = {0};
-
-       cppc_get_perf_ctrs(cpc_ptr->cpu_id, &fb_ctrs);
-
-       return scnprintf(buf, PAGE_SIZE, "%llu\n",
-                       fb_ctrs.reference_perf);
-}
-define_one_cppc_ro(reference_perf);
-
-static ssize_t show_wraparound_time(struct kobject *kobj,
-                               struct attribute *attr, char *buf)
-{
-       struct cpc_desc *cpc_ptr = to_cpc_desc(kobj);
-       struct cppc_perf_fb_ctrs fb_ctrs = {0};
-
-       cppc_get_perf_ctrs(cpc_ptr->cpu_id, &fb_ctrs);
-
-       return scnprintf(buf, PAGE_SIZE, "%llu\n", fb_ctrs.ctr_wrap_time);
-
-}
-define_one_cppc_ro(wraparound_time);
-
 static struct attribute *cppc_attrs[] = {
        &feedback_ctrs.attr,
        &reference_perf.attr,
        &wraparound_time.attr,
+       &highest_perf.attr,
+       &lowest_perf.attr,
+       &lowest_nonlinear_perf.attr,
+       &nominal_perf.attr,
        NULL
 };
 
@@ -1086,7 +1091,7 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
        perf_fb_ctrs->delivered = delivered;
        perf_fb_ctrs->reference = reference;
        perf_fb_ctrs->reference_perf = ref_perf;
-       perf_fb_ctrs->ctr_wrap_time = ctr_wrap_time;
+       perf_fb_ctrs->wraparound_time = ctr_wrap_time;
 out_err:
        if (regs_in_pcc)
                up_write(&pcc_data.pcc_lock);
index 34e9680c55db446ebf40410937013e51c46bf855..2010c0516f273f05185d8131b363996c37d68903 100644 (file)
@@ -116,7 +116,7 @@ struct cppc_perf_fb_ctrs {
        u64 reference;
        u64 delivered;
        u64 reference_perf;
-       u64 ctr_wrap_time;
+       u64 wraparound_time;
 };
 
 /* Per CPU container for runtime CPPC management. */