Commit c010d696 authored by Adam Wujek's avatar Adam Wujek

sw/patches/linux: add 4 debugfs registers to monimod driver

added:
BOOT_NEW_FW
UPTIME_SECS
TMR_ERROR_CNT
USE_PEC
Signed-off-by: 's avatarAdam Wujek <dev_public@wujek.eu>
parent b7f25b38
From a4a2c0fde5aa5286d574046e09f4179c4e716510 Mon Sep 17 00:00:00 2001
From: Adam Wujek <dev_public@wujek.eu>
Date: Fri, 29 Apr 2022 02:44:39 +0200
Subject: [PATCH] hwmon: (monimod) add 4 debugfs registers
added:
BOOT_NEW_FW
UPTIME_SECS
TMR_ERROR_CNT
USE_PEC
Signed-off-by: Adam Wujek <dev_public@wujek.eu>
---
drivers/hwmon/pmbus/monimod.c | 160 +++++++++++++++++++++++++++++++++-
1 file changed, 158 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/pmbus/monimod.c b/drivers/hwmon/pmbus/monimod.c
index 15f95dd4488c..2d9fef5c5300 100644
--- a/drivers/hwmon/pmbus/monimod.c
+++ b/drivers/hwmon/pmbus/monimod.c
@@ -2,7 +2,7 @@
* Hardware monitoring driver for Monimod FANTRAY
*
* Author: Adam Wujek
- * Copyright (c) 2021 CERN
+ * Copyright (c) 2021-2022 CERN
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,8 +20,17 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/i2c.h>
+#include <linux/debugfs.h>
#include "pmbus.h"
+#define MONIMOD_FW_TYPE_BOOTLOADER 1
+#define MONIMOD_FW_TYPE_MAIN 2
+
+#define MONIMOD_REG_BOOT_NEW_FW 0xD5
+#define MONIMOD_REG_UPTIME_SECS 0xD7
+#define MONIMOD_REG_TMR_ERROR_CNT 0xD8
+#define MONIMOD_REG_USE_PEC 0xD9
+
#define MONIMOD_FUNC_0 (PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | \
PMBUS_HAVE_TEMP | \
PMBUS_HAVE_FAN12 | \
@@ -29,6 +38,11 @@
#define MONIMOD_FUNC_1 (PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT)
#define MONIMOD_FUNC_2 (PMBUS_HAVE_IOUT)
+struct pmbus_debugfs_entry {
+ struct i2c_client *client;
+ u8 reg;
+};
+
static struct pmbus_driver_info monimod_info = {
.pages = 3,
.func[0] = MONIMOD_FUNC_0,
@@ -37,10 +51,24 @@ static struct pmbus_driver_info monimod_info = {
.format[PSC_VOLTAGE_OUT] = linear,
};
+static int monimod_debugfs(struct i2c_client *client);
+
+
static int monimod_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- return pmbus_do_probe(client, id, &monimod_info);
+ int ret;
+ int probe_ret;
+
+ probe_ret = pmbus_do_probe(client, id, &monimod_info);
+ if (probe_ret < 0)
+ return probe_ret;
+
+ ret = monimod_debugfs(client);
+ if (ret)
+ dev_warn(&client->dev, "Failed to register debugfs\n");
+
+ return probe_ret;
}
static const struct i2c_device_id monimod_id[] = {
@@ -62,6 +90,134 @@ static struct i2c_driver monimod_driver = {
module_i2c_driver(monimod_driver);
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+static int monimod_debugfs_get_byte(void *data, u64 *val)
+{
+ int rc;
+ struct pmbus_debugfs_entry *entry = data;
+
+ rc = pmbus_read_byte_data(entry->client, 0, entry->reg);
+ if (rc < 0)
+ return rc;
+
+ *val = rc;
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(monimod_debugfs_ops_get_byte, monimod_debugfs_get_byte,
+ NULL, "%llx\n");
+
+
+static int monimod_debugfs_get_dword(void *data, u64 *val)
+{
+ int rc;
+ struct pmbus_debugfs_entry *entry = data;
+ u8 tmp[4];
+
+ rc = i2c_smbus_read_i2c_block_data(entry->client, entry->reg,
+ sizeof(tmp), tmp);
+ if (rc < 0)
+ return rc;
+
+ *val = tmp[0] | tmp[1] << 8 | tmp[2] << 16 | tmp[3] << 24;
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(monimod_debugfs_ops_get_dword,
+ monimod_debugfs_get_dword, NULL, "%lld\n");
+
+static ssize_t monimod_debugfs_get_fw_type(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int rc;
+ struct pmbus_debugfs_entry *entry = file->private_data;
+ char *data = NULL;
+
+ rc = pmbus_read_byte_data(entry->client, 0, entry->reg);
+ if (rc < 0)
+ return rc;
+
+ switch (rc) {
+ case MONIMOD_FW_TYPE_BOOTLOADER:
+ data = "bootloader\n";
+ break;
+ case MONIMOD_FW_TYPE_MAIN:
+ data = "main_fw\n";
+ break;
+
+ default:
+ break;
+ }
+
+ return simple_read_from_buffer(buf, count, ppos, data, strlen(data));
+}
+
+static const struct file_operations monimod_debugfs_ops_get_fw_type = {
+ .llseek = noop_llseek,
+ .read = monimod_debugfs_get_fw_type,
+ .write = NULL,
+ .open = simple_open,
+};
+
+static int monimod_debugfs(struct i2c_client *client)
+{
+ struct dentry *debugfs;
+ struct dentry *monimod_dir;
+ struct pmbus_debugfs_entry *entries;
+ int idx = 0;
+
+ debugfs = pmbus_get_debugfs_dir(client);
+ monimod_dir = debugfs_create_dir("monimod", debugfs);
+ if (IS_ERR_OR_NULL(monimod_dir)) {
+ monimod_dir = NULL;
+ return -ENODEV;
+ }
+
+ /* Allocate the max possible entries we need. */
+ entries = devm_kcalloc(&client->dev,
+ 3, sizeof(*entries),
+ GFP_KERNEL);
+ if (!entries)
+ return -ENOMEM;
+
+ /* Create debugfs entry for fw_type */
+ entries[idx].client = client;
+ entries[idx].reg = MONIMOD_REG_BOOT_NEW_FW;
+ debugfs_create_file("fw_type", 0444, monimod_dir,
+ &entries[idx++],
+ &monimod_debugfs_ops_get_fw_type);
+
+ /* Create debugfs entry for uptime_secs */
+ entries[idx].client = client;
+ entries[idx].reg = MONIMOD_REG_UPTIME_SECS;
+ debugfs_create_file("uptime_secs", 0444, monimod_dir,
+ &entries[idx++],
+ &monimod_debugfs_ops_get_dword);
+
+ /* Create debugfs entry for tmr_error_cnt */
+ entries[idx].client = client;
+ entries[idx].reg = MONIMOD_REG_TMR_ERROR_CNT;
+ debugfs_create_file("tmr_error_cnt", 0444, monimod_dir,
+ &entries[idx++],
+ &monimod_debugfs_ops_get_dword);
+
+ /* Create debugfs entry for use_pec */
+ entries[idx].client = client;
+ entries[idx].reg = MONIMOD_REG_USE_PEC;
+ debugfs_create_file("use_pec", 0444, monimod_dir,
+ &entries[idx++],
+ &monimod_debugfs_ops_get_byte);
+
+ return 0;
+}
+#else
+static int monimod_debugfs(struct i2c_client *client)
+{
+ return 0;
+}
+#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */
+
+
MODULE_AUTHOR("Adam Wujek");
MODULE_DESCRIPTION("PMBus driver for monimod");
MODULE_LICENSE("GPL");
--
2.17.1
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment