[{"id":1761153,"web_url":"http://patchwork.ozlabs.org/comment/1761153/","msgid":"<ada8076c-bed0-35df-4499-f0cfd5eab503@linux.vnet.ibm.com>","list_archive_url":null,"date":"2017-08-31T16:12:02","subject":"Re: [PATCH linux dev-4.10 v6 3/3] hwmon: (ucd9000) Add debugfs to\n\tlist mfr_status info","submitter":{"id":70582,"url":"http://patchwork.ozlabs.org/api/people/70582/","name":"Matt Spinler","email":"mspinler@linux.vnet.ibm.com"},"content":"Tested-by: Matt Spinler mspinler@linux.vnet.ibm.com\n\n\nOn 8/30/2017 4:49 PM, Christopher Bostic wrote:\n> Expose via files in debugfs the gpiN_fault fields as well as\n> the entire contents of the mfr_status register.  Allows user\n> space to pull this data for error logging etc...\n>\n> Signed-off-by: Christopher Bostic <cbostic@linux.vnet.ibm.com>\n> ---\n> v6 - Remove chip idx values on remove so that we can retain the\n>       same indexes regardless how many times we're bound/unbound.\n>     - Remove type 90160 check when adding debugfs.\n> v5 - Add unique debugfs dir ID for each ucd9000 sysfs device.\n>     - Change branching return to a !! method.\n>     - Clean up line breaks, other white space.\n>     - Add comments on assumptions made regarding ucd90160 versus other\n>       types.\n> v2 - Remove mfr_status directory in debugfs and place the files\n>       up in the parent ucd9000 directory.\n> ---\n>   drivers/hwmon/pmbus/ucd9000.c | 160 +++++++++++++++++++++++++++++++++++++++++-\n>   1 file changed, 159 insertions(+), 1 deletion(-)\n>\n> diff --git a/drivers/hwmon/pmbus/ucd9000.c b/drivers/hwmon/pmbus/ucd9000.c\n> index 61abd3a..d5c310f 100644\n> --- a/drivers/hwmon/pmbus/ucd9000.c\n> +++ b/drivers/hwmon/pmbus/ucd9000.c\n> @@ -19,6 +19,7 @@\n>    * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n>    */\n>\n> +#include <linux/debugfs.h>\n>   #include <linux/kernel.h>\n>   #include <linux/module.h>\n>   #include <linux/init.h>\n> @@ -29,6 +30,7 @@\n>   #include <linux/sysfs.h>\n>   #include <linux/hwmon-sysfs.h>\n>   #include <linux/gpio.h>\n> +#include <linux/idr.h>\n>   #include \"pmbus.h\"\n>\n>   enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd9090, ucd90910 };\n> @@ -38,6 +40,7 @@\n>   #define UCD9000_FAN_CONFIG_INDEX\t0xe7\n>   #define UCD9000_FAN_CONFIG\t\t0xe8\n>   #define UCD9000_LOGGED_FAULTS\t\t0xea\n> +#define UCD9000_MFR_STATUS\t\t0xf3\n>   #define UCD9000_GPIO_SELECT\t\t0xfa\n>   #define UCD9000_GPIO_CONFIG\t\t0xfb\n>   #define UCD9000_DEVICE_ID\t\t0xfd\n> @@ -59,17 +62,29 @@\n>   #define UCD9000_MON_VOLTAGE_HW\t4\n>\n>   #define UCD9000_NUM_FAN\t\t4\n> +#define UCD9000_NAME_SIZE\t24\n>\n>   #define UCD9000_GPIO_NAME_LEN\t16\n>   #define UCD90160_NUM_GPIOS\t26\n> +#define UCD90160_GPI_COUNT\t8\n> +#define UCD90160_GPI_FAULT_BASE\t16\n> +\n> +static DEFINE_IDA(ucd9000_ida);\n>\n>   struct ucd9000_data {\n>   \tu8 fan_data[UCD9000_NUM_FAN][I2C_SMBUS_BLOCK_MAX];\n>   \tstruct pmbus_driver_info info;\n>   \tstruct gpio_chip gpio;\n> +\tstruct dentry *debugfs;\n> +\tint idx;\n>   };\n>   #define to_ucd9000_data(_info) container_of(_info, struct ucd9000_data, info)\n>\n> +struct ucd9000_debugfs_entry {\n> +\tstruct i2c_client *client;\n> +\tu8 index;\n> +};\n> +\n>   static int ucd9000_get_fan_config(struct i2c_client *client, int fan)\n>   {\n>   \tint fan_config = 0;\n> @@ -297,6 +312,140 @@ static int ucd9000_gpio_direction_output(struct gpio_chip *gc,\n>   \treturn ucd9000_gpio_set_direction(gc, offset, UCD9000_GPIO_OUTPUT, val);\n>   }\n>\n> +static struct dentry *ucd9000_debugfs_dir;\n> +\n> +#if IS_ENABLED(CONFIG_DEBUG_FS)\n> +static int ucd9000_get_mfr_status(struct i2c_client *client, u32 *buffer)\n> +{\n> +\tint ret;\n> +\n> +\tret = pmbus_set_page(client, 0);\n> +\tif (ret < 0) {\n> +\t\tdev_err(&client->dev, \"pmbus_set_page failed. rc:%d\\n\", ret);\n> +\n> +\t\treturn ret;\n> +\t}\n> +\n> +\t/*\n> +\t * Warning:\n> +\t *\n> +\t * Though not currently supported this will cause stack corruption for\n> +\t * ucd90240!  Command reference, page 81:\n> +\t *\n> +\t *    With the ucd90120 and ucd90124 devices, this command [MFR_STATUS]\n> +\t *    is 2 bytes long (bits 0-15).  With the ucd90240 this command is 5\n> +\t *    bytes long.  With all other devices, it is 4 bytes long.\n> +\t */\n> +\treturn i2c_smbus_read_block_data(client, UCD9000_MFR_STATUS,\n> +\t\t\t\t\t(u8 *)buffer);\n> +}\n> +\n> +static int ucd9000_debugfs_get_mfr_status_bit(void *data, u64 *val)\n> +{\n> +\tstruct ucd9000_debugfs_entry *entry = data;\n> +\tstruct i2c_client *client = entry->client;\n> +\tint nr = entry->index;\n> +\tu32 buffer;\n> +\tint ret;\n> +\n> +\tret = ucd9000_get_mfr_status(client, &buffer);\n> +\tif (ret < 0) {\n> +\t\tdev_err(&client->dev, \"Failed to read mfr status. rc:%d\\n\",\n> +\t\t\tret);\n> +\n> +\t\treturn ret;\n> +\t}\n> +\n> +\t*val = !!(ret & BIT(nr));\n> +\n> +\treturn 0;\n> +}\n> +DEFINE_DEBUGFS_ATTRIBUTE(ucd9000_debugfs_ops_mfr_status_bit,\n> +\t\tucd9000_debugfs_get_mfr_status_bit, NULL, \"%1lld\\n\");\n> +\n> +static int ucd9000_debugfs_get_mfr_status_word(void *data, u64 *val)\n> +{\n> +\tstruct ucd9000_debugfs_entry *entry = data;\n> +\tstruct i2c_client *client = entry->client;\n> +\tu32 buffer;\n> +\tint ret;\n> +\n> +\tret = ucd9000_get_mfr_status(client, &buffer);\n> +\tif (ret < 0) {\n> +\t\tdev_err(&client->dev, \"Failed to read mfr status. rc:%d\\n\",\n> +\t\t\tret);\n> +\n> +\t\treturn ret;\n> +\t}\n> +\n> +\t*val = ret;\n> +\n> +\treturn 0;\n> +}\n> +DEFINE_DEBUGFS_ATTRIBUTE(ucd9000_debugfs_ops_mfr_status_word,\n> +\t\tucd9000_debugfs_get_mfr_status_word, NULL, \"%08llx\\n\");\n> +\n> +static int ucd9000_init_debugfs(struct i2c_client *client,\n> +\t\t\t\tstruct ucd9000_data *data)\n> +{\n> +\tstruct ucd9000_debugfs_entry *entries;\n> +\tchar name[UCD9000_NAME_SIZE];\n> +\tint i;\n> +\n> +\tdata->idx = ida_simple_get(&ucd9000_ida, 0, INT_MAX, GFP_KERNEL);\n> +\tscnprintf(name, UCD9000_NAME_SIZE, \"ucd9000.%d\", data->idx);\n> +\tucd9000_debugfs_dir = debugfs_create_dir(name, NULL);\n> +\tif (IS_ERR(ucd9000_debugfs_dir)) {\n> +\t\tdev_warn(&client->dev, \"Failed to create debugfs dir: %p\\n\",\n> +\t\t\tucd9000_debugfs_dir);\n> +\t\tucd9000_debugfs_dir = NULL;\n> +\t\tida_simple_remove(&ucd9000_ida, data->idx);\n> +\t\treturn 0;\n> +\t}\n> +\n> +\t/*\n> +\t * Warning:\n> +\t *\n> +\t * Makes assumption we're on a ucd90160 type! entries will be different\n> +\t * sizes for other types.\n> +\t */\n> +\tentries = devm_kzalloc(&client->dev, sizeof(*entries) *\n> +\t\t\t\t(UCD90160_GPI_COUNT + 1) * 10, GFP_KERNEL);\n> +\tif (!entries) {\n> +\t\tida_simple_remove(&ucd9000_ida, data->idx);\n> +\t\treturn -ENOMEM;\n> +\t}\n> +\n> +\t/*\n> +\t * Warning:\n> +\t *\n> +\t * This makes the assumption we're probing a ucd90160 type and how the\n> +\t * GPI information is organized.  Needs to account for all other\n> +\t * ucd9000 varieties.\n> +\t */\n> +\tfor (i = 0; i < UCD90160_GPI_COUNT; i++) {\n> +\t\tentries[i].client = client;\n> +\t\tentries[i].index = UCD90160_GPI_FAULT_BASE + i;\n> +\t\tscnprintf(name, UCD9000_NAME_SIZE, \"gpi%d_alarm\", i+1);\n> +\t\tdebugfs_create_file(name, 0444, ucd9000_debugfs_dir,\n> +\t\t\t\t&entries[i],\n> +\t\t\t\t&ucd9000_debugfs_ops_mfr_status_bit);\n> +\t}\n> +\tentries[i].client = client;\n> +\tscnprintf(name, UCD9000_NAME_SIZE, \"mfr_status\");\n> +\tdebugfs_create_file(name, 0444, ucd9000_debugfs_dir, &entries[i],\n> +\t\t\t&ucd9000_debugfs_ops_mfr_status_word);\n> +\n> +\treturn 0;\n> +}\n> +#else\n> +static int ucd9000_init_debugfs(struct i2c_client *client,\n> +\t\t\t\tstruct ucd9000_data *data)\n> +{\n> +\treturn 0;\n> +}\n> +#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */\n> +\n>   static ssize_t ucd9000_clear_logged_faults(struct device *dev,\n>   \t\t\t\tstruct device_attribute *attr, const char *buf,\n>   \t\t\t\tsize_t count)\n> @@ -474,12 +623,21 @@ static int ucd9000_probe(struct i2c_client *client,\n>   \t\treturn ret;\n>   \t}\n>\n> -\treturn pmbus_do_probe(client, mid, info);\n> +\tret = ucd9000_init_debugfs(client, data);\n> +\tif (ret < 0)\n> +\t\tdev_warn(&client->dev, \"Failed to register debugfs: %d\\n\", ret);\n> +\n> +\treturn  pmbus_do_probe(client, mid, info);\n>   }\n>\n>   static int ucd9000_remove(struct i2c_client *client)\n>   {\n> +\tstruct ucd9000_data *data\n> +\t\t= to_ucd9000_data(pmbus_get_driver_info(client));\n> +\n>   \tsysfs_remove_group(&client->dev.kobj, &ucd9000_attr_group);\n> +\tida_simple_remove(&ucd9000_ida, data->idx);\n> +\tdebugfs_remove_recursive(ucd9000_debugfs_dir);\n>   \treturn pmbus_do_remove(client);\n>   }\n>","headers":{"Return-Path":"<openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>","X-Original-To":["incoming@patchwork.ozlabs.org","openbmc@lists.ozlabs.org"],"Delivered-To":["patchwork-incoming@bilbo.ozlabs.org","openbmc@lists.ozlabs.org"],"Received":["from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\t(using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xjnSs5mPjz9sNr\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri,  1 Sep 2017 02:12:13 +1000 (AEST)","from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 3xjnSs4nsSzDqXs\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri,  1 Sep 2017 02:12:13 +1000 (AEST)","from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com\n\t[148.163.156.1])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 3xjnSm19LRzDqYQ\n\tfor <openbmc@lists.ozlabs.org>; Fri,  1 Sep 2017 02:12:07 +1000 (AEST)","from pps.filterd (m0098404.ppops.net [127.0.0.1])\n\tby mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id\n\tv7VGC31Z082451\n\tfor <openbmc@lists.ozlabs.org>; Thu, 31 Aug 2017 12:12:06 -0400","from e15.ny.us.ibm.com (e15.ny.us.ibm.com [129.33.205.205])\n\tby mx0a-001b2d01.pphosted.com with ESMTP id 2cpkvgx6ju-1\n\t(version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT)\n\tfor <openbmc@lists.ozlabs.org>; Thu, 31 Aug 2017 12:12:05 -0400","from localhost\n\tby e15.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use\n\tOnly! Violators will be prosecuted\n\tfor <openbmc@lists.ozlabs.org> from <mspinler@linux.vnet.ibm.com>;\n\tThu, 31 Aug 2017 12:12:04 -0400","from b01cxnp22033.gho.pok.ibm.com (9.57.198.23)\n\tby e15.ny.us.ibm.com (146.89.104.202) with IBM ESMTP SMTP Gateway:\n\tAuthorized Use Only! Violators will be prosecuted; \n\tThu, 31 Aug 2017 12:12:01 -0400","from b01ledav005.gho.pok.ibm.com (b01ledav005.gho.pok.ibm.com\n\t[9.57.199.110])\n\tby b01cxnp22033.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP\n\tid v7VGC1mE23134250; Thu, 31 Aug 2017 16:12:01 GMT","from b01ledav005.gho.pok.ibm.com (unknown [127.0.0.1])\n\tby IMSVA (Postfix) with ESMTP id E8F62AE043;\n\tThu, 31 Aug 2017 12:12:25 -0400 (EDT)","from [9.10.99.183] (unknown [9.10.99.183])\n\tby b01ledav005.gho.pok.ibm.com (Postfix) with ESMTP id BA8EAAE03B;\n\tThu, 31 Aug 2017 12:12:25 -0400 (EDT)"],"Subject":"Re: [PATCH linux dev-4.10 v6 3/3] hwmon: (ucd9000) Add debugfs to\n\tlist mfr_status info","To":"Christopher Bostic <cbostic@linux.vnet.ibm.com>","References":"<20170830214953.73327-1-cbostic@linux.vnet.ibm.com>\n\t<20170830214953.73327-4-cbostic@linux.vnet.ibm.com>","From":"Matt Spinler <mspinler@linux.vnet.ibm.com>","Date":"Thu, 31 Aug 2017 11:12:02 -0500","User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101\n\tThunderbird/45.8.0","MIME-Version":"1.0","In-Reply-To":"<20170830214953.73327-4-cbostic@linux.vnet.ibm.com>","Content-Type":"text/plain; charset=windows-1252; format=flowed","Content-Transfer-Encoding":"7bit","X-TM-AS-GCONF":"00","x-cbid":"17083116-0036-0000-0000-00000261E399","X-IBM-SpamModules-Scores":"","X-IBM-SpamModules-Versions":"BY=3.00007642; HX=3.00000241; KW=3.00000007;\n\tPH=3.00000004; SC=3.00000226; SDB=6.00910273; UDB=6.00456616;\n\tIPR=6.00690553; \n\tBA=6.00005563; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009;\n\tZB=6.00000000; \n\tZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00016945;\n\tXFM=3.00000015; UTC=2017-08-31 16:12:03","X-IBM-AV-DETECTION":"SAVI=unused REMOTE=unused XFE=unused","x-cbparentid":"17083116-0037-0000-0000-0000419DB486","Message-Id":"<ada8076c-bed0-35df-4499-f0cfd5eab503@linux.vnet.ibm.com>","X-Proofpoint-Virus-Version":"vendor=fsecure engine=2.50.10432:, ,\n\tdefinitions=2017-08-31_06:, , signatures=0","X-Proofpoint-Spam-Details":"rule=outbound_notspam policy=outbound score=0\n\tspamscore=0 suspectscore=0\n\tmalwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam\n\tadjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000\n\tdefinitions=main-1708310239","X-BeenThere":"openbmc@lists.ozlabs.org","X-Mailman-Version":"2.1.23","Precedence":"list","List-Id":"Development list for OpenBMC <openbmc.lists.ozlabs.org>","List-Unsubscribe":"<https://lists.ozlabs.org/options/openbmc>,\n\t<mailto:openbmc-request@lists.ozlabs.org?subject=unsubscribe>","List-Archive":"<http://lists.ozlabs.org/pipermail/openbmc/>","List-Post":"<mailto:openbmc@lists.ozlabs.org>","List-Help":"<mailto:openbmc-request@lists.ozlabs.org?subject=help>","List-Subscribe":"<https://lists.ozlabs.org/listinfo/openbmc>,\n\t<mailto:openbmc-request@lists.ozlabs.org?subject=subscribe>","Cc":"openbmc@lists.ozlabs.org","Errors-To":"openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org","Sender":"\"openbmc\"\n\t<openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>"}}]