Received: by 2002:ac0:aa62:0:0:0:0:0 with SMTP id w31-v6csp3290684ima; Tue, 23 Oct 2018 03:38:05 -0700 (PDT) X-Google-Smtp-Source: ACcGV60r0UA6eV+0ZXoHlezvsUA9siBRD3EjJKtmd3pUWZsjWA2jSEic5JVr7u8S+3YS9cGorzGo X-Received: by 2002:a62:5016:: with SMTP id e22-v6mr49789818pfb.30.1540291085879; Tue, 23 Oct 2018 03:38:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1540291085; cv=none; d=google.com; s=arc-20160816; b=hostkH61kVmdS/yFcIKTxAUv10lTlgDvpjrHuT9gksyVP/TacuiP3/4Pmvt8if36xI olRgt4oBuniRdH8VhU1GYYnS5cTyreaj/u1U3+g7JDBIi1RWhrBsB7h3lbP073H5jj8e WO5A2JbrrXW/Vw3MXZQz67Z1s6gWTQyZmkRy34HIVGghiVOvebmTlVBY+wU8Ss+ZdxRO Wt2+eMc+zWpaHjVzqNKHK4btOATw+KXsEjRSToNkWac6G6SQOmZK8LlV51kyat/43KtU 9TF/LrSOzG5NdeqSSnles0frll4ihE+pXW7/Rpu5ltTckq9uZ+ogg+20D5iz6b3s9pkl HKpw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from; bh=VVUU1L9xAAApIVk8/Rldt3WMBh/ZP42r71Knr/TF194=; b=fHLtOuGk2LD1TdYk4rUUjHO7zxo3e568Op0oZgeZMtCn1oZkHqrKz0vf+MPh4Z1qf8 84Yr1MDGv3zpVWlkabyHnaEyU/JMANSsrdU7wWGumpOjg18BI6kR3B32QjXRJUxy3aUC eYKU06uU7XqRm0YAyciaqhn4t1hVPcfoPWobcHCmRG4v6AhPLicGdFmcEN3aacxzATEv ikfozQjylSX4WPFhy2zbdvL048LC7TB6xsfrO7HvicUBmHAxnVgSwqIIp0h7why0RfXh n2wDDKKFy+GxLp0ujVGWsnxpqwuNWwp3WSUViZCgdyyCzTzn6aGxGnpzb5cQDsT6VqXc v8hg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 32-v6si969340plc.11.2018.10.23.03.37.50; Tue, 23 Oct 2018 03:38:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727802AbeJWS7x (ORCPT + 99 others); Tue, 23 Oct 2018 14:59:53 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:43444 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727250AbeJWS7x (ORCPT ); Tue, 23 Oct 2018 14:59:53 -0400 Received: from pps.filterd (m0098420.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w9NASg4i042137 for ; Tue, 23 Oct 2018 06:37:01 -0400 Received: from e06smtp05.uk.ibm.com (e06smtp05.uk.ibm.com [195.75.94.101]) by mx0b-001b2d01.pphosted.com with ESMTP id 2na1k2h5rg-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 23 Oct 2018 06:37:00 -0400 Received: from localhost by e06smtp05.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 23 Oct 2018 11:36:59 +0100 Received: from b06cxnps3075.portsmouth.uk.ibm.com (9.149.109.195) by e06smtp05.uk.ibm.com (192.168.101.135) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Tue, 23 Oct 2018 11:36:58 +0100 Received: from d06av26.portsmouth.uk.ibm.com (d06av26.portsmouth.uk.ibm.com [9.149.105.62]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w9NAavIb27787366 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 23 Oct 2018 10:36:57 GMT Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 07E73AE045; Tue, 23 Oct 2018 10:36:57 +0000 (GMT) Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 17DE7AE053; Tue, 23 Oct 2018 10:36:56 +0000 (GMT) Received: from oc4502181600.in.ibm.com (unknown [9.124.35.202]) by d06av26.portsmouth.uk.ibm.com (Postfix) with ESMTP; Tue, 23 Oct 2018 10:36:55 +0000 (GMT) From: Shilpasri G Bhat To: mpe@ellerman.id.au Cc: linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, ego@linux.vnet.ibm.com, Shilpasri G Bhat Subject: [PATCH v2] powernv: sensor-groups: Add debugfs file to enable/disable sensor groups Date: Tue, 23 Oct 2018 16:06:30 +0530 X-Mailer: git-send-email 1.8.3.1 X-TM-AS-GCONF: 00 x-cbid: 18102310-0020-0000-0000-000002D8D037 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18102310-0021-0000-0000-00002127F166 Message-Id: <1540290990-22503-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2018-10-23_03:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1807170000 definitions=main-1810230094 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch provides support to disable and enable platform specific sensor groups like performance, utilization and frequency which are currently not supported in hwmon. Signed-off-by: Shilpasri G Bhat --- Changes from V1: - As per Michael Ellerman's suggestion, adding the "enable" files to debugfs. The original code had been written in mind to accomodate the "enable" file in the same path as "clear" attribute. As this is not required anymore the code is cleaned up to bifurcate the functions adding "enable" and "clear" attribute. .../powerpc/platforms/powernv/opal-sensor-groups.c | 284 ++++++++++++++------- 1 file changed, 186 insertions(+), 98 deletions(-) diff --git a/arch/powerpc/platforms/powernv/opal-sensor-groups.c b/arch/powerpc/platforms/powernv/opal-sensor-groups.c index f7d04b6..e270dba 100644 --- a/arch/powerpc/platforms/powernv/opal-sensor-groups.c +++ b/arch/powerpc/platforms/powernv/opal-sensor-groups.c @@ -15,22 +15,21 @@ #include #include +#include #include -DEFINE_MUTEX(sg_mutex); +#define SENSOR_GROUPS_DIR_STR "sensor_groups" static struct kobject *sg_kobj; -struct sg_attr { - u32 handle; - struct kobj_attribute attr; -}; - static struct sensor_group { - char name[20]; + struct kobj_attribute sattr; struct attribute_group sg; - struct sg_attr *sgattrs; -} *sgs; + struct mutex mutex; + char name[20]; + u32 handle; + u32 enable; +} *sgroups; int sensor_group_enable(u32 handle, bool enable) { @@ -60,10 +59,12 @@ int sensor_group_enable(u32 handle, bool enable) } EXPORT_SYMBOL_GPL(sensor_group_enable); -static ssize_t sg_store(struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t count) +static ssize_t sgroup_clear_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) { - struct sg_attr *sattr = container_of(attr, struct sg_attr, attr); + struct sensor_group *sgroup = container_of(attr, struct sensor_group, + sattr); struct opal_msg msg; u32 data; int ret, token; @@ -81,11 +82,11 @@ static ssize_t sg_store(struct kobject *kobj, struct kobj_attribute *attr, return token; } - ret = mutex_lock_interruptible(&sg_mutex); + ret = mutex_lock_interruptible(&sgroup->mutex); if (ret) goto out_token; - ret = opal_sensor_group_clear(sattr->handle, token); + ret = opal_sensor_group_clear(sgroup->handle, token); switch (ret) { case OPAL_ASYNC_COMPLETION: ret = opal_async_wait_response(token, &msg); @@ -106,135 +107,222 @@ static ssize_t sg_store(struct kobject *kobj, struct kobj_attribute *attr, } out: - mutex_unlock(&sg_mutex); + mutex_unlock(&sgroup->mutex); out_token: opal_async_release_token(token); return ret; } -static struct sg_ops_info { - int opal_no; - const char *attr_name; - ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t count); -} ops_info[] = { - { OPAL_SENSOR_GROUP_CLEAR, "clear", sg_store }, -}; +static int find_nr_groups(struct device_node *sensor_group_node, int opal_no) +{ + struct devce_node *node; + int count = 0; + + for_each_child_of_node(sensor_group_node, node) { + u32 sgid, op; + + if (of_device_is_compatible(node, "ibm,opal-sensor")) + continue; + + if (of_property_read_u32(node, "ops", &op)) + continue; + + if (op != opal_no) + continue; + + if (of_property_read_u32(node, "sensor-group-id", &sgid)) + continue; + count++; + } + + return count; +} -static void add_attr(int handle, struct sg_attr *attr, int index) +#ifdef CONFIG_DEBUG_FS +static int sgroup_enable_get(void *data, u64 *val) { - attr->handle = handle; - sysfs_attr_init(&attr->attr.attr); - attr->attr.attr.name = ops_info[index].attr_name; - attr->attr.attr.mode = 0220; - attr->attr.store = ops_info[index].store; + struct sensor_group *sgroup = (struct sensor_group *)data; + + *val = sgroup->enable; + return 0; } -static int add_attr_group(const __be32 *ops, int len, struct sensor_group *sg, - u32 handle) +static int sgroup_enable_set(void *data, u64 val) { - int i, j; - int count = 0; + struct sensor_group *sgroup = (struct sensor_group *)data; + int rc; + + if (val != 0 && val != 1) + return -EINVAL; + + rc = mutex_lock_interruptible(&sgroup->mutex); + if (rc) + return rc; - for (i = 0; i < len; i++) - for (j = 0; j < ARRAY_SIZE(ops_info); j++) - if (be32_to_cpu(ops[i]) == ops_info[j].opal_no) { - add_attr(handle, &sg->sgattrs[count], j); - sg->sg.attrs[count] = - &sg->sgattrs[count].attr.attr; - count++; - } + if (val != sgroup->enable) { + rc = sensor_group_enable(sgroup->handle, val); + if (!rc) + sgroup->enable = val; + } - return sysfs_create_group(sg_kobj, &sg->sg); + mutex_unlock(&sgroup->mutex); + return rc; } -static int get_nr_attrs(const __be32 *ops, int len) +DEFINE_DEBUGFS_ATTRIBUTE(sensor_debugfs_ops, sgroup_enable_get, + sgroup_enable_set, "%llx\n"); +static struct dentry *sensor_debugfs_parent; +static struct sensor_group *dgroups; + +static void add_debugfs_attrs(struct device_node *sensor_group_node) { - int i, j; - int nr_attrs = 0; + struct device_node *node; + int i = 0, count; + + count = find_nr_groups(sensor_group_node, OPAL_SENSOR_GROUP_ENABLE); + if (!count) + return; - for (i = 0; i < len; i++) - for (j = 0; j < ARRAY_SIZE(ops_info); j++) - if (be32_to_cpu(ops[i]) == ops_info[j].opal_no) - nr_attrs++; + dgroups = kcalloc(count, sizeof(*dgroups), GFP_KERNEL); + if (!sgroups) + return; + + sensor_debugfs_parent = debugfs_create_dir(SENSOR_GROUPS_DIR_STR, + powerpc_debugfs_root); + if (!sensor_debugfs_parent) + goto out_dgroups; - return nr_attrs; + for_each_child_of_node(sensor_group_node, node) { + struct dentry *group; + u32 op, sgid, chipid; + + if (of_device_is_compatible(node, "ibm,opal-sensor")) + continue; + + if (of_property_read_u32(node, "ops", &op)) + continue; + + if (op != OPAL_SENSOR_GROUP_ENABLE) + continue; + + if (of_property_read_u32(node, "sensor-group-id", &sgid)) + continue; + + if (!of_property_read_u32(node, "ibm,chip-id", &chipid)) + sprintf(dgroups[i].name, "%s%d", node->name, chipid); + else + sprintf(dgroups[i].name, "%s", node->name); + + dgroups[i].handle = sgid; + dgroups[i].enable = 1; + mutex_init(&dgroups[i].mutex); + group = debugfs_create_dir(dgroups[i].name, + sensor_debugfs_parent); + if (!group) { + of_node_put(node); + goto out_debugfs; + } + + if (!debugfs_create_file("enable", 0664, group, &dgroups[i], + &sensor_debugfs_ops)) { + of_node_put(node); + goto out_debugfs; + } + i++; + } + + return; + +out_debugfs: + debugfs_remove_recursive(sensor_debugfs_parent); +out_dgroups: + kfree(dgroups); } +#endif /* CONFIG_DEBUG_FS */ void __init opal_sensor_groups_init(void) { - struct device_node *sg, *node; - int i = 0; + struct device_node *sensor_group_node, *node; + int i = 0, count; - sg = of_find_compatible_node(NULL, NULL, "ibm,opal-sensor-group"); - if (!sg) { + sensor_group_node = of_find_compatible_node(NULL, NULL, + "ibm,opal-sensor-group"); + if (!sensor_group_node) { pr_devel("Sensor groups node not found\n"); return; } - sgs = kcalloc(of_get_child_count(sg), sizeof(*sgs), GFP_KERNEL); - if (!sgs) - return; + count = find_nr_groups(sensor_group_node, OPAL_SENSOR_GROUP_CLEAR); + if (!count) + goto out_node_put; - sg_kobj = kobject_create_and_add("sensor_groups", opal_kobj); + sgroups = kcalloc(count, sizeof(*sgroups), GFP_KERNEL); + if (!sgroups) + goto out_node_put; + + sg_kobj = kobject_create_and_add(SENSOR_GROUPS_DIR_STR, opal_kobj); if (!sg_kobj) { pr_warn("Failed to create sensor group kobject\n"); - goto out_sgs; + goto out_sgroups; } - for_each_child_of_node(sg, node) { - const __be32 *ops; - u32 sgid, len, nr_attrs, chipid; + for_each_child_of_node(sensor_group_node, node) { + u32 sgid, chipid, op; - ops = of_get_property(node, "ops", &len); - if (!ops) + if (of_property_read_u32(node, "ops", &op)) continue; - nr_attrs = get_nr_attrs(ops, len); - if (!nr_attrs) + if (op != OPAL_SENSOR_GROUP_CLEAR) continue; - sgs[i].sgattrs = kcalloc(nr_attrs, sizeof(*sgs[i].sgattrs), - GFP_KERNEL); - if (!sgs[i].sgattrs) - goto out_sgs_sgattrs; - - sgs[i].sg.attrs = kcalloc(nr_attrs + 1, - sizeof(*sgs[i].sg.attrs), - GFP_KERNEL); - - if (!sgs[i].sg.attrs) { - kfree(sgs[i].sgattrs); - goto out_sgs_sgattrs; - } - - if (of_property_read_u32(node, "sensor-group-id", &sgid)) { - pr_warn("sensor-group-id property not found\n"); - goto out_sgs_sgattrs; - } + if (of_property_read_u32(node, "sensor-group-id", &sgid)) + continue; if (!of_property_read_u32(node, "ibm,chip-id", &chipid)) - sprintf(sgs[i].name, "%s%d", node->name, chipid); + sprintf(sgroups[i].name, "%s%d", node->name, chipid); else - sprintf(sgs[i].name, "%s", node->name); + sprintf(sgroups[i].name, "%s", node->name); + + sgroups[i].sg.attrs = kzalloc(sizeof(struct attribute *) * 2, + GFP_KERNEL); + if (!sgroups[i].sg.attrs) { + of_node_put(node); + goto out_sg_attrs; + } - sgs[i].sg.name = sgs[i].name; - if (add_attr_group(ops, len, &sgs[i], sgid)) { + sgroups[i].sg.name = sgroups[i].name; + sgroups[i].handle = sgid; + sysfs_attr_init(sgroups[i].sattr.attr); + sgroups[i].sattr.attr.name = "clear"; + sgroups[i].sattr.attr.mode = 0220; + sgroups[i].sattr.store = sgroup_clear_store; + sgroups[i].sg.attrs[0] = &sgroups[i].sattr.attr; + sgroups[i].sg.attrs[1] = NULL; + mutex_init(&sgroups[i].mutex); + + if (sysfs_create_group(sg_kobj, &sgroups[i].sg)) { pr_warn("Failed to create sensor attribute group %s\n", - sgs[i].sg.name); - goto out_sgs_sgattrs; + sgroups[i].sg.name); + kfree(sgroups[i].sg.attrs); + of_node_put(node); + goto out_sg_attrs; } + i++; } - return; +#ifdef CONFIG_DEBUG_FS + add_debugfs_attrs(sensor_group_node); +#endif /* CONFIG_DEBUG_FS */ -out_sgs_sgattrs: - while (--i >= 0) { - kfree(sgs[i].sgattrs); - kfree(sgs[i].sg.attrs); - } + goto out_node_put; + +out_sg_attrs: + while (i-- > 0) + kfree(sgroups[i].sg.attrs); kobject_put(sg_kobj); -out_sgs: - kfree(sgs); +out_sgroups: + kfree(sgroups); +out_node_put: + of_node_put(sensor_group_node); } -- 1.8.3.1