diff options
-rw-r--r-- | Documentation/watchdog/watchdog-kernel-api.txt | 5 | ||||
-rw-r--r-- | drivers/watchdog/watchdog_core.c | 34 | ||||
-rw-r--r-- | drivers/watchdog/watchdog_dev.c | 1 | ||||
-rw-r--r-- | include/linux/watchdog.h | 4 |
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: | |||
41 | struct watchdog_device { | 41 | struct 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 | ||
41 | static DEFINE_IDA(watchdog_ida); | 42 | static DEFINE_IDA(watchdog_ida); |
43 | static 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 | */ |
53 | int watchdog_register_device(struct watchdog_device *wdd) | 55 | int 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 | } |
106 | EXPORT_SYMBOL_GPL(watchdog_register_device); | 118 | EXPORT_SYMBOL_GPL(watchdog_register_device); |
@@ -115,6 +127,7 @@ EXPORT_SYMBOL_GPL(watchdog_register_device); | |||
115 | void watchdog_unregister_device(struct watchdog_device *wdd) | 127 | void 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 | } |
127 | EXPORT_SYMBOL_GPL(watchdog_unregister_device); | 142 | EXPORT_SYMBOL_GPL(watchdog_unregister_device); |
128 | 143 | ||
129 | static int __init watchdog_init(void) | 144 | static 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 | ||
134 | static void __exit watchdog_exit(void) | 163 | static 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 { | |||
113 | struct watchdog_device { | 115 | struct 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; |