lkml.org 
[lkml]   [2019]   [Apr]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v2 2/7] acpi/cppc: Ensure only supported CPPC sysfs entries are created
Date
Add attributes for registers that are supported by the platform. This prevents
unsupported optional registers from having sysfs entries created.

Also, add a macro REG_SUPPORTED which will decide on the check to perform
based on the type of register.

Signed-off-by: Janakarajan Natarajan <Janakarajan.Natarajan@amd.com>
---
drivers/acpi/cppc_acpi.c | 100 +++++++++++++++++++++++++++++++++------
1 file changed, 86 insertions(+), 14 deletions(-)

diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index 56a09e057c4f..37157d19d2df 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -187,22 +187,8 @@ static ssize_t show_feedback_ctrs(struct kobject *kobj,
}
define_one_cppc_ro(feedback_ctrs);

-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,
- &nominal_freq.attr,
- &lowest_freq.attr,
- NULL
-};
-
static struct kobj_type cppc_ktype = {
.sysfs_ops = &kobj_sysfs_ops,
- .default_attrs = cppc_attrs,
};

static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit)
@@ -717,6 +703,87 @@ static bool is_cppc_supported(int revision, int num_ent)
* }
*/

+static bool is_buf_only(int reg_idx)
+{
+ switch (reg_idx) {
+ case HIGHEST_PERF:
+ case NOMINAL_PERF:
+ case LOW_NON_LINEAR_PERF:
+ case LOWEST_PERF:
+ case CTR_WRAP_TIME:
+ case AUTO_SEL_ENABLE:
+ case REFERENCE_PERF:
+ return false;
+ default:
+ return true;
+ }
+}
+
+#define REG_SUPPORTED(cpc, idx) (is_buf_only(idx) ? \
+ CPC_SUP_BUFFER_ONLY(&cpc->cpc_regs[idx]) : \
+ CPC_SUPPORTED(&cpc->cpc_regs[idx]))
+
+static int is_mandatory_reg(int reg_idx)
+{
+ switch (reg_idx) {
+ case HIGHEST_PERF:
+ case NOMINAL_PERF:
+ case LOW_NON_LINEAR_PERF:
+ case LOWEST_PERF:
+ case REFERENCE_CTR:
+ case DELIVERED_CTR:
+ return 1;
+ }
+
+ return 0;
+}
+
+#define MANDATORY_REG_CNT 6
+
+static int set_cppc_attrs(struct cpc_desc *cpc, int entries)
+{
+ int i, attr_i = 0, opt_reg_cnt = entries - MANDATORY_REG_CNT;
+ static struct attribute **cppc_attrs;
+
+ cppc_attrs = kcalloc(entries, sizeof(*cppc_attrs), GFP_KERNEL);
+ if (!cppc_attrs)
+ return -ENOMEM;
+
+ for (i = 0; i < MAX_CPC_REG_ENT && attr_i < opt_reg_cnt; i++) {
+ if (is_mandatory_reg(i) || !REG_SUPPORTED(cpc, i))
+ continue;
+
+ switch (i) {
+ case NOMINAL_FREQ:
+ cppc_attrs[attr_i++] = &nominal_freq.attr;
+ break;
+ case LOWEST_FREQ:
+ cppc_attrs[attr_i++] = &lowest_freq.attr;
+ break;
+ case REFERENCE_PERF:
+ cppc_attrs[attr_i++] = &reference_perf.attr;
+ break;
+ case CTR_WRAP_TIME:
+ cppc_attrs[attr_i++] = &wraparound_time.attr;
+ break;
+ }
+ }
+
+ /* Set mandatory regs */
+ cppc_attrs[attr_i++] = &highest_perf.attr;
+ cppc_attrs[attr_i++] = &nominal_perf.attr;
+ cppc_attrs[attr_i++] = &lowest_nonlinear_perf.attr;
+ cppc_attrs[attr_i++] = &lowest_perf.attr;
+
+ /* Set feedback_ctr sysfs entry */
+ cppc_attrs[attr_i] = &feedback_ctrs.attr;
+
+ /* Set kobj_type member */
+ cppc_ktype.default_attrs = cppc_attrs;
+
+ return 0;
+}
+
/**
* acpi_cppc_processor_probe - Search for per CPU _CPC objects.
* @pr: Ptr to acpi_processor containing this CPUs logical Id.
@@ -871,6 +938,10 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
/* Plug PSD data into this CPUs CPC descriptor. */
per_cpu(cpc_desc_ptr, pr->id) = cpc_ptr;

+ ret = set_cppc_attrs(cpc_ptr, num_ent - 2);
+ if (ret)
+ goto out_free;
+
ret = kobject_init_and_add(&cpc_ptr->kobj, &cppc_ktype, &cpu_dev->kobj,
"acpi_cppc");
if (ret) {
@@ -932,6 +1003,7 @@ void acpi_cppc_processor_exit(struct acpi_processor *pr)
iounmap(addr);
}

+ kfree(cppc_ktype.default_attrs);
kobject_put(&cpc_ptr->kobj);
kfree(cpc_ptr);
}
--
2.17.1
\
 
 \ /
  Last update: 2019-04-04 23:28    [W:0.255 / U:0.488 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site