watchdog_pretimeout.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2015-2016 Mentor Graphics
  4. */
  5. #include <linux/list.h>
  6. #include <linux/slab.h>
  7. #include <linux/spinlock.h>
  8. #include <linux/string.h>
  9. #include <linux/sysfs.h>
  10. #include <linux/types.h>
  11. #include <linux/watchdog.h>
  12. #include "watchdog_core.h"
  13. #include "watchdog_pretimeout.h"
  14. /* Default watchdog pretimeout governor */
  15. static struct watchdog_governor *default_gov;
  16. /* The spinlock protects default_gov, wdd->gov and pretimeout_list */
  17. static DEFINE_SPINLOCK(pretimeout_lock);
  18. /* List of watchdog devices, which can generate a pretimeout event */
  19. static LIST_HEAD(pretimeout_list);
  20. struct watchdog_pretimeout {
  21. struct watchdog_device *wdd;
  22. struct list_head entry;
  23. };
  24. /* The mutex protects governor list and serializes external interfaces */
  25. static DEFINE_MUTEX(governor_lock);
  26. /* List of the registered watchdog pretimeout governors */
  27. static LIST_HEAD(governor_list);
  28. struct governor_priv {
  29. struct watchdog_governor *gov;
  30. struct list_head entry;
  31. };
  32. static struct governor_priv *find_governor_by_name(const char *gov_name)
  33. {
  34. struct governor_priv *priv;
  35. list_for_each_entry(priv, &governor_list, entry)
  36. if (sysfs_streq(gov_name, priv->gov->name))
  37. return priv;
  38. return NULL;
  39. }
  40. int watchdog_pretimeout_available_governors_get(char *buf)
  41. {
  42. struct governor_priv *priv;
  43. int count = 0;
  44. mutex_lock(&governor_lock);
  45. list_for_each_entry(priv, &governor_list, entry)
  46. count += sysfs_emit_at(buf, count, "%s\n", priv->gov->name);
  47. mutex_unlock(&governor_lock);
  48. return count;
  49. }
  50. int watchdog_pretimeout_governor_get(struct watchdog_device *wdd, char *buf)
  51. {
  52. int count = 0;
  53. spin_lock_irq(&pretimeout_lock);
  54. if (wdd->gov)
  55. count = sysfs_emit(buf, "%s\n", wdd->gov->name);
  56. spin_unlock_irq(&pretimeout_lock);
  57. return count;
  58. }
  59. int watchdog_pretimeout_governor_set(struct watchdog_device *wdd,
  60. const char *buf)
  61. {
  62. struct governor_priv *priv;
  63. mutex_lock(&governor_lock);
  64. priv = find_governor_by_name(buf);
  65. if (!priv) {
  66. mutex_unlock(&governor_lock);
  67. return -EINVAL;
  68. }
  69. spin_lock_irq(&pretimeout_lock);
  70. wdd->gov = priv->gov;
  71. spin_unlock_irq(&pretimeout_lock);
  72. mutex_unlock(&governor_lock);
  73. return 0;
  74. }
  75. void watchdog_notify_pretimeout(struct watchdog_device *wdd)
  76. {
  77. unsigned long flags;
  78. spin_lock_irqsave(&pretimeout_lock, flags);
  79. if (!wdd->gov) {
  80. spin_unlock_irqrestore(&pretimeout_lock, flags);
  81. return;
  82. }
  83. wdd->gov->pretimeout(wdd);
  84. spin_unlock_irqrestore(&pretimeout_lock, flags);
  85. }
  86. EXPORT_SYMBOL_GPL(watchdog_notify_pretimeout);
  87. int watchdog_register_governor(struct watchdog_governor *gov)
  88. {
  89. struct watchdog_pretimeout *p;
  90. struct governor_priv *priv;
  91. priv = kzalloc_obj(*priv);
  92. if (!priv)
  93. return -ENOMEM;
  94. mutex_lock(&governor_lock);
  95. if (find_governor_by_name(gov->name)) {
  96. mutex_unlock(&governor_lock);
  97. kfree(priv);
  98. return -EBUSY;
  99. }
  100. priv->gov = gov;
  101. list_add(&priv->entry, &governor_list);
  102. if (!strncmp(gov->name, WATCHDOG_PRETIMEOUT_DEFAULT_GOV,
  103. WATCHDOG_GOV_NAME_MAXLEN)) {
  104. spin_lock_irq(&pretimeout_lock);
  105. default_gov = gov;
  106. list_for_each_entry(p, &pretimeout_list, entry)
  107. if (!p->wdd->gov)
  108. p->wdd->gov = default_gov;
  109. spin_unlock_irq(&pretimeout_lock);
  110. }
  111. mutex_unlock(&governor_lock);
  112. return 0;
  113. }
  114. EXPORT_SYMBOL(watchdog_register_governor);
  115. void watchdog_unregister_governor(struct watchdog_governor *gov)
  116. {
  117. struct watchdog_pretimeout *p;
  118. struct governor_priv *priv, *t;
  119. mutex_lock(&governor_lock);
  120. list_for_each_entry_safe(priv, t, &governor_list, entry) {
  121. if (priv->gov == gov) {
  122. list_del(&priv->entry);
  123. kfree(priv);
  124. break;
  125. }
  126. }
  127. spin_lock_irq(&pretimeout_lock);
  128. list_for_each_entry(p, &pretimeout_list, entry)
  129. if (p->wdd->gov == gov)
  130. p->wdd->gov = default_gov;
  131. spin_unlock_irq(&pretimeout_lock);
  132. mutex_unlock(&governor_lock);
  133. }
  134. EXPORT_SYMBOL(watchdog_unregister_governor);
  135. int watchdog_register_pretimeout(struct watchdog_device *wdd)
  136. {
  137. struct watchdog_pretimeout *p;
  138. if (!watchdog_have_pretimeout(wdd))
  139. return 0;
  140. p = kzalloc_obj(*p);
  141. if (!p)
  142. return -ENOMEM;
  143. spin_lock_irq(&pretimeout_lock);
  144. list_add(&p->entry, &pretimeout_list);
  145. p->wdd = wdd;
  146. wdd->gov = default_gov;
  147. spin_unlock_irq(&pretimeout_lock);
  148. return 0;
  149. }
  150. void watchdog_unregister_pretimeout(struct watchdog_device *wdd)
  151. {
  152. struct watchdog_pretimeout *p, *t;
  153. if (!watchdog_have_pretimeout(wdd))
  154. return;
  155. spin_lock_irq(&pretimeout_lock);
  156. wdd->gov = NULL;
  157. list_for_each_entry_safe(p, t, &pretimeout_list, entry) {
  158. if (p->wdd == wdd) {
  159. list_del(&p->entry);
  160. kfree(p);
  161. break;
  162. }
  163. }
  164. spin_unlock_irq(&pretimeout_lock);
  165. }