Received: by 10.213.65.68 with SMTP id h4csp545350imn; Tue, 13 Mar 2018 12:31:33 -0700 (PDT) X-Google-Smtp-Source: AG47ELtCmFmVCKDpzJ4Ev0a1fRBSxFAxQVNdG7Rr3sDdUBB9bkTe/QHdHmuANAZdidovBDgYaajG X-Received: by 2002:a17:902:768b:: with SMTP id m11-v6mr1585836pll.185.1520969493120; Tue, 13 Mar 2018 12:31:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1520969493; cv=none; d=google.com; s=arc-20160816; b=sGyNFpZhOSwpnClWtAFzEA6tHqTbMQeLg0ze/pvCor4ogCfPaiTDBS7bHR+MW8nx35 IUySv47D9MwvchgIekXt3pCSzG+6Pyl4JWhyU8RPrCt2buUgb+Dha7TBJSByGHFadzRx TnxFP+PY4FgtdKcC2tEH7YwqeDke2TfRbGTh5FwPDm7ZeG2oxAWRkTgCizZEG4RNCgy/ qR/14gFbM05inLiqN/m7j7kbi2RCbH5eZmUk7LXg5Hzz60ifv31/K8BN+TbGsgGvaC6t w5WSVPl/tP9sDiwpc3jkUZFo2vKrE1VBmITzv+blEIDPyHCeTLeGTHY5oeR/epJgoeu/ EbBQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-transfer-encoding:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature :arc-authentication-results; bh=RUYNerfolwZGr9bmRAUREK57QP3WgDfToedwiZ3IE14=; b=QRcAvcZtbOTIUbgUUw85Reb/KGM9jxhSqnbCXp/bzY24duowlNhf8I7/rkw9FvShzX Fi71HlTMxbSJ2Y8UwTt79sxHr7y6xK4F6mpZjBaTQVe/08lWZ4YDTp1+nKQ0+5/MJsTv Muu4+yOrkIIYgJNaTg5u3tfZRsrlOX8o2ILlXJ/xKIpV/GjTvGTCaFFhhtMETs64TLNN 8j5p+8xCn5WCvtHXm63aVZpGG8iibuinChV/l3FQzrGFxAHA5f5GPHV8tJ9r1F8l8bQw ctipqGapObipiGXhPYgpVzkgNwYJiuTmmlkLWUv8hb3lP16mz5ucseaj9Ncg32sh38Py 1ZAA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=ff7hY5RP; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f12si570246pga.52.2018.03.13.12.31.16; Tue, 13 Mar 2018 12:31:33 -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; dkim=fail header.i=@gmail.com header.s=20161025 header.b=ff7hY5RP; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752605AbeCMT3I (ORCPT + 99 others); Tue, 13 Mar 2018 15:29:08 -0400 Received: from mail-pf0-f193.google.com ([209.85.192.193]:36389 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752468AbeCMT3H (ORCPT ); Tue, 13 Mar 2018 15:29:07 -0400 Received: by mail-pf0-f193.google.com with SMTP id 68so323827pfx.3; Tue, 13 Mar 2018 12:29:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=RUYNerfolwZGr9bmRAUREK57QP3WgDfToedwiZ3IE14=; b=ff7hY5RPXLcByMdr7woJP/miyantL8Hyt9OYR8sebfrRyAd9smyEI1H7C0mJobe+Xy XR6DnhQppYminsYLlRGANvdh/ioNHWCg1I6hDOmr5xTcWHCBdn9zmoJAy0JYzXfa4gMo 6rm9atv7RHqpfh+D84ukwHv/rZVFWQ/WZ9oIyw64nFffVI3W6cV8yFAJwwrodQ5DkywY 3Z74Z3i0si1JoYd8T8OytsOKLwEqLsByJt9nCIFIYQ5+ACNjeaTXR+qsJmVRtIynTA2f o1fcq8hb+WM7iswnrKRtx4IPeprXzSky5e/qrYPOOFlXfJPEL1QAc+Vdb/U7/YYrlhr9 wptA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:from:to:cc:subject:message-id :references:mime-version:content-disposition :content-transfer-encoding:in-reply-to:user-agent; bh=RUYNerfolwZGr9bmRAUREK57QP3WgDfToedwiZ3IE14=; b=Ss64ngNAhZrhiS7VCO2d257f/t3IafM+IdLyzSivErZKhjVDz9Y7RmUyHHHK3wmYEl JPzW+NSVkCkGxsXEGFZ0TW7cvimg+yY4rJJEWtBlrdSma71qi3ABEMzOiaQoWl4i+DvP 6tbBVUNyWhJLsLobMe+XZQ9L7VhBaG6HB2Z1R9ZeC3140KR9GaXcHBEwql86pTg5+ftN wx10VIXbHTmqkk7xEjyBROZl1rm4UzH1VmmE2lKjamifXuuK7m+LEATMmj8YCAh0Ja3D J9gWFY8UCTMXc9HjuH00QtExPhSL+kfUakONIcft8t1sPFpMh4C7hVujYRCeHw/tnovd UGDg== X-Gm-Message-State: AElRT7HGkkfAvcEvGdXaZg3vf7JTKXxIVCvXFN8yXwgJbdT9sTRfw0y7 kWnyGUvDqfq+ZxX3dzo6TtU= X-Received: by 10.98.75.18 with SMTP id y18mr1694393pfa.124.1520969346423; Tue, 13 Mar 2018 12:29:06 -0700 (PDT) Received: from localhost (108-223-40-66.lightspeed.sntcca.sbcglobal.net. [108.223.40.66]) by smtp.gmail.com with ESMTPSA id m3sm1176545pgd.3.2018.03.13.12.29.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 13 Mar 2018 12:29:05 -0700 (PDT) Date: Tue, 13 Mar 2018 12:29:03 -0700 From: Guenter Roeck To: Eddie James Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org, jdelvare@suse.com, joel@jms.id.au, Christopher Bostic , Andrew Jeffery Subject: Re: [PATCH 2/2] hwmon: (ucd9000) Add debugfs attributes to provide mfr_status Message-ID: <20180313192903.GA14572@roeck-us.net> References: <1520623196-9534-1-git-send-email-eajames@linux.vnet.ibm.com> <1520623196-9534-3-git-send-email-eajames@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Mar 13, 2018 at 02:01:51PM -0500, Eddie James wrote: > > > On 03/10/2018 10:50 AM, Guenter Roeck wrote: > >On 03/09/2018 11:19 AM, Eddie James wrote: > >>From: Christopher Bostic > >> > >>Expose the gpiN_fault fields of mfr_status as individual debugfs > >>attributes. This provides a way for users to be easily notified of gpi > >>faults. Also provide the whole mfr_status register in debugfs. > >> > >>Signed-off-by: Christopher Bostic > >>Signed-off-by: Andrew Jeffery > >>Signed-off-by: Eddie James > >>--- > >>? drivers/hwmon/pmbus/ucd9000.c | 172 > >>+++++++++++++++++++++++++++++++++++++++++- > >>? 1 file changed, 171 insertions(+), 1 deletion(-) > >> > >>diff --git a/drivers/hwmon/pmbus/ucd9000.c > >>b/drivers/hwmon/pmbus/ucd9000.c > >>index e3a507f..297da0e 100644 > >>--- a/drivers/hwmon/pmbus/ucd9000.c > >>+++ b/drivers/hwmon/pmbus/ucd9000.c > >>@@ -19,6 +19,7 @@ > >>?? * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > >>?? */ > >>? +#include > >>? #include > >>? #include > >>? #include > >>@@ -36,6 +37,7 @@ > >>? #define UCD9000_NUM_PAGES??????? 0xd6 > >>? #define UCD9000_FAN_CONFIG_INDEX??? 0xe7 > >>? #define UCD9000_FAN_CONFIG??????? 0xe8 > >>+#define UCD9000_MFR_STATUS??????? 0xf3 > >>? #define UCD9000_GPIO_SELECT??????? 0xfa > >>? #define UCD9000_GPIO_CONFIG??????? 0xfb > >>? #define UCD9000_DEVICE_ID??????? 0xfd > >>@@ -63,13 +65,22 @@ > >>? #define UCD901XX_NUM_GPIOS??? 26 > >>? #define UCD90910_NUM_GPIOS??? 26 > >>? +#define UCD9000_DEBUGFS_NAME_LEN??? 24 > >>+#define UCD9000_GPI_COUNT??????? 8 > >>+ > >>? struct ucd9000_data { > >>????? u8 fan_data[UCD9000_NUM_FAN][I2C_SMBUS_BLOCK_MAX]; > >>????? struct pmbus_driver_info info; > >>????? struct gpio_chip gpio; > >>+??? struct dentry *debugfs; > >>? }; > >>? #define to_ucd9000_data(_info) container_of(_info, struct > >>ucd9000_data, info) > >>? +struct ucd9000_debugfs_entry { > >>+??? struct i2c_client *client; > >>+??? u8 index; > >>+}; > >>+ > >>? static int ucd9000_get_fan_config(struct i2c_client *client, int fan) > >>? { > >>????? int fan_config = 0; > >>@@ -328,6 +339,156 @@ static int ucd9000_gpio_direction_output(struct > >>gpio_chip *gc, > >>??????????????????????? val); > >>? } > >>? +#if IS_ENABLED(CONFIG_DEBUG_FS) > >>+static int ucd9000_get_mfr_status(struct i2c_client *client, u8 > >>*buffer) > >>+{ > >>+??? int ret = pmbus_set_page(client, 0); > >>+ > >>+??? if (ret < 0) > >>+??????? return ret; > >>+ > >>+??? /* > >>+???? * With the ucd90120 and ucd90124 devices, this command > >>[MFR_STATUS] > >>+???? * is 2 bytes long (bits 0-15).? With the ucd90240 this command is > >>5 > >>+???? * bytes long.? With all other devices, it is 4 bytes long. > >>+???? */ > >>+??? return i2c_smbus_read_block_data(client, UCD9000_MFR_STATUS, > >>buffer); > >>+} > >>+ > >>+static int ucd9000_debugfs_show_mfr_status_bit(void *data, u64 *val) > >>+{ > >>+??? struct ucd9000_debugfs_entry *entry = data; > >>+??? struct i2c_client *client = entry->client; > >>+??? u8 buffer[4]; > >>+??? int ret; > >>+ > >>+??? /* > >>+???? * This attribute is only created for devices that return 4 bytes > >>for > >>+???? * status_mfr, so it's safe to call with 4-byte buffer. > >>+???? */ > >>+??? ret = ucd9000_get_mfr_status(client, buffer); > >>+??? if (ret < 0) { > >>+??????? dev_err(&client->dev, "Failed to read mfr status. rc:%d\n", > >>+??????????? ret); > >>+ > >>+??????? return ret; > >>+??? } > >>+ > >>+??? /* > >>+???? * Attribute only created for devices with gpi fault bits at bits > >>+???? * 16-23, which is the second byte of the response. > >>+???? */ > >>+??? *val = !!(buffer[1] & BIT(entry->index)); > >>+ > >>+??? return 0; > >>+} > >>+DEFINE_DEBUGFS_ATTRIBUTE(ucd9000_debugfs_mfr_status_bit, > >>+???????????? ucd9000_debugfs_show_mfr_status_bit, NULL, "%1lld\n"); > >>+ > >>+static int ucd9000_debugfs_show_mfr_status_word2(void *data, u64 *val) > >>+{ > >>+??? struct i2c_client *client = data; > >>+??? __be16 buffer; > >>+??? int ret; > >>+ > >>+??? ret = ucd9000_get_mfr_status(client, (u8 *)&buffer); > >>+??? if (ret < 0) { > >>+??????? dev_err(&client->dev, "Failed to read mfr status. rc:%d\n", > >>+??????????? ret); > >>+ > >>+??????? return ret; > >>+??? } > >>+ > >>+??? *val = be16_to_cpu(buffer); > >>+ > >>+??? return 0; > >>+} > >>+DEFINE_DEBUGFS_ATTRIBUTE(ucd9000_debugfs_mfr_status_word2, > >>+???????????? ucd9000_debugfs_show_mfr_status_word2, NULL, > >>+???????????? "%04llx\n"); > >>+ > >>+static int ucd9000_debugfs_show_mfr_status_word4(void *data, u64 *val) > >>+{ > >>+??? struct i2c_client *client = data; > >>+??? __be32 buffer; > >>+??? int ret; > >>+ > >>+??? ret = ucd9000_get_mfr_status(client, (u8 *)&buffer); > >>+??? if (ret < 0) { > >>+??????? dev_err(&client->dev, "Failed to read mfr status. rc:%d\n", > >>+??????????? ret); > >>+ > >>+??????? return ret; > >>+??? } > >>+ > >>+??? *val = be32_to_cpu(buffer); > >>+ > >>+??? return 0; > >>+} > >>+DEFINE_DEBUGFS_ATTRIBUTE(ucd9000_debugfs_mfr_status_word4, > >>+???????????? ucd9000_debugfs_show_mfr_status_word4, NULL, > >>+???????????? "%08llx\n"); > >>+ > >>+static int ucd9000_init_debugfs(struct i2c_client *client, > >>+??????????????? const struct i2c_device_id *mid, > >>+??????????????? struct ucd9000_data *data) > >>+{ > >>+??? struct dentry *debugfs; > >>+??? struct ucd9000_debugfs_entry *entries; > >>+??? int i; > >>+??? char name[UCD9000_DEBUGFS_NAME_LEN]; > >>+ > >>+??? debugfs = pmbus_get_debugfs_dir(client); > >>+??? if (!debugfs) > >>+??????? return -ENOENT; > >>+ > >>+??? data->debugfs = debugfs_create_dir(client->name, debugfs); > >>+??? if (!data->debugfs) > >>+??????? return -ENOENT; > >>+ > >>+??? /* > >>+???? * Of the chips this driver supports, only the UCD9090, UCD90160, > >>+???? * and UCD90910 report GPI faults in their MFR_STATUS register, so > >>only > >>+???? * create the GPI fault debugfs attributes for those chips. > >>+???? */ > >>+??? if (mid->driver_data == ucd9090 || mid->driver_data == ucd90160 || > >>+??????? mid->driver_data == ucd90910) { > >>+??????? entries = devm_kzalloc(&client->dev, > >>+?????????????????????? sizeof(*entries) * UCD9000_GPI_COUNT, > >>+?????????????????????? GFP_KERNEL); > >>+??????? if (!entries) > >>+??????????? return -ENOMEM; > >>+ > >>+??????? for (i = 0; i < UCD9000_GPI_COUNT; i++) { > >>+??????????? entries[i].client = client; > >>+??????????? entries[i].index = i; > >>+??????????? scnprintf(name, UCD9000_DEBUGFS_NAME_LEN, > >>+????????????????? "gpi%d_alarm", i + 1); > >>+??????????? debugfs_create_file(name, 0444, data->debugfs, > >>+??????????????????????? &entries[i], > >>+??????????????????????? &ucd9000_debugfs_mfr_status_bit); > >>+??????? } > >>+ > >>+??????? scnprintf(name, UCD9000_DEBUGFS_NAME_LEN, "mfr_status"); > >>+??????? debugfs_create_file(name, 0444, data->debugfs, client, > >>+??????????????????? &ucd9000_debugfs_mfr_status_word4); > >>+??? } else if (mid->driver_data == ucd90120 || > >>+?????????? mid->driver_data == ucd90124) { > >>+??????? scnprintf(name, UCD9000_DEBUGFS_NAME_LEN, "mfr_status"); > >>+??????? debugfs_create_file(name, 0444, data->debugfs, client, > >>+??????????????????? &ucd9000_debugfs_mfr_status_word2); > >>+??? } > >>+ > >>+??? return 0; > >>+} > > > >Is all that complexity really worth it ? Why not just read the > >manufacturing > >status as byte string into a buffer and use hexdump to pront it, no matter > >how > >many bytes are actually returned ? This would also be less error prone, > >and > >automatically support future chips. > > Hm, well then we have the additional complexity of setting up custom debugfs > file operations to show the binary data instead of just using > DEFINE_DEBUGFS_ATTRIBUTE. Plus, at some point someone has to interpret it as > either a word, half-word, or 5 bytes chunk. Where better to do it than the > driver, as this is hw-dependent? > I can't exactly follow your logic. You mean it is acceptable for the user to have to look into the datasheet to find out what the 1/2/4 byte hex value means, but it is unacceptable to expect the user to have to use the datasheet to identify what a 1..5 byte hex string, displayed in the order received from the chip, means ? I am having difficulties understanding the difference. How is 12345678 different from, say, 12 34 56 78 (which you could display as 12345678 as well) ? The macro generates the file operations as part of the define, so I don't see having to define as valid argument. One could instead add a generic debugfs macro to display a string if that is of interest. > I could just use one function and do a byte-swap based on data length in a > loop within #ifdef LITTLE_ENDIAN, but that's a little messy. It will handle > all the cases though. What do you think? > Personally I don't see a problem displaying data as received. Either case, there are functions/macros to convert from big/little endian to host byte order, so related ifdefs in the code should never be necessary. Guenter > Thanks, > Eddie > > > > >Thanks, > >Guenter > > > >>+#else > >>+static int ucd9000_init_debugfs(struct i2c_client *client, > >>+??????????????? struct ucd9000_data *data) > >>+{ > >>+??? return 0; > >>+} > >>+#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ > >>+ > >>? static int ucd9000_probe(struct i2c_client *client, > >>?????????????? const struct i2c_device_id *id) > >>? { > >>@@ -483,7 +644,16 @@ static int ucd9000_probe(struct i2c_client *client, > >>????????? return ret; > >>????? } > >>? -??? return pmbus_do_probe(client, mid, info); > >>+??? ret = pmbus_do_probe(client, mid, info); > >>+??? if (ret) > >>+??????? return ret; > >>+ > >>+??? ret = ucd9000_init_debugfs(client, mid, data); > >>+??? if (ret) > >>+??????? dev_warn(&client->dev, "Failed to register debugfs: %d\n", > >>+???????????? ret); > >>+ > >>+??? return 0; > >>? } > >>? ? /* This is the driver that will be inserted */ > >> > > >