[PATCH linux dev-4.10 2/2] hwmon: (pmbus): cffps: Add input_history debugfs file
Eddie James
eajames at linux.vnet.ibm.com
Fri Nov 3 07:59:41 AEDT 2017
From: "Edward A. James" <eajames at us.ibm.com>
Provide binary data of the powers supply input history to debugfs.
Signed-off-by: Edward A. James <eajames at us.ibm.com>
---
drivers/hwmon/pmbus/ibm-cffps.c | 97 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 96 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/pmbus/ibm-cffps.c b/drivers/hwmon/pmbus/ibm-cffps.c
index 1a6294c..0570c12 100644
--- a/drivers/hwmon/pmbus/ibm-cffps.c
+++ b/drivers/hwmon/pmbus/ibm-cffps.c
@@ -7,13 +7,19 @@
* (at your option) any later version.
*/
+#include <linux/debugfs.h>
#include <linux/device.h>
+#include <linux/fs.h>
#include <linux/i2c.h>
#include <linux/jiffies.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include "pmbus.h"
+#define CFFPS_INPUT_HISTORY_CMD 0xD6
+#define CFFPS_INPUT_HISTORY_SIZE 100
+
/* STATUS_MFR_SPECIFIC bits */
#define CFFPS_MFR_FAN_FAULT BIT(0)
#define CFFPS_MFR_THERMAL_FAULT BIT(1)
@@ -24,6 +30,70 @@
#define CFFPS_MFR_VAUX_FAULT BIT(6)
#define CFFPS_MFR_CURRENT_SHARE_WARNING BIT(7)
+struct ibm_cffps {
+ struct i2c_client *client;
+
+ struct mutex update_lock;
+ unsigned long last_updated;
+
+ u8 byte_count;
+ u8 input_history[CFFPS_INPUT_HISTORY_SIZE];
+};
+
+static ssize_t ibm_cffps_read_input_history(struct file *file,
+ char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ int rc;
+ struct ibm_cffps *psu = file->private_data;
+ u8 msgbuf0[1] = { CFFPS_INPUT_HISTORY_CMD };
+ u8 msgbuf1[CFFPS_INPUT_HISTORY_SIZE + 1] = { 0 };
+ struct i2c_msg msg[2] = {
+ {
+ .addr = psu->client->addr,
+ .flags = psu->client->flags,
+ .len = 1,
+ .buf = msgbuf0,
+ }, {
+ .addr = psu->client->addr,
+ .flags = psu->client->flags | I2C_M_RD,
+ .len = CFFPS_INPUT_HISTORY_SIZE + 1,
+ .buf = msgbuf1,
+ },
+ };
+
+ if (!*ppos) {
+ mutex_lock(&psu->update_lock);
+ if (time_after(jiffies, psu->last_updated + HZ)) {
+ /*
+ * Use a raw i2c transfer, since we need more bytes
+ * than Linux I2C supports through smbus xfr (only 32).
+ */
+ rc = i2c_transfer(psu->client->adapter, msg, 2);
+ if (rc < 0) {
+ mutex_unlock(&psu->update_lock);
+ return rc;
+ }
+
+ psu->byte_count = msgbuf1[0];
+ memcpy(psu->input_history, &msgbuf1[1],
+ CFFPS_INPUT_HISTORY_SIZE);
+ psu->last_updated = jiffies;
+ }
+
+ mutex_unlock(&psu->update_lock);
+ }
+
+ return simple_read_from_buffer(buf, count, ppos, psu->input_history,
+ psu->byte_count);
+}
+
+static const struct file_operations ibm_cffps_fops = {
+ .llseek = noop_llseek,
+ .read = ibm_cffps_read_input_history,
+ .open = simple_open,
+};
+
static int ibm_cffps_read_byte_data(struct i2c_client *client, int page,
int reg)
{
@@ -119,7 +189,32 @@ static int ibm_cffps_read_word_data(struct i2c_client *client, int page,
static int ibm_cffps_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- return pmbus_do_probe(client, id, &ibm_cffps_info);
+ int rc;
+ struct dentry *debugfs;
+ struct ibm_cffps *psu;
+
+ rc = pmbus_do_probe(client, id, &ibm_cffps_info);
+ if (rc)
+ return rc;
+
+ /* Don't fail the probe if we can't create debugfs */
+ psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL);
+ if (!psu)
+ return 0;
+
+ psu->client = client;
+ mutex_init(&psu->update_lock);
+ if (jiffies > HZ)
+ psu->last_updated = jiffies - HZ;
+
+ debugfs = pmbus_get_debugfs_dir(client);
+ if (!debugfs)
+ return 0;
+
+ debugfs_create_file("ibm_cffps_input_history", 0444, debugfs, psu,
+ &ibm_cffps_fops);
+
+ return 0;
}
static const struct i2c_device_id ibm_cffps_id[] = {
--
1.8.3.1
More information about the openbmc
mailing list