009-5-watchdog-Create-watchdog-device-in-watchdog_dev-c.patch 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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
  5. The watchdog character device is currently created in watchdog_dev.c,
  6. and the watchdog device in watchdog_core.c. This results in
  7. cross-dependencies, since device creation needs to know the watchdog
  8. character device number as well as the watchdog class, both of which
  9. reside in watchdog_dev.c.
  10. Create the watchdog device in watchdog_dev.c to simplify the code.
  11. Inspired by earlier patch set from Damien Riegel.
  12. Cc: Damien Riegel <damien.riegel@savoirfairelinux.com>
  13. Signed-off-by: Guenter Roeck <linux@roeck-us.net>
  14. Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
  15. ---
  16. drivers/watchdog/watchdog_core.c | 33 ++++--------------
  17. drivers/watchdog/watchdog_core.h | 4 +--
  18. drivers/watchdog/watchdog_dev.c | 73 +++++++++++++++++++++++++++++++++-------
  19. 3 files changed, 69 insertions(+), 41 deletions(-)
  20. --- a/drivers/watchdog/watchdog_core.c
  21. +++ b/drivers/watchdog/watchdog_core.c
  22. @@ -42,7 +42,6 @@
  23. #include "watchdog_core.h" /* For watchdog_dev_register/... */
  24. static DEFINE_IDA(watchdog_ida);
  25. -static struct class *watchdog_class;
  26. /*
  27. * Deferred Registration infrastructure.
  28. @@ -194,7 +193,7 @@ EXPORT_SYMBOL_GPL(watchdog_set_restart_p
  29. static int __watchdog_register_device(struct watchdog_device *wdd)
  30. {
  31. - int ret, id = -1, devno;
  32. + int ret, id = -1;
  33. if (wdd == NULL || wdd->info == NULL || wdd->ops == NULL)
  34. return -EINVAL;
  35. @@ -247,16 +246,6 @@ static int __watchdog_register_device(st
  36. }
  37. }
  38. - devno = wdd->cdev.dev;
  39. - wdd->dev = device_create(watchdog_class, wdd->parent, devno,
  40. - wdd, "watchdog%d", wdd->id);
  41. - if (IS_ERR(wdd->dev)) {
  42. - watchdog_dev_unregister(wdd);
  43. - ida_simple_remove(&watchdog_ida, id);
  44. - ret = PTR_ERR(wdd->dev);
  45. - return ret;
  46. - }
  47. -
  48. if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) {
  49. wdd->reboot_nb.notifier_call = watchdog_reboot_notifier;
  50. @@ -265,9 +254,7 @@ static int __watchdog_register_device(st
  51. dev_err(wdd->dev, "Cannot register reboot notifier (%d)\n",
  52. ret);
  53. watchdog_dev_unregister(wdd);
  54. - device_destroy(watchdog_class, devno);
  55. ida_simple_remove(&watchdog_ida, wdd->id);
  56. - wdd->dev = NULL;
  57. return ret;
  58. }
  59. }
  60. @@ -311,9 +298,6 @@ EXPORT_SYMBOL_GPL(watchdog_register_devi
  61. static void __watchdog_unregister_device(struct watchdog_device *wdd)
  62. {
  63. - int ret;
  64. - int devno;
  65. -
  66. if (wdd == NULL)
  67. return;
  68. @@ -323,13 +307,8 @@ static void __watchdog_unregister_device
  69. if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status))
  70. unregister_reboot_notifier(&wdd->reboot_nb);
  71. - devno = wdd->cdev.dev;
  72. - ret = watchdog_dev_unregister(wdd);
  73. - if (ret)
  74. - pr_err("error unregistering /dev/watchdog (err=%d)\n", ret);
  75. - device_destroy(watchdog_class, devno);
  76. + watchdog_dev_unregister(wdd);
  77. ida_simple_remove(&watchdog_ida, wdd->id);
  78. - wdd->dev = NULL;
  79. }
  80. /**
  81. @@ -370,9 +349,11 @@ static int __init watchdog_deferred_regi
  82. static int __init watchdog_init(void)
  83. {
  84. - watchdog_class = watchdog_dev_init();
  85. - if (IS_ERR(watchdog_class))
  86. - return PTR_ERR(watchdog_class);
  87. + int err;
  88. +
  89. + err = watchdog_dev_init();
  90. + if (err < 0)
  91. + return err;
  92. watchdog_deferred_registration();
  93. return 0;
  94. --- a/drivers/watchdog/watchdog_core.h
  95. +++ b/drivers/watchdog/watchdog_core.h
  96. @@ -32,6 +32,6 @@
  97. * Functions/procedures to be called by the core
  98. */
  99. extern int watchdog_dev_register(struct watchdog_device *);
  100. -extern int watchdog_dev_unregister(struct watchdog_device *);
  101. -extern struct class * __init watchdog_dev_init(void);
  102. +extern void watchdog_dev_unregister(struct watchdog_device *);
  103. +extern int __init watchdog_dev_init(void);
  104. extern void __exit watchdog_dev_exit(void);
  105. --- a/drivers/watchdog/watchdog_dev.c
  106. +++ b/drivers/watchdog/watchdog_dev.c
  107. @@ -628,17 +628,18 @@ static struct miscdevice watchdog_miscde
  108. };
  109. /*
  110. - * watchdog_dev_register: register a watchdog device
  111. + * watchdog_cdev_register: register watchdog character device
  112. * @wdd: watchdog device
  113. + * @devno: character device number
  114. *
  115. - * Register a watchdog device including handling the legacy
  116. + * Register a watchdog character device including handling the legacy
  117. * /dev/watchdog node. /dev/watchdog is actually a miscdevice and
  118. * thus we set it up like that.
  119. */
  120. -int watchdog_dev_register(struct watchdog_device *wdd)
  121. +static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
  122. {
  123. - int err, devno;
  124. + int err;
  125. if (wdd->id == 0) {
  126. old_wdd = wdd;
  127. @@ -656,7 +657,6 @@ int watchdog_dev_register(struct watchdo
  128. }
  129. /* Fill in the data structures */
  130. - devno = MKDEV(MAJOR(watchdog_devt), wdd->id);
  131. cdev_init(&wdd->cdev, &watchdog_fops);
  132. wdd->cdev.owner = wdd->ops->owner;
  133. @@ -674,13 +674,14 @@ int watchdog_dev_register(struct watchdo
  134. }
  135. /*
  136. - * watchdog_dev_unregister: unregister a watchdog device
  137. + * watchdog_cdev_unregister: unregister watchdog character device
  138. * @watchdog: watchdog device
  139. *
  140. - * Unregister the watchdog and if needed the legacy /dev/watchdog device.
  141. + * Unregister watchdog character device and if needed the legacy
  142. + * /dev/watchdog device.
  143. */
  144. -int watchdog_dev_unregister(struct watchdog_device *wdd)
  145. +static void watchdog_cdev_unregister(struct watchdog_device *wdd)
  146. {
  147. mutex_lock(&wdd->lock);
  148. set_bit(WDOG_UNREGISTERED, &wdd->status);
  149. @@ -691,7 +692,6 @@ int watchdog_dev_unregister(struct watch
  150. misc_deregister(&watchdog_miscdev);
  151. old_wdd = NULL;
  152. }
  153. - return 0;
  154. }
  155. static struct class watchdog_class = {
  156. @@ -701,29 +701,76 @@ static struct class watchdog_class = {
  157. };
  158. /*
  159. + * watchdog_dev_register: register a watchdog device
  160. + * @wdd: watchdog device
  161. + *
  162. + * Register a watchdog device including handling the legacy
  163. + * /dev/watchdog node. /dev/watchdog is actually a miscdevice and
  164. + * thus we set it up like that.
  165. + */
  166. +
  167. +int watchdog_dev_register(struct watchdog_device *wdd)
  168. +{
  169. + struct device *dev;
  170. + dev_t devno;
  171. + int ret;
  172. +
  173. + devno = MKDEV(MAJOR(watchdog_devt), wdd->id);
  174. +
  175. + ret = watchdog_cdev_register(wdd, devno);
  176. + if (ret)
  177. + return ret;
  178. +
  179. + dev = device_create(&watchdog_class, wdd->parent, devno, wdd,
  180. + "watchdog%d", wdd->id);
  181. + if (IS_ERR(dev)) {
  182. + watchdog_cdev_unregister(wdd);
  183. + return PTR_ERR(dev);
  184. + }
  185. + wdd->dev = dev;
  186. +
  187. + return ret;
  188. +}
  189. +
  190. +/*
  191. + * watchdog_dev_unregister: unregister a watchdog device
  192. + * @watchdog: watchdog device
  193. + *
  194. + * Unregister watchdog device and if needed the legacy
  195. + * /dev/watchdog device.
  196. + */
  197. +
  198. +void watchdog_dev_unregister(struct watchdog_device *wdd)
  199. +{
  200. + watchdog_cdev_unregister(wdd);
  201. + device_destroy(&watchdog_class, wdd->dev->devt);
  202. + wdd->dev = NULL;
  203. +}
  204. +
  205. +/*
  206. * watchdog_dev_init: init dev part of watchdog core
  207. *
  208. * Allocate a range of chardev nodes to use for watchdog devices
  209. */
  210. -struct class * __init watchdog_dev_init(void)
  211. +int __init watchdog_dev_init(void)
  212. {
  213. int err;
  214. err = class_register(&watchdog_class);
  215. if (err < 0) {
  216. pr_err("couldn't register class\n");
  217. - return ERR_PTR(err);
  218. + return err;
  219. }
  220. err = alloc_chrdev_region(&watchdog_devt, 0, MAX_DOGS, "watchdog");
  221. if (err < 0) {
  222. pr_err("watchdog: unable to allocate char dev region\n");
  223. class_unregister(&watchdog_class);
  224. - return ERR_PTR(err);
  225. + return err;
  226. }
  227. - return &watchdog_class;
  228. + return 0;
  229. }
  230. /*