sbsa_gwdt.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. /*
  2. * SBSA(Server Base System Architecture) Generic Watchdog driver
  3. *
  4. * Copyright (c) 2015, Linaro Ltd.
  5. * Author: Fu Wei <fu.wei@linaro.org>
  6. * Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
  7. * Al Stone <al.stone@linaro.org>
  8. * Timur Tabi <timur@codeaurora.org>
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License 2 as published
  12. * by the Free Software Foundation.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * ARM SBSA Generic Watchdog has two stage timeouts:
  20. * the first signal (WS0) is for alerting the system by interrupt,
  21. * the second one (WS1) is a real hardware reset.
  22. * More details about the hardware specification of this device:
  23. * ARM DEN0029B - Server Base System Architecture (SBSA)
  24. *
  25. * This driver can operate ARM SBSA Generic Watchdog as a single stage watchdog
  26. * or a two stages watchdog, it's set up by the module parameter "action".
  27. * In the single stage mode, when the timeout is reached, your system
  28. * will be reset by WS1. The first signal (WS0) is ignored.
  29. * In the two stages mode, when the timeout is reached, the first signal (WS0)
  30. * will trigger panic. If the system is getting into trouble and cannot be reset
  31. * by panic or restart properly by the kdump kernel(if supported), then the
  32. * second stage (as long as the first stage) will be reached, system will be
  33. * reset by WS1. This function can help administrator to backup the system
  34. * context info by panic console output or kdump.
  35. *
  36. * SBSA GWDT:
  37. * if action is 1 (the two stages mode):
  38. * |--------WOR-------WS0--------WOR-------WS1
  39. * |----timeout-----(panic)----timeout-----reset
  40. *
  41. * if action is 0 (the single stage mode):
  42. * |------WOR-----WS0(ignored)-----WOR------WS1
  43. * |--------------timeout-------------------reset
  44. *
  45. * Note: Since this watchdog timer has two stages, and each stage is determined
  46. * by WOR, in the single stage mode, the timeout is (WOR * 2); in the two
  47. * stages mode, the timeout is WOR. The maximum timeout in the two stages mode
  48. * is half of that in the single stage mode.
  49. *
  50. */
  51. #include <linux/io.h>
  52. #include <linux/io-64-nonatomic-lo-hi.h>
  53. #include <linux/interrupt.h>
  54. #include <linux/module.h>
  55. #include <linux/moduleparam.h>
  56. #include <linux/of.h>
  57. #include <linux/of_device.h>
  58. #include <linux/platform_device.h>
  59. #include <linux/uaccess.h>
  60. #include <linux/watchdog.h>
  61. #include <asm/arch_timer.h>
  62. #define DRV_NAME "sbsa-gwdt"
  63. #define WATCHDOG_NAME "SBSA Generic Watchdog"
  64. /* SBSA Generic Watchdog register definitions */
  65. /* refresh frame */
  66. #define SBSA_GWDT_WRR 0x000
  67. /* control frame */
  68. #define SBSA_GWDT_WCS 0x000
  69. #define SBSA_GWDT_WOR 0x008
  70. #define SBSA_GWDT_WCV 0x010
  71. /* refresh/control frame */
  72. #define SBSA_GWDT_W_IIDR 0xfcc
  73. #define SBSA_GWDT_IDR 0xfd0
  74. /* Watchdog Control and Status Register */
  75. #define SBSA_GWDT_WCS_EN BIT(0)
  76. #define SBSA_GWDT_WCS_WS0 BIT(1)
  77. #define SBSA_GWDT_WCS_WS1 BIT(2)
  78. /**
  79. * struct sbsa_gwdt - Internal representation of the SBSA GWDT
  80. * @wdd: kernel watchdog_device structure
  81. * @clk: store the System Counter clock frequency, in Hz.
  82. * @refresh_base: Virtual address of the watchdog refresh frame
  83. * @control_base: Virtual address of the watchdog control frame
  84. */
  85. struct sbsa_gwdt {
  86. struct watchdog_device wdd;
  87. u32 clk;
  88. void __iomem *refresh_base;
  89. void __iomem *control_base;
  90. };
  91. #define DEFAULT_TIMEOUT 10 /* seconds */
  92. static unsigned int timeout;
  93. module_param(timeout, uint, 0);
  94. MODULE_PARM_DESC(timeout,
  95. "Watchdog timeout in seconds. (>=0, default="
  96. __MODULE_STRING(DEFAULT_TIMEOUT) ")");
  97. /*
  98. * action refers to action taken when watchdog gets WS0
  99. * 0 = skip
  100. * 1 = panic
  101. * defaults to skip (0)
  102. */
  103. static int action;
  104. module_param(action, int, 0);
  105. MODULE_PARM_DESC(action, "after watchdog gets WS0 interrupt, do: "
  106. "0 = skip(*) 1 = panic");
  107. static bool nowayout = WATCHDOG_NOWAYOUT;
  108. module_param(nowayout, bool, S_IRUGO);
  109. MODULE_PARM_DESC(nowayout,
  110. "Watchdog cannot be stopped once started (default="
  111. __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
  112. /*
  113. * watchdog operation functions
  114. */
  115. static int sbsa_gwdt_set_timeout(struct watchdog_device *wdd,
  116. unsigned int timeout)
  117. {
  118. struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
  119. wdd->timeout = timeout;
  120. if (action)
  121. writel(gwdt->clk * timeout,
  122. gwdt->control_base + SBSA_GWDT_WOR);
  123. else
  124. /*
  125. * In the single stage mode, The first signal (WS0) is ignored,
  126. * the timeout is (WOR * 2), so the WOR should be configured
  127. * to half value of timeout.
  128. */
  129. writel(gwdt->clk / 2 * timeout,
  130. gwdt->control_base + SBSA_GWDT_WOR);
  131. return 0;
  132. }
  133. static unsigned int sbsa_gwdt_get_timeleft(struct watchdog_device *wdd)
  134. {
  135. struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
  136. u64 timeleft = 0;
  137. /*
  138. * In the single stage mode, if WS0 is deasserted
  139. * (watchdog is in the first stage),
  140. * timeleft = WOR + (WCV - system counter)
  141. */
  142. if (!action &&
  143. !(readl(gwdt->control_base + SBSA_GWDT_WCS) & SBSA_GWDT_WCS_WS0))
  144. timeleft += readl(gwdt->control_base + SBSA_GWDT_WOR);
  145. timeleft += lo_hi_readq(gwdt->control_base + SBSA_GWDT_WCV) -
  146. arch_counter_get_cntvct();
  147. do_div(timeleft, gwdt->clk);
  148. return timeleft;
  149. }
  150. static int sbsa_gwdt_keepalive(struct watchdog_device *wdd)
  151. {
  152. struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
  153. /*
  154. * Writing WRR for an explicit watchdog refresh.
  155. * You can write anyting (like 0).
  156. */
  157. writel(0, gwdt->refresh_base + SBSA_GWDT_WRR);
  158. return 0;
  159. }
  160. static int sbsa_gwdt_start(struct watchdog_device *wdd)
  161. {
  162. struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
  163. /* writing WCS will cause an explicit watchdog refresh */
  164. writel(SBSA_GWDT_WCS_EN, gwdt->control_base + SBSA_GWDT_WCS);
  165. return 0;
  166. }
  167. static int sbsa_gwdt_stop(struct watchdog_device *wdd)
  168. {
  169. struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
  170. /* Simply write 0 to WCS to clean WCS_EN bit */
  171. writel(0, gwdt->control_base + SBSA_GWDT_WCS);
  172. return 0;
  173. }
  174. static irqreturn_t sbsa_gwdt_interrupt(int irq, void *dev_id)
  175. {
  176. panic(WATCHDOG_NAME " timeout");
  177. return IRQ_HANDLED;
  178. }
  179. static struct watchdog_info sbsa_gwdt_info = {
  180. .identity = WATCHDOG_NAME,
  181. .options = WDIOF_SETTIMEOUT |
  182. WDIOF_KEEPALIVEPING |
  183. WDIOF_MAGICCLOSE |
  184. WDIOF_CARDRESET,
  185. };
  186. static struct watchdog_ops sbsa_gwdt_ops = {
  187. .owner = THIS_MODULE,
  188. .start = sbsa_gwdt_start,
  189. .stop = sbsa_gwdt_stop,
  190. .ping = sbsa_gwdt_keepalive,
  191. .set_timeout = sbsa_gwdt_set_timeout,
  192. .get_timeleft = sbsa_gwdt_get_timeleft,
  193. };
  194. static int sbsa_gwdt_probe(struct platform_device *pdev)
  195. {
  196. void __iomem *rf_base, *cf_base;
  197. struct device *dev = &pdev->dev;
  198. struct watchdog_device *wdd;
  199. struct sbsa_gwdt *gwdt;
  200. struct resource *res;
  201. int ret, irq;
  202. u32 status;
  203. gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
  204. if (!gwdt)
  205. return -ENOMEM;
  206. platform_set_drvdata(pdev, gwdt);
  207. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  208. cf_base = devm_ioremap_resource(dev, res);
  209. if (IS_ERR(cf_base))
  210. return PTR_ERR(cf_base);
  211. res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  212. rf_base = devm_ioremap_resource(dev, res);
  213. if (IS_ERR(rf_base))
  214. return PTR_ERR(rf_base);
  215. /*
  216. * Get the frequency of system counter from the cp15 interface of ARM
  217. * Generic timer. We don't need to check it, because if it returns "0",
  218. * system would panic in very early stage.
  219. */
  220. gwdt->clk = arch_timer_get_cntfrq();
  221. gwdt->refresh_base = rf_base;
  222. gwdt->control_base = cf_base;
  223. wdd = &gwdt->wdd;
  224. wdd->parent = dev;
  225. wdd->info = &sbsa_gwdt_info;
  226. wdd->ops = &sbsa_gwdt_ops;
  227. wdd->min_timeout = 1;
  228. wdd->max_hw_heartbeat_ms = U32_MAX / gwdt->clk * 1000;
  229. wdd->timeout = DEFAULT_TIMEOUT;
  230. watchdog_set_drvdata(wdd, gwdt);
  231. watchdog_set_nowayout(wdd, nowayout);
  232. status = readl(cf_base + SBSA_GWDT_WCS);
  233. if (status & SBSA_GWDT_WCS_WS1) {
  234. dev_warn(dev, "System reset by WDT.\n");
  235. wdd->bootstatus |= WDIOF_CARDRESET;
  236. }
  237. if (status & SBSA_GWDT_WCS_EN)
  238. set_bit(WDOG_HW_RUNNING, &wdd->status);
  239. if (action) {
  240. irq = platform_get_irq(pdev, 0);
  241. if (irq < 0) {
  242. action = 0;
  243. dev_warn(dev, "unable to get ws0 interrupt.\n");
  244. } else {
  245. /*
  246. * In case there is a pending ws0 interrupt, just ping
  247. * the watchdog before registering the interrupt routine
  248. */
  249. writel(0, rf_base + SBSA_GWDT_WRR);
  250. if (devm_request_irq(dev, irq, sbsa_gwdt_interrupt, 0,
  251. pdev->name, gwdt)) {
  252. action = 0;
  253. dev_warn(dev, "unable to request IRQ %d.\n",
  254. irq);
  255. }
  256. }
  257. if (!action)
  258. dev_warn(dev, "falling back to single stage mode.\n");
  259. }
  260. /*
  261. * In the single stage mode, The first signal (WS0) is ignored,
  262. * the timeout is (WOR * 2), so the maximum timeout should be doubled.
  263. */
  264. if (!action)
  265. wdd->max_hw_heartbeat_ms *= 2;
  266. watchdog_init_timeout(wdd, timeout, dev);
  267. /*
  268. * Update timeout to WOR.
  269. * Because of the explicit watchdog refresh mechanism,
  270. * it's also a ping, if watchdog is enabled.
  271. */
  272. sbsa_gwdt_set_timeout(wdd, wdd->timeout);
  273. ret = watchdog_register_device(wdd);
  274. if (ret)
  275. return ret;
  276. dev_info(dev, "Initialized with %ds timeout @ %u Hz, action=%d.%s\n",
  277. wdd->timeout, gwdt->clk, action,
  278. status & SBSA_GWDT_WCS_EN ? " [enabled]" : "");
  279. return 0;
  280. }
  281. static void sbsa_gwdt_shutdown(struct platform_device *pdev)
  282. {
  283. struct sbsa_gwdt *gwdt = platform_get_drvdata(pdev);
  284. sbsa_gwdt_stop(&gwdt->wdd);
  285. }
  286. static int sbsa_gwdt_remove(struct platform_device *pdev)
  287. {
  288. struct sbsa_gwdt *gwdt = platform_get_drvdata(pdev);
  289. watchdog_unregister_device(&gwdt->wdd);
  290. return 0;
  291. }
  292. /* Disable watchdog if it is active during suspend */
  293. static int __maybe_unused sbsa_gwdt_suspend(struct device *dev)
  294. {
  295. struct sbsa_gwdt *gwdt = dev_get_drvdata(dev);
  296. if (watchdog_active(&gwdt->wdd))
  297. sbsa_gwdt_stop(&gwdt->wdd);
  298. return 0;
  299. }
  300. /* Enable watchdog if necessary */
  301. static int __maybe_unused sbsa_gwdt_resume(struct device *dev)
  302. {
  303. struct sbsa_gwdt *gwdt = dev_get_drvdata(dev);
  304. if (watchdog_active(&gwdt->wdd))
  305. sbsa_gwdt_start(&gwdt->wdd);
  306. return 0;
  307. }
  308. static const struct dev_pm_ops sbsa_gwdt_pm_ops = {
  309. SET_SYSTEM_SLEEP_PM_OPS(sbsa_gwdt_suspend, sbsa_gwdt_resume)
  310. };
  311. static const struct of_device_id sbsa_gwdt_of_match[] = {
  312. { .compatible = "arm,sbsa-gwdt", },
  313. {},
  314. };
  315. MODULE_DEVICE_TABLE(of, sbsa_gwdt_of_match);
  316. static const struct platform_device_id sbsa_gwdt_pdev_match[] = {
  317. { .name = DRV_NAME, },
  318. {},
  319. };
  320. MODULE_DEVICE_TABLE(platform, sbsa_gwdt_pdev_match);
  321. static struct platform_driver sbsa_gwdt_driver = {
  322. .driver = {
  323. .name = DRV_NAME,
  324. .pm = &sbsa_gwdt_pm_ops,
  325. .of_match_table = sbsa_gwdt_of_match,
  326. },
  327. .probe = sbsa_gwdt_probe,
  328. .remove = sbsa_gwdt_remove,
  329. .shutdown = sbsa_gwdt_shutdown,
  330. .id_table = sbsa_gwdt_pdev_match,
  331. };
  332. module_platform_driver(sbsa_gwdt_driver);
  333. MODULE_DESCRIPTION("SBSA Generic Watchdog Driver");
  334. MODULE_AUTHOR("Fu Wei <fu.wei@linaro.org>");
  335. MODULE_AUTHOR("Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>");
  336. MODULE_AUTHOR("Al Stone <al.stone@linaro.org>");
  337. MODULE_AUTHOR("Timur Tabi <timur@codeaurora.org>");
  338. MODULE_LICENSE("GPL v2");
  339. MODULE_ALIAS("platform:" DRV_NAME);