drivers: thermal: tsens: Add debugfs support

Dump some basic version info and sensor details into debugfs. Example
from qcs404 below:

--(/sys/kernel/debug) $ ls tsens/
4a9000.thermal-sensor  version
--(/sys/kernel/debug) $ cat tsens/version
1.4.0
--(/sys/kernel/debug) $ cat tsens/4a9000.thermal-sensor/sensors
max: 11
num: 10

      id    slope   offset
------------------------
       0     3200   404000
       1     3200   404000
       2     3200   404000
       3     3200   404000
       4     3200   404000
       5     3200   404000
       6     3200   404000
       7     3200   404000
       8     3200   404000
       9     3200   404000

Signed-off-by: Amit Kucheria <amit.kucheria@linaro.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/16e39c1bbfc18b5cf6274620cd72cc63205f53a5.1572526427.git.amit.kucheria@linaro.org
This commit is contained in:
Amit Kucheria 2019-11-01 00:07:28 +05:30 committed by Daniel Lezcano
parent 3795ad5e26
commit 7c938f4837
3 changed files with 91 additions and 0 deletions

View File

@ -3,6 +3,7 @@
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
*/
#include <linux/debugfs.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/nvmem-consumer.h>
@ -139,6 +140,77 @@ int get_temp_common(struct tsens_sensor *s, int *temp)
return 0;
}
#ifdef CONFIG_DEBUG_FS
static int dbg_sensors_show(struct seq_file *s, void *data)
{
struct platform_device *pdev = s->private;
struct tsens_priv *priv = platform_get_drvdata(pdev);
int i;
seq_printf(s, "max: %2d\nnum: %2d\n\n",
priv->feat->max_sensors, priv->num_sensors);
seq_puts(s, " id slope offset\n--------------------------\n");
for (i = 0; i < priv->num_sensors; i++) {
seq_printf(s, "%8d %8d %8d\n", priv->sensor[i].hw_id,
priv->sensor[i].slope, priv->sensor[i].offset);
}
return 0;
}
static int dbg_version_show(struct seq_file *s, void *data)
{
struct platform_device *pdev = s->private;
struct tsens_priv *priv = platform_get_drvdata(pdev);
u32 maj_ver, min_ver, step_ver;
int ret;
if (tsens_ver(priv) > VER_0_1) {
ret = regmap_field_read(priv->rf[VER_MAJOR], &maj_ver);
if (ret)
return ret;
ret = regmap_field_read(priv->rf[VER_MINOR], &min_ver);
if (ret)
return ret;
ret = regmap_field_read(priv->rf[VER_STEP], &step_ver);
if (ret)
return ret;
seq_printf(s, "%d.%d.%d\n", maj_ver, min_ver, step_ver);
} else {
seq_puts(s, "0.1.0\n");
}
return 0;
}
DEFINE_SHOW_ATTRIBUTE(dbg_version);
DEFINE_SHOW_ATTRIBUTE(dbg_sensors);
static void tsens_debug_init(struct platform_device *pdev)
{
struct tsens_priv *priv = platform_get_drvdata(pdev);
struct dentry *root, *file;
root = debugfs_lookup("tsens", NULL);
if (!root)
priv->debug_root = debugfs_create_dir("tsens", NULL);
else
priv->debug_root = root;
file = debugfs_lookup("version", priv->debug_root);
if (!file)
debugfs_create_file("version", 0444, priv->debug_root,
pdev, &dbg_version_fops);
/* A directory for each instance of the TSENS IP */
priv->debug = debugfs_create_dir(dev_name(&pdev->dev), priv->debug_root);
debugfs_create_file("sensors", 0444, priv->debug, pdev, &dbg_sensors_fops);
}
#else
static inline void tsens_debug_init(struct platform_device *pdev) {}
#endif
static const struct regmap_config tsens_config = {
.name = "tm",
.reg_bits = 32,
@ -199,6 +271,15 @@ int __init init_common(struct tsens_priv *priv)
goto err_put_device;
}
if (tsens_ver(priv) > VER_0_1) {
for (i = VER_MAJOR; i <= VER_STEP; i++) {
priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map,
priv->fields[i]);
if (IS_ERR(priv->rf[i]))
return PTR_ERR(priv->rf[i]);
}
}
priv->rf[TSENS_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
priv->fields[TSENS_EN]);
if (IS_ERR(priv->rf[TSENS_EN])) {
@ -238,6 +319,8 @@ int __init init_common(struct tsens_priv *priv)
}
}
tsens_debug_init(op);
return 0;
err_put_device:

View File

@ -3,6 +3,7 @@
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
*/
#include <linux/debugfs.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
@ -176,6 +177,7 @@ static int tsens_remove(struct platform_device *pdev)
{
struct tsens_priv *priv = platform_get_drvdata(pdev);
debugfs_remove_recursive(priv->debug_root);
if (priv->ops->disable)
priv->ops->disable(priv);

View File

@ -293,6 +293,8 @@ struct tsens_context {
* @feat: features of the IP
* @fields: bitfield locations
* @ops: pointer to list of callbacks supported by this device
* @debug_root: pointer to debugfs dentry for all tsens
* @debug: pointer to debugfs dentry for tsens controller
* @sensor: list of sensors attached to this device
*/
struct tsens_priv {
@ -306,6 +308,10 @@ struct tsens_priv {
const struct tsens_features *feat;
const struct reg_field *fields;
const struct tsens_ops *ops;
struct dentry *debug_root;
struct dentry *debug;
struct tsens_sensor sensor[0];
};