aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/watchdog/watchdog-kernel-api.txt5
-rw-r--r--drivers/watchdog/watchdog_core.c34
-rw-r--r--drivers/watchdog/watchdog_dev.c1
-rw-r--r--include/linux/watchdog.h4
4 files changed, 42 insertions, 2 deletions
diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt
index 3c85fc7dc1f1..ce1fa22aa70b 100644
--- a/Documentation/watchdog/watchdog-kernel-api.txt
+++ b/Documentation/watchdog/watchdog-kernel-api.txt
@@ -41,6 +41,8 @@ The watchdog device structure looks like this:
41struct watchdog_device { 41struct watchdog_device {
42 int id; 42 int id;
43 struct cdev cdev; 43 struct cdev cdev;
44 struct device *dev;
45 struct device *parent;
44 const struct watchdog_info *info; 46 const struct watchdog_info *info;
45 const struct watchdog_ops *ops; 47 const struct watchdog_ops *ops;
46 unsigned int bootstatus; 48 unsigned int bootstatus;
@@ -58,6 +60,9 @@ It contains following fields:
58 watchdog_register_device. 60 watchdog_register_device.
59* cdev: cdev for the dynamic /dev/watchdog<id> device nodes. This 61* cdev: cdev for the dynamic /dev/watchdog<id> device nodes. This
60 field is also populated by watchdog_register_device. 62 field is also populated by watchdog_register_device.
63* dev: device under the watchdog class (created by watchdog_register_device).
64* parent: set this to the parent device (or NULL) before calling
65 watchdog_register_device.
61* info: a pointer to a watchdog_info structure. This structure gives some 66* info: a pointer to a watchdog_info structure. This structure gives some
62 additional information about the watchdog timer itself. (Like it's unique name) 67 additional information about the watchdog timer itself. (Like it's unique name)
63* ops: a pointer to the list of watchdog operations that the watchdog supports. 68* ops: a pointer to the list of watchdog operations that the watchdog supports.
diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c
index 5f9879369003..86a57673abf9 100644
--- a/drivers/watchdog/watchdog_core.c
+++ b/drivers/watchdog/watchdog_core.c
@@ -35,10 +35,12 @@
35#include <linux/watchdog.h> /* For watchdog specific items */ 35#include <linux/watchdog.h> /* For watchdog specific items */
36#include <linux/init.h> /* For __init/__exit/... */ 36#include <linux/init.h> /* For __init/__exit/... */
37#include <linux/idr.h> /* For ida_* macros */ 37#include <linux/idr.h> /* For ida_* macros */
38#include <linux/err.h> /* For IS_ERR macros */
38 39
39#include "watchdog_core.h" /* For watchdog_dev_register/... */ 40#include "watchdog_core.h" /* For watchdog_dev_register/... */
40 41
41static DEFINE_IDA(watchdog_ida); 42static DEFINE_IDA(watchdog_ida);
43static struct class *watchdog_class;
42 44
43/** 45/**
44 * watchdog_register_device() - register a watchdog device 46 * watchdog_register_device() - register a watchdog device
@@ -52,7 +54,7 @@ static DEFINE_IDA(watchdog_ida);
52 */ 54 */
53int watchdog_register_device(struct watchdog_device *wdd) 55int watchdog_register_device(struct watchdog_device *wdd)
54{ 56{
55 int ret, id; 57 int ret, id, devno;
56 58
57 if (wdd == NULL || wdd->info == NULL || wdd->ops == NULL) 59 if (wdd == NULL || wdd->info == NULL || wdd->ops == NULL)
58 return -EINVAL; 60 return -EINVAL;
@@ -101,6 +103,16 @@ int watchdog_register_device(struct watchdog_device *wdd)
101 } 103 }
102 } 104 }
103 105
106 devno = wdd->cdev.dev;
107 wdd->dev = device_create(watchdog_class, wdd->parent, devno,
108 NULL, "watchdog%d", wdd->id);
109 if (IS_ERR(wdd->dev)) {
110 watchdog_dev_unregister(wdd);
111 ida_simple_remove(&watchdog_ida, id);
112 ret = PTR_ERR(wdd->dev);
113 return ret;
114 }
115
104 return 0; 116 return 0;
105} 117}
106EXPORT_SYMBOL_GPL(watchdog_register_device); 118EXPORT_SYMBOL_GPL(watchdog_register_device);
@@ -115,6 +127,7 @@ EXPORT_SYMBOL_GPL(watchdog_register_device);
115void watchdog_unregister_device(struct watchdog_device *wdd) 127void watchdog_unregister_device(struct watchdog_device *wdd)
116{ 128{
117 int ret; 129 int ret;
130 int devno = wdd->cdev.dev;
118 131
119 if (wdd == NULL) 132 if (wdd == NULL)
120 return; 133 return;
@@ -122,18 +135,35 @@ void watchdog_unregister_device(struct watchdog_device *wdd)
122 ret = watchdog_dev_unregister(wdd); 135 ret = watchdog_dev_unregister(wdd);
123 if (ret) 136 if (ret)
124 pr_err("error unregistering /dev/watchdog (err=%d)\n", ret); 137 pr_err("error unregistering /dev/watchdog (err=%d)\n", ret);
138 device_destroy(watchdog_class, devno);
125 ida_simple_remove(&watchdog_ida, wdd->id); 139 ida_simple_remove(&watchdog_ida, wdd->id);
140 wdd->dev = NULL;
126} 141}
127EXPORT_SYMBOL_GPL(watchdog_unregister_device); 142EXPORT_SYMBOL_GPL(watchdog_unregister_device);
128 143
129static int __init watchdog_init(void) 144static int __init watchdog_init(void)
130{ 145{
131 return watchdog_dev_init(); 146 int err;
147
148 watchdog_class = class_create(THIS_MODULE, "watchdog");
149 if (IS_ERR(watchdog_class)) {
150 pr_err("couldn't create class\n");
151 return PTR_ERR(watchdog_class);
152 }
153
154 err = watchdog_dev_init();
155 if (err < 0) {
156 class_destroy(watchdog_class);
157 return err;
158 }
159
160 return 0;
132} 161}
133 162
134static void __exit watchdog_exit(void) 163static void __exit watchdog_exit(void)
135{ 164{
136 watchdog_dev_exit(); 165 watchdog_dev_exit();
166 class_destroy(watchdog_class);
137 ida_destroy(&watchdog_ida); 167 ida_destroy(&watchdog_ida);
138} 168}
139 169
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index 3b22582bcb04..1f011f2d6e48 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -365,6 +365,7 @@ int watchdog_dev_register(struct watchdog_device *watchdog)
365 int err, devno; 365 int err, devno;
366 366
367 if (watchdog->id == 0) { 367 if (watchdog->id == 0) {
368 watchdog_miscdev.parent = watchdog->parent;
368 err = misc_register(&watchdog_miscdev); 369 err = misc_register(&watchdog_miscdev);
369 if (err != 0) { 370 if (err != 0) {
370 pr_err("%s: cannot register miscdev on minor=%d (err=%d).\n", 371 pr_err("%s: cannot register miscdev on minor=%d (err=%d).\n",
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index 32678a50f98d..c3545c5d918a 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -95,6 +95,8 @@ struct watchdog_ops {
95 * 95 *
96 * @id: The watchdog's ID. (Allocated by watchdog_register_device) 96 * @id: The watchdog's ID. (Allocated by watchdog_register_device)
97 * @cdev: The watchdog's Character device. 97 * @cdev: The watchdog's Character device.
98 * @dev: The device for our watchdog
99 * @parent: The parent bus device
98 * @info: Pointer to a watchdog_info structure. 100 * @info: Pointer to a watchdog_info structure.
99 * @ops: Pointer to the list of watchdog operations. 101 * @ops: Pointer to the list of watchdog operations.
100 * @bootstatus: Status of the watchdog device at boot. 102 * @bootstatus: Status of the watchdog device at boot.
@@ -113,6 +115,8 @@ struct watchdog_ops {
113struct watchdog_device { 115struct watchdog_device {
114 int id; 116 int id;
115 struct cdev cdev; 117 struct cdev cdev;
118 struct device *dev;
119 struct device *parent;
116 const struct watchdog_info *info; 120 const struct watchdog_info *info;
117 const struct watchdog_ops *ops; 121 const struct watchdog_ops *ops;
118 unsigned int bootstatus; 122 unsigned int bootstatus;