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

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

diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index c43de65531ae..53a9dc9960b6 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -183,22 +183,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)
@@ -733,6 +719,69 @@ static bool is_buf_only(int reg_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;
+ static struct attribute **cppc_attrs;
+
+ cppc_attrs = kcalloc(entries, sizeof(*cppc_attrs), GFP_KERNEL);
+ if (!cppc_attrs)
+ return -ENOMEM;
+
+ /* Set optional regs */
+ opt_reg_cnt = entries - MANDATORY_REG_CNT;
+ 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 CPU's logical ID.
@@ -887,6 +936,10 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
/* Plug PSD data into this CPU's 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) {
@@ -948,6 +1001,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-07-10 20:38    [W:0.065 / U:28.252 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site