ipq806x: add ipq4019 support
[openwrt/openwrt.git] / target / linux / ipq806x / patches-4.4 / 009-4-watchdog-Read-device-status-through-sysfs-attributes.patch
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
5
6 This patch adds following attributes to watchdog device's sysfs interface
7 to read its different status.
8
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
16
17 Testing with iTCO_wdt:
18 # cd /sys/class/watchdog/watchdog1/
19 # ls
20 bootstatus dev device identity nowayout power state
21 subsystem timeleft timeout uevent
22 # cat identity
23 iTCO_wdt
24 # cat timeout
25 30
26 # cat state
27 inactive
28 # echo > /dev/watchdog1
29 # cat timeleft
30 26
31 # cat state
32 active
33 # cat bootstatus
34 0
35 # cat nowayout
36 0
37
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>
42 ---
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
49
50 --- /dev/null
51 +++ b/Documentation/ABI/testing/sysfs-class-watchdog
52 @@ -0,0 +1,51 @@
53 +What: /sys/class/watchdog/watchdogn/bootstatus
54 +Date: August 2015
55 +Contact: Wim Van Sebroeck <wim@iguana.be>
56 +Description:
57 + It is a read only file. It contains status of the watchdog
58 + device at boot. It is equivalent to WDIOC_GETBOOTSTATUS of
59 + ioctl interface.
60 +
61 +What: /sys/class/watchdog/watchdogn/identity
62 +Date: August 2015
63 +Contact: Wim Van Sebroeck <wim@iguana.be>
64 +Description:
65 + It is a read only file. It contains identity string of
66 + watchdog device.
67 +
68 +What: /sys/class/watchdog/watchdogn/nowayout
69 +Date: August 2015
70 +Contact: Wim Van Sebroeck <wim@iguana.be>
71 +Description:
72 + It is a read only file. While reading, it gives '1' if that
73 + device supports nowayout feature else, it gives '0'.
74 +
75 +What: /sys/class/watchdog/watchdogn/state
76 +Date: August 2015
77 +Contact: Wim Van Sebroeck <wim@iguana.be>
78 +Description:
79 + It is a read only file. It gives active/inactive status of
80 + watchdog device.
81 +
82 +What: /sys/class/watchdog/watchdogn/status
83 +Date: August 2015
84 +Contact: Wim Van Sebroeck <wim@iguana.be>
85 +Description:
86 + It is a read only file. It contains watchdog device's
87 + internal status bits. It is equivalent to WDIOC_GETSTATUS
88 + of ioctl interface.
89 +
90 +What: /sys/class/watchdog/watchdogn/timeleft
91 +Date: August 2015
92 +Contact: Wim Van Sebroeck <wim@iguana.be>
93 +Description:
94 + It is a read only file. It contains value of time left for
95 + reset generation. It is equivalent to WDIOC_GETTIMELEFT of
96 + ioctl interface.
97 +
98 +What: /sys/class/watchdog/watchdogn/timeout
99 +Date: August 2015
100 +Contact: Wim Van Sebroeck <wim@iguana.be>
101 +Description:
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
108 it has been started.
109
110 +config WATCHDOG_SYSFS
111 + bool "Read different watchdog information through sysfs"
112 + default n
113 + help
114 + Say Y here if you want to enable watchdog device status read through
115 + sysfs attributes.
116 +
117 #
118 # General Watchdog drivers
119 #
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
123
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:
134 return err;
135 }
136
137 +#ifdef CONFIG_WATCHDOG_SYSFS
138 +static ssize_t nowayout_show(struct device *dev, struct device_attribute *attr,
139 + char *buf)
140 +{
141 + struct watchdog_device *wdd = dev_get_drvdata(dev);
142 +
143 + return sprintf(buf, "%d\n", !!test_bit(WDOG_NO_WAY_OUT, &wdd->status));
144 +}
145 +static DEVICE_ATTR_RO(nowayout);
146 +
147 +static ssize_t status_show(struct device *dev, struct device_attribute *attr,
148 + char *buf)
149 +{
150 + struct watchdog_device *wdd = dev_get_drvdata(dev);
151 + ssize_t status;
152 + unsigned int val;
153 +
154 + status = watchdog_get_status(wdd, &val);
155 + if (!status)
156 + status = sprintf(buf, "%u\n", val);
157 +
158 + return status;
159 +}
160 +static DEVICE_ATTR_RO(status);
161 +
162 +static ssize_t bootstatus_show(struct device *dev,
163 + struct device_attribute *attr, char *buf)
164 +{
165 + struct watchdog_device *wdd = dev_get_drvdata(dev);
166 +
167 + return sprintf(buf, "%u\n", wdd->bootstatus);
168 +}
169 +static DEVICE_ATTR_RO(bootstatus);
170 +
171 +static ssize_t timeleft_show(struct device *dev, struct device_attribute *attr,
172 + char *buf)
173 +{
174 + struct watchdog_device *wdd = dev_get_drvdata(dev);
175 + ssize_t status;
176 + unsigned int val;
177 +
178 + status = watchdog_get_timeleft(wdd, &val);
179 + if (!status)
180 + status = sprintf(buf, "%u\n", val);
181 +
182 + return status;
183 +}
184 +static DEVICE_ATTR_RO(timeleft);
185 +
186 +static ssize_t timeout_show(struct device *dev, struct device_attribute *attr,
187 + char *buf)
188 +{
189 + struct watchdog_device *wdd = dev_get_drvdata(dev);
190 +
191 + return sprintf(buf, "%u\n", wdd->timeout);
192 +}
193 +static DEVICE_ATTR_RO(timeout);
194 +
195 +static ssize_t identity_show(struct device *dev, struct device_attribute *attr,
196 + char *buf)
197 +{
198 + struct watchdog_device *wdd = dev_get_drvdata(dev);
199 +
200 + return sprintf(buf, "%s\n", wdd->info->identity);
201 +}
202 +static DEVICE_ATTR_RO(identity);
203 +
204 +static ssize_t state_show(struct device *dev, struct device_attribute *attr,
205 + char *buf)
206 +{
207 + struct watchdog_device *wdd = dev_get_drvdata(dev);
208 +
209 + if (watchdog_active(wdd))
210 + return sprintf(buf, "active\n");
211 +
212 + return sprintf(buf, "inactive\n");
213 +}
214 +static DEVICE_ATTR_RO(state);
215 +
216 +static umode_t wdt_is_visible(struct kobject *kobj, struct attribute *attr,
217 + int n)
218 +{
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;
222 +
223 + if (attr == &dev_attr_status.attr && !wdd->ops->status)
224 + mode = 0;
225 + else if (attr == &dev_attr_timeleft.attr && !wdd->ops->get_timeleft)
226 + mode = 0;
227 +
228 + return mode;
229 +}
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,
238 + NULL,
239 +};
240 +
241 +static const struct attribute_group wdt_group = {
242 + .attrs = wdt_attrs,
243 + .is_visible = wdt_is_visible,
244 +};
245 +__ATTRIBUTE_GROUPS(wdt);
246 +#else
247 +#define wdt_groups NULL
248 +#endif
249 +
250 /*
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 = {
255 .name = "watchdog",
256 .owner = THIS_MODULE,
257 + .dev_groups = wdt_groups,
258 };
259
260 /*