1 From 32ecc6392654a0db34b310e8924b5b2c3b8bf503 Mon Sep 17 00:00:00 2001
2 From: Guenter Roeck <linux@roeck-us.net>
3 Date: Fri, 25 Dec 2015 16:01:40 -0800
4 Subject: watchdog: Create watchdog device in watchdog_dev.c
6 The watchdog character device is currently created in watchdog_dev.c,
7 and the watchdog device in watchdog_core.c. This results in
8 cross-dependencies, since device creation needs to know the watchdog
9 character device number as well as the watchdog class, both of which
10 reside in watchdog_dev.c.
12 Create the watchdog device in watchdog_dev.c to simplify the code.
14 Inspired by earlier patch set from Damien Riegel.
16 Cc: Damien Riegel <damien.riegel@savoirfairelinux.com>
17 Signed-off-by: Guenter Roeck <linux@roeck-us.net>
18 Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
20 drivers/watchdog/watchdog_core.c | 33 ++++--------------
21 drivers/watchdog/watchdog_core.h | 4 +--
22 drivers/watchdog/watchdog_dev.c | 73 +++++++++++++++++++++++++++++++++-------
23 3 files changed, 69 insertions(+), 41 deletions(-)
25 --- a/drivers/watchdog/watchdog_core.c
26 +++ b/drivers/watchdog/watchdog_core.c
28 #include "watchdog_core.h" /* For watchdog_dev_register/... */
30 static DEFINE_IDA(watchdog_ida);
31 -static struct class *watchdog_class;
34 * Deferred Registration infrastructure.
35 @@ -194,7 +193,7 @@ EXPORT_SYMBOL_GPL(watchdog_set_restart_p
37 static int __watchdog_register_device(struct watchdog_device *wdd)
39 - int ret, id = -1, devno;
42 if (wdd == NULL || wdd->info == NULL || wdd->ops == NULL)
44 @@ -247,16 +246,6 @@ static int __watchdog_register_device(st
48 - devno = wdd->cdev.dev;
49 - wdd->dev = device_create(watchdog_class, wdd->parent, devno,
50 - wdd, "watchdog%d", wdd->id);
51 - if (IS_ERR(wdd->dev)) {
52 - watchdog_dev_unregister(wdd);
53 - ida_simple_remove(&watchdog_ida, id);
54 - ret = PTR_ERR(wdd->dev);
58 if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) {
59 wdd->reboot_nb.notifier_call = watchdog_reboot_notifier;
61 @@ -265,9 +254,7 @@ static int __watchdog_register_device(st
62 dev_err(wdd->dev, "Cannot register reboot notifier (%d)\n",
64 watchdog_dev_unregister(wdd);
65 - device_destroy(watchdog_class, devno);
66 ida_simple_remove(&watchdog_ida, wdd->id);
71 @@ -311,9 +298,6 @@ EXPORT_SYMBOL_GPL(watchdog_register_devi
73 static void __watchdog_unregister_device(struct watchdog_device *wdd)
81 @@ -323,13 +307,8 @@ static void __watchdog_unregister_device
82 if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status))
83 unregister_reboot_notifier(&wdd->reboot_nb);
85 - devno = wdd->cdev.dev;
86 - ret = watchdog_dev_unregister(wdd);
88 - pr_err("error unregistering /dev/watchdog (err=%d)\n", ret);
89 - device_destroy(watchdog_class, devno);
90 + watchdog_dev_unregister(wdd);
91 ida_simple_remove(&watchdog_ida, wdd->id);
96 @@ -370,9 +349,11 @@ static int __init watchdog_deferred_regi
98 static int __init watchdog_init(void)
100 - watchdog_class = watchdog_dev_init();
101 - if (IS_ERR(watchdog_class))
102 - return PTR_ERR(watchdog_class);
105 + err = watchdog_dev_init();
109 watchdog_deferred_registration();
111 --- a/drivers/watchdog/watchdog_core.h
112 +++ b/drivers/watchdog/watchdog_core.h
114 * Functions/procedures to be called by the core
116 extern int watchdog_dev_register(struct watchdog_device *);
117 -extern int watchdog_dev_unregister(struct watchdog_device *);
118 -extern struct class * __init watchdog_dev_init(void);
119 +extern void watchdog_dev_unregister(struct watchdog_device *);
120 +extern int __init watchdog_dev_init(void);
121 extern void __exit watchdog_dev_exit(void);
122 --- a/drivers/watchdog/watchdog_dev.c
123 +++ b/drivers/watchdog/watchdog_dev.c
124 @@ -628,17 +628,18 @@ static struct miscdevice watchdog_miscde
128 - * watchdog_dev_register: register a watchdog device
129 + * watchdog_cdev_register: register watchdog character device
130 * @wdd: watchdog device
131 + * @devno: character device number
133 - * Register a watchdog device including handling the legacy
134 + * Register a watchdog character device including handling the legacy
135 * /dev/watchdog node. /dev/watchdog is actually a miscdevice and
136 * thus we set it up like that.
139 -int watchdog_dev_register(struct watchdog_device *wdd)
140 +static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
147 @@ -656,7 +657,6 @@ int watchdog_dev_register(struct watchdo
150 /* Fill in the data structures */
151 - devno = MKDEV(MAJOR(watchdog_devt), wdd->id);
152 cdev_init(&wdd->cdev, &watchdog_fops);
153 wdd->cdev.owner = wdd->ops->owner;
155 @@ -674,13 +674,14 @@ int watchdog_dev_register(struct watchdo
159 - * watchdog_dev_unregister: unregister a watchdog device
160 + * watchdog_cdev_unregister: unregister watchdog character device
161 * @watchdog: watchdog device
163 - * Unregister the watchdog and if needed the legacy /dev/watchdog device.
164 + * Unregister watchdog character device and if needed the legacy
165 + * /dev/watchdog device.
168 -int watchdog_dev_unregister(struct watchdog_device *wdd)
169 +static void watchdog_cdev_unregister(struct watchdog_device *wdd)
171 mutex_lock(&wdd->lock);
172 set_bit(WDOG_UNREGISTERED, &wdd->status);
173 @@ -691,7 +692,6 @@ int watchdog_dev_unregister(struct watch
174 misc_deregister(&watchdog_miscdev);
180 static struct class watchdog_class = {
181 @@ -701,29 +701,76 @@ static struct class watchdog_class = {
185 + * watchdog_dev_register: register a watchdog device
186 + * @wdd: watchdog device
188 + * Register a watchdog device including handling the legacy
189 + * /dev/watchdog node. /dev/watchdog is actually a miscdevice and
190 + * thus we set it up like that.
193 +int watchdog_dev_register(struct watchdog_device *wdd)
195 + struct device *dev;
199 + devno = MKDEV(MAJOR(watchdog_devt), wdd->id);
201 + ret = watchdog_cdev_register(wdd, devno);
205 + dev = device_create(&watchdog_class, wdd->parent, devno, wdd,
206 + "watchdog%d", wdd->id);
208 + watchdog_cdev_unregister(wdd);
209 + return PTR_ERR(dev);
217 + * watchdog_dev_unregister: unregister a watchdog device
218 + * @watchdog: watchdog device
220 + * Unregister watchdog device and if needed the legacy
221 + * /dev/watchdog device.
224 +void watchdog_dev_unregister(struct watchdog_device *wdd)
226 + watchdog_cdev_unregister(wdd);
227 + device_destroy(&watchdog_class, wdd->dev->devt);
232 * watchdog_dev_init: init dev part of watchdog core
234 * Allocate a range of chardev nodes to use for watchdog devices
237 -struct class * __init watchdog_dev_init(void)
238 +int __init watchdog_dev_init(void)
242 err = class_register(&watchdog_class);
244 pr_err("couldn't register class\n");
245 - return ERR_PTR(err);
249 err = alloc_chrdev_region(&watchdog_devt, 0, MAX_DOGS, "watchdog");
251 pr_err("watchdog: unable to allocate char dev region\n");
252 class_unregister(&watchdog_class);
253 - return ERR_PTR(err);
257 - return &watchdog_class;