aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2016-01-07 17:49:23 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-02-07 01:11:06 -0500
commitc9cf20ee45602a7a5512b7fbbef5672382790555 (patch)
tree4b3555c09e163186c194a3a5cf5c7daffe94b905
parent222818c3d84c1f3190767f5f09f2b9b9a0e0ca7f (diff)
watchdog: mei_wdt: add status debugfs entry
Add entry for displaying current watchdog internal state cat <debugfs>/mei_wdt/state IDLE|START|RUNNING|STOPPING Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/watchdog/mei_wdt.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c
index 32e3e1d55ef3..e7e3f144f2b0 100644
--- a/drivers/watchdog/mei_wdt.c
+++ b/drivers/watchdog/mei_wdt.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/debugfs.h>
18#include <linux/watchdog.h> 19#include <linux/watchdog.h>
19 20
20#include <linux/uuid.h> 21#include <linux/uuid.h>
@@ -54,6 +55,24 @@ enum mei_wdt_state {
54 MEI_WDT_STOPPING, 55 MEI_WDT_STOPPING,
55}; 56};
56 57
58#if IS_ENABLED(CONFIG_DEBUG_FS)
59static const char *mei_wdt_state_str(enum mei_wdt_state state)
60{
61 switch (state) {
62 case MEI_WDT_IDLE:
63 return "IDLE";
64 case MEI_WDT_START:
65 return "START";
66 case MEI_WDT_RUNNING:
67 return "RUNNING";
68 case MEI_WDT_STOPPING:
69 return "STOPPING";
70 default:
71 return "unknown";
72 }
73}
74#endif /* CONFIG_DEBUG_FS */
75
57/** 76/**
58 * struct mei_wdt - mei watchdog driver 77 * struct mei_wdt - mei watchdog driver
59 * @wdd: watchdog device 78 * @wdd: watchdog device
@@ -61,6 +80,8 @@ enum mei_wdt_state {
61 * @cldev: mei watchdog client device 80 * @cldev: mei watchdog client device
62 * @state: watchdog internal state 81 * @state: watchdog internal state
63 * @timeout: watchdog current timeout 82 * @timeout: watchdog current timeout
83 *
84 * @dbgfs_dir: debugfs dir entry
64 */ 85 */
65struct mei_wdt { 86struct mei_wdt {
66 struct watchdog_device wdd; 87 struct watchdog_device wdd;
@@ -68,6 +89,10 @@ struct mei_wdt {
68 struct mei_cl_device *cldev; 89 struct mei_cl_device *cldev;
69 enum mei_wdt_state state; 90 enum mei_wdt_state state;
70 u16 timeout; 91 u16 timeout;
92
93#if IS_ENABLED(CONFIG_DEBUG_FS)
94 struct dentry *dbgfs_dir;
95#endif /* CONFIG_DEBUG_FS */
71}; 96};
72 97
73/* 98/*
@@ -310,6 +335,63 @@ static int mei_wdt_register(struct mei_wdt *wdt)
310 return ret; 335 return ret;
311} 336}
312 337
338#if IS_ENABLED(CONFIG_DEBUG_FS)
339
340static ssize_t mei_dbgfs_read_state(struct file *file, char __user *ubuf,
341 size_t cnt, loff_t *ppos)
342{
343 struct mei_wdt *wdt = file->private_data;
344 const size_t bufsz = 32;
345 char buf[bufsz];
346 ssize_t pos;
347
348 pos = scnprintf(buf, bufsz, "state: %s\n",
349 mei_wdt_state_str(wdt->state));
350
351 return simple_read_from_buffer(ubuf, cnt, ppos, buf, pos);
352}
353
354static const struct file_operations dbgfs_fops_state = {
355 .open = simple_open,
356 .read = mei_dbgfs_read_state,
357 .llseek = generic_file_llseek,
358};
359
360static void dbgfs_unregister(struct mei_wdt *wdt)
361{
362 debugfs_remove_recursive(wdt->dbgfs_dir);
363 wdt->dbgfs_dir = NULL;
364}
365
366static int dbgfs_register(struct mei_wdt *wdt)
367{
368 struct dentry *dir, *f;
369
370 dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
371 if (!dir)
372 return -ENOMEM;
373
374 wdt->dbgfs_dir = dir;
375 f = debugfs_create_file("state", S_IRUSR, dir, wdt, &dbgfs_fops_state);
376 if (!f)
377 goto err;
378
379 return 0;
380err:
381 dbgfs_unregister(wdt);
382 return -ENODEV;
383}
384
385#else
386
387static inline void dbgfs_unregister(struct mei_wdt *wdt) {}
388
389static inline int dbgfs_register(struct mei_wdt *wdt)
390{
391 return 0;
392}
393#endif /* CONFIG_DEBUG_FS */
394
313static int mei_wdt_probe(struct mei_cl_device *cldev, 395static int mei_wdt_probe(struct mei_cl_device *cldev,
314 const struct mei_cl_device_id *id) 396 const struct mei_cl_device_id *id)
315{ 397{
@@ -337,6 +419,9 @@ static int mei_wdt_probe(struct mei_cl_device *cldev,
337 if (ret) 419 if (ret)
338 goto err_disable; 420 goto err_disable;
339 421
422 if (dbgfs_register(wdt))
423 dev_warn(&cldev->dev, "cannot register debugfs\n");
424
340 return 0; 425 return 0;
341 426
342err_disable: 427err_disable:
@@ -356,6 +441,8 @@ static int mei_wdt_remove(struct mei_cl_device *cldev)
356 441
357 mei_cldev_disable(cldev); 442 mei_cldev_disable(cldev);
358 443
444 dbgfs_unregister(wdt);
445
359 kfree(wdt); 446 kfree(wdt);
360 447
361 return 0; 448 return 0;