1 From 33b711269ade3f6bc9d9d15e4343e6fa922d999b Mon Sep 17 00:00:00 2001
2 From: Pratyush Anand <panand@redhat.com>
3 Date: Thu, 17 Dec 2015 17:53:59 +0530
4 Subject: watchdog: Read device status through sysfs attributes
6 This patch adds following attributes to watchdog device's sysfs interface
7 to read its different status.
9 * state - reads whether device is active or not
10 * identity - reads Watchdog device's identity string.
11 * timeout - reads current timeout.
12 * timeleft - reads timeleft before watchdog generates a reset
13 * bootstatus - reads status of the watchdog device at boot
14 * status - reads watchdog device's internal status bits
15 * nowayout - reads whether nowayout feature was set or not
17 Testing with iTCO_wdt:
18 # cd /sys/class/watchdog/watchdog1/
20 bootstatus dev device identity nowayout power state
21 subsystem timeleft timeout uevent
28 # echo > /dev/watchdog1
38 Signed-off-by: Pratyush Anand <panand@redhat.com>
39 Reviewed-by: Guenter Roeck <linux@roeck-us.net>
40 Signed-off-by: Guenter Roeck <linux@roeck-us.net>
41 Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
43 Documentation/ABI/testing/sysfs-class-watchdog | 51 +++++++++++
44 drivers/watchdog/Kconfig | 7 ++
45 drivers/watchdog/watchdog_core.c | 2 +-
46 drivers/watchdog/watchdog_dev.c | 114 +++++++++++++++++++++++++
47 4 files changed, 173 insertions(+), 1 deletion(-)
48 create mode 100644 Documentation/ABI/testing/sysfs-class-watchdog
51 +++ b/Documentation/ABI/testing/sysfs-class-watchdog
53 +What: /sys/class/watchdog/watchdogn/bootstatus
55 +Contact: Wim Van Sebroeck <wim@iguana.be>
57 + It is a read only file. It contains status of the watchdog
58 + device at boot. It is equivalent to WDIOC_GETBOOTSTATUS of
61 +What: /sys/class/watchdog/watchdogn/identity
63 +Contact: Wim Van Sebroeck <wim@iguana.be>
65 + It is a read only file. It contains identity string of
68 +What: /sys/class/watchdog/watchdogn/nowayout
70 +Contact: Wim Van Sebroeck <wim@iguana.be>
72 + It is a read only file. While reading, it gives '1' if that
73 + device supports nowayout feature else, it gives '0'.
75 +What: /sys/class/watchdog/watchdogn/state
77 +Contact: Wim Van Sebroeck <wim@iguana.be>
79 + It is a read only file. It gives active/inactive status of
82 +What: /sys/class/watchdog/watchdogn/status
84 +Contact: Wim Van Sebroeck <wim@iguana.be>
86 + It is a read only file. It contains watchdog device's
87 + internal status bits. It is equivalent to WDIOC_GETSTATUS
90 +What: /sys/class/watchdog/watchdogn/timeleft
92 +Contact: Wim Van Sebroeck <wim@iguana.be>
94 + It is a read only file. It contains value of time left for
95 + reset generation. It is equivalent to WDIOC_GETTIMELEFT of
98 +What: /sys/class/watchdog/watchdogn/timeout
100 +Contact: Wim Van Sebroeck <wim@iguana.be>
102 + It is a read only file. It is read to know about current
103 + value of timeout programmed.
104 --- a/drivers/watchdog/Kconfig
105 +++ b/drivers/watchdog/Kconfig
106 @@ -46,6 +46,13 @@ config WATCHDOG_NOWAYOUT
107 get killed. If you say Y here, the watchdog cannot be stopped once
110 +config WATCHDOG_SYSFS
111 + bool "Read different watchdog information through sysfs"
114 + Say Y here if you want to enable watchdog device status read through
118 # General Watchdog drivers
120 --- a/drivers/watchdog/watchdog_core.c
121 +++ b/drivers/watchdog/watchdog_core.c
122 @@ -249,7 +249,7 @@ static int __watchdog_register_device(st
124 devno = wdd->cdev.dev;
125 wdd->dev = device_create(watchdog_class, wdd->parent, devno,
126 - NULL, "watchdog%d", wdd->id);
127 + wdd, "watchdog%d", wdd->id);
128 if (IS_ERR(wdd->dev)) {
129 watchdog_dev_unregister(wdd);
130 ida_simple_remove(&watchdog_ida, id);
131 --- a/drivers/watchdog/watchdog_dev.c
132 +++ b/drivers/watchdog/watchdog_dev.c
133 @@ -247,6 +247,119 @@ out_timeleft:
137 +#ifdef CONFIG_WATCHDOG_SYSFS
138 +static ssize_t nowayout_show(struct device *dev, struct device_attribute *attr,
141 + struct watchdog_device *wdd = dev_get_drvdata(dev);
143 + return sprintf(buf, "%d\n", !!test_bit(WDOG_NO_WAY_OUT, &wdd->status));
145 +static DEVICE_ATTR_RO(nowayout);
147 +static ssize_t status_show(struct device *dev, struct device_attribute *attr,
150 + struct watchdog_device *wdd = dev_get_drvdata(dev);
154 + status = watchdog_get_status(wdd, &val);
156 + status = sprintf(buf, "%u\n", val);
160 +static DEVICE_ATTR_RO(status);
162 +static ssize_t bootstatus_show(struct device *dev,
163 + struct device_attribute *attr, char *buf)
165 + struct watchdog_device *wdd = dev_get_drvdata(dev);
167 + return sprintf(buf, "%u\n", wdd->bootstatus);
169 +static DEVICE_ATTR_RO(bootstatus);
171 +static ssize_t timeleft_show(struct device *dev, struct device_attribute *attr,
174 + struct watchdog_device *wdd = dev_get_drvdata(dev);
178 + status = watchdog_get_timeleft(wdd, &val);
180 + status = sprintf(buf, "%u\n", val);
184 +static DEVICE_ATTR_RO(timeleft);
186 +static ssize_t timeout_show(struct device *dev, struct device_attribute *attr,
189 + struct watchdog_device *wdd = dev_get_drvdata(dev);
191 + return sprintf(buf, "%u\n", wdd->timeout);
193 +static DEVICE_ATTR_RO(timeout);
195 +static ssize_t identity_show(struct device *dev, struct device_attribute *attr,
198 + struct watchdog_device *wdd = dev_get_drvdata(dev);
200 + return sprintf(buf, "%s\n", wdd->info->identity);
202 +static DEVICE_ATTR_RO(identity);
204 +static ssize_t state_show(struct device *dev, struct device_attribute *attr,
207 + struct watchdog_device *wdd = dev_get_drvdata(dev);
209 + if (watchdog_active(wdd))
210 + return sprintf(buf, "active\n");
212 + return sprintf(buf, "inactive\n");
214 +static DEVICE_ATTR_RO(state);
216 +static umode_t wdt_is_visible(struct kobject *kobj, struct attribute *attr,
219 + struct device *dev = container_of(kobj, struct device, kobj);
220 + struct watchdog_device *wdd = dev_get_drvdata(dev);
221 + umode_t mode = attr->mode;
223 + if (attr == &dev_attr_status.attr && !wdd->ops->status)
225 + else if (attr == &dev_attr_timeleft.attr && !wdd->ops->get_timeleft)
230 +static struct attribute *wdt_attrs[] = {
231 + &dev_attr_state.attr,
232 + &dev_attr_identity.attr,
233 + &dev_attr_timeout.attr,
234 + &dev_attr_timeleft.attr,
235 + &dev_attr_bootstatus.attr,
236 + &dev_attr_status.attr,
237 + &dev_attr_nowayout.attr,
241 +static const struct attribute_group wdt_group = {
242 + .attrs = wdt_attrs,
243 + .is_visible = wdt_is_visible,
245 +__ATTRIBUTE_GROUPS(wdt);
247 +#define wdt_groups NULL
251 * watchdog_ioctl_op: call the watchdog drivers ioctl op if defined
252 * @wdd: the watchdog device to do the ioctl on
253 @@ -584,6 +697,7 @@ int watchdog_dev_unregister(struct watch
254 static struct class watchdog_class = {
256 .owner = THIS_MODULE,
257 + .dev_groups = wdt_groups,