ipq806x: set v4.9 as default
[librecmc/librecmc.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  /*