aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-12-24 14:27:45 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-24 14:27:45 -0500
commit3a77fa854477a12fc543a69d00ff8a42adefc586 (patch)
tree2902fe8b833cb64f9a5eb5e1276e9dcc6426c123
parent01e0d6037de687fd3bb8b45ab1376e8322c1fcc9 (diff)
parent067161281f428aa7c6e153e06aab7b5fe1ed1e98 (diff)
Merge tag 'watchdog-for-linus-v4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging
Pull watchdog updates from Wim Van Sebroeck and Guenter Roeck: - new driver for Add Loongson1 SoC - minor cleanup and fixes in various drivers * tag 'watchdog-for-linus-v4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: watchdog: it87_wdt: add IT8620E ID watchdog: mpc8xxx: Remove unneeded linux/miscdevice.h include watchdog: octeon: Remove unneeded linux/miscdevice.h include watchdog: bcm2835_wdt: set WDOG_HW_RUNNING bit when appropriate watchdog: loongson1: Add Loongson1 SoC watchdog driver watchdog: cpwd: remove memory allocate failure message watchdog: da9062/61: watchdog driver intel-mid_wdt: Error code is just an integer intel-mid_wdt: make sure watchdog is not running at startup watchdog: mei_wdt: request stop on reboot to prevent false positive event watchdog: hpwdt: changed maintainer information watchdog: jz4740: Fix modular build watchdog: qcom: fix kernel panic due to external abort on non-linefetch watchdog: davinci: add support for deferred probing watchdog: meson: Remove unneeded platform MODULE_ALIAS watchdog: Standardize leading tabs and spaces in Kconfig file watchdog: max77620_wdt: fix module autoload watchdog: bcm7038_wdt: fix module autoload
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/watchdog/Kconfig49
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/bcm2835_wdt.c20
-rw-r--r--drivers/watchdog/bcm7038_wdt.c1
-rw-r--r--drivers/watchdog/cpwd.c23
-rw-r--r--drivers/watchdog/da9062_wdt.c12
-rw-r--r--drivers/watchdog/davinci_wdt.c6
-rw-r--r--drivers/watchdog/intel-mid_wdt.c22
-rw-r--r--drivers/watchdog/it87_wdt.c4
-rw-r--r--drivers/watchdog/jz4740_wdt.c2
-rw-r--r--drivers/watchdog/loongson1_wdt.c170
-rw-r--r--drivers/watchdog/max77620_wdt.c1
-rw-r--r--drivers/watchdog/mei_wdt.c2
-rw-r--r--drivers/watchdog/meson_gxbb_wdt.c1
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c1
-rw-r--r--drivers/watchdog/octeon-wdt-main.c1
-rw-r--r--drivers/watchdog/qcom-wdt.c2
18 files changed, 262 insertions, 58 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index a9f277ace0a6..cfff2c9e3d94 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5735,7 +5735,7 @@ S: Maintained
5735F: drivers/media/dvb-frontends/hd29l2* 5735F: drivers/media/dvb-frontends/hd29l2*
5736 5736
5737HEWLETT PACKARD ENTERPRISE ILO NMI WATCHDOG DRIVER 5737HEWLETT PACKARD ENTERPRISE ILO NMI WATCHDOG DRIVER
5738M: Brian Boylston <brian.boylston@hpe.com> 5738M: Jimmy Vance <jimmy.vance@hpe.com>
5739S: Supported 5739S: Supported
5740F: Documentation/watchdog/hpwdt.txt 5740F: Documentation/watchdog/hpwdt.txt
5741F: drivers/watchdog/hpwdt.c 5741F: drivers/watchdog/hpwdt.c
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 3eb58cb51e56..acb00b53a520 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -72,16 +72,16 @@ config SOFT_WATCHDOG
72 module will be called softdog. 72 module will be called softdog.
73 73
74config DA9052_WATCHDOG 74config DA9052_WATCHDOG
75 tristate "Dialog DA9052 Watchdog" 75 tristate "Dialog DA9052 Watchdog"
76 depends on PMIC_DA9052 76 depends on PMIC_DA9052
77 select WATCHDOG_CORE 77 select WATCHDOG_CORE
78 help 78 help
79 Support for the watchdog in the DA9052 PMIC. Watchdog trigger 79 Support for the watchdog in the DA9052 PMIC. Watchdog trigger
80 cause system reset. 80 cause system reset.
81 81
82 Say Y here to include support for the DA9052 watchdog. 82 Say Y here to include support for the DA9052 watchdog.
83 Alternatively say M to compile the driver as a module, 83 Alternatively say M to compile the driver as a module,
84 which will be called da9052_wdt. 84 which will be called da9052_wdt.
85 85
86config DA9055_WATCHDOG 86config DA9055_WATCHDOG
87 tristate "Dialog Semiconductor DA9055 Watchdog" 87 tristate "Dialog Semiconductor DA9055 Watchdog"
@@ -104,11 +104,11 @@ config DA9063_WATCHDOG
104 This driver can be built as a module. The module name is da9063_wdt. 104 This driver can be built as a module. The module name is da9063_wdt.
105 105
106config DA9062_WATCHDOG 106config DA9062_WATCHDOG
107 tristate "Dialog DA9062 Watchdog" 107 tristate "Dialog DA9062/61 Watchdog"
108 depends on MFD_DA9062 108 depends on MFD_DA9062
109 select WATCHDOG_CORE 109 select WATCHDOG_CORE
110 help 110 help
111 Support for the watchdog in the DA9062 PMIC. 111 Support for the watchdog in the DA9062 and DA9061 PMICs.
112 112
113 This driver can be built as a module. The module name is da9062_wdt. 113 This driver can be built as a module. The module name is da9062_wdt.
114 114
@@ -1008,8 +1008,8 @@ config IT87_WDT
1008 tristate "IT87 Watchdog Timer" 1008 tristate "IT87 Watchdog Timer"
1009 depends on X86 1009 depends on X86
1010 ---help--- 1010 ---help---
1011 This is the driver for the hardware watchdog on the ITE IT8702, 1011 This is the driver for the hardware watchdog on the ITE IT8620,
1012 IT8712, IT8716, IT8718, IT8720, IT8721, IT8726 and IT8728 1012 IT8702, IT8712, IT8716, IT8718, IT8720, IT8721, IT8726 and IT8728
1013 Super I/O chips. 1013 Super I/O chips.
1014 1014
1015 If the driver does not work, then make sure that the game port in 1015 If the driver does not work, then make sure that the game port in
@@ -1514,6 +1514,13 @@ config LANTIQ_WDT
1514 help 1514 help
1515 Hardware driver for the Lantiq SoC Watchdog Timer. 1515 Hardware driver for the Lantiq SoC Watchdog Timer.
1516 1516
1517config LOONGSON1_WDT
1518 tristate "Loongson1 SoC hardware watchdog"
1519 depends on MACH_LOONGSON32
1520 select WATCHDOG_CORE
1521 help
1522 Hardware driver for the Loongson1 SoC Watchdog Timer.
1523
1517config RALINK_WDT 1524config RALINK_WDT
1518 tristate "Ralink SoC watchdog" 1525 tristate "Ralink SoC watchdog"
1519 select WATCHDOG_CORE 1526 select WATCHDOG_CORE
@@ -1624,16 +1631,16 @@ config BOOKE_WDT_DEFAULT_TIMEOUT
1624 The value can be overridden by the wdt_period command-line parameter. 1631 The value can be overridden by the wdt_period command-line parameter.
1625 1632
1626config MEN_A21_WDT 1633config MEN_A21_WDT
1627 tristate "MEN A21 VME CPU Carrier Board Watchdog Timer" 1634 tristate "MEN A21 VME CPU Carrier Board Watchdog Timer"
1628 select WATCHDOG_CORE 1635 select WATCHDOG_CORE
1629 depends on GPIOLIB || COMPILE_TEST 1636 depends on GPIOLIB || COMPILE_TEST
1630 help 1637 help
1631 Watchdog driver for MEN A21 VMEbus CPU Carrier Boards. 1638 Watchdog driver for MEN A21 VMEbus CPU Carrier Boards.
1632 1639
1633 The driver can also be built as a module. If so, the module will be 1640 The driver can also be built as a module. If so, the module will be
1634 called mena21_wdt. 1641 called mena21_wdt.
1635 1642
1636 If unsure select N here. 1643 If unsure select N here.
1637 1644
1638# PPC64 Architecture 1645# PPC64 Architecture
1639 1646
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index caa9f4aa492a..0c3d35e3c334 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -163,6 +163,7 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
163obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o 163obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
164octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o 164octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
165obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o 165obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o
166obj-$(CONFIG_LOONGSON1_WDT) += loongson1_wdt.o
166obj-$(CONFIG_RALINK_WDT) += rt2880_wdt.o 167obj-$(CONFIG_RALINK_WDT) += rt2880_wdt.o
167obj-$(CONFIG_IMGPDC_WDT) += imgpdc_wdt.o 168obj-$(CONFIG_IMGPDC_WDT) += imgpdc_wdt.o
168obj-$(CONFIG_MT7621_WDT) += mt7621_wdt.o 169obj-$(CONFIG_MT7621_WDT) += mt7621_wdt.o
diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c
index 4dddd8298a22..c32c45bd8b09 100644
--- a/drivers/watchdog/bcm2835_wdt.c
+++ b/drivers/watchdog/bcm2835_wdt.c
@@ -55,6 +55,15 @@ struct bcm2835_wdt {
55static unsigned int heartbeat; 55static unsigned int heartbeat;
56static bool nowayout = WATCHDOG_NOWAYOUT; 56static bool nowayout = WATCHDOG_NOWAYOUT;
57 57
58static bool bcm2835_wdt_is_running(struct bcm2835_wdt *wdt)
59{
60 uint32_t cur;
61
62 cur = readl(wdt->base + PM_RSTC);
63
64 return !!(cur & PM_RSTC_WRCFG_FULL_RESET);
65}
66
58static int bcm2835_wdt_start(struct watchdog_device *wdog) 67static int bcm2835_wdt_start(struct watchdog_device *wdog)
59{ 68{
60 struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog); 69 struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog);
@@ -181,6 +190,17 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
181 watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev); 190 watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev);
182 watchdog_set_nowayout(&bcm2835_wdt_wdd, nowayout); 191 watchdog_set_nowayout(&bcm2835_wdt_wdd, nowayout);
183 bcm2835_wdt_wdd.parent = &pdev->dev; 192 bcm2835_wdt_wdd.parent = &pdev->dev;
193 if (bcm2835_wdt_is_running(wdt)) {
194 /*
195 * The currently active timeout value (set by the
196 * bootloader) may be different from the module
197 * heartbeat parameter or the value in device
198 * tree. But we just need to set WDOG_HW_RUNNING,
199 * because then the framework will "immediately" ping
200 * the device, updating the timeout.
201 */
202 set_bit(WDOG_HW_RUNNING, &bcm2835_wdt_wdd.status);
203 }
184 err = watchdog_register_device(&bcm2835_wdt_wdd); 204 err = watchdog_register_device(&bcm2835_wdt_wdd);
185 if (err) { 205 if (err) {
186 dev_err(dev, "Failed to register watchdog device"); 206 dev_err(dev, "Failed to register watchdog device");
diff --git a/drivers/watchdog/bcm7038_wdt.c b/drivers/watchdog/bcm7038_wdt.c
index e238df4d75a2..4814c00b32f6 100644
--- a/drivers/watchdog/bcm7038_wdt.c
+++ b/drivers/watchdog/bcm7038_wdt.c
@@ -216,6 +216,7 @@ static const struct of_device_id bcm7038_wdt_match[] = {
216 { .compatible = "brcm,bcm7038-wdt" }, 216 { .compatible = "brcm,bcm7038-wdt" },
217 {}, 217 {},
218}; 218};
219MODULE_DEVICE_TABLE(of, bcm7038_wdt_match);
219 220
220static struct platform_driver bcm7038_wdt_driver = { 221static struct platform_driver bcm7038_wdt_driver = {
221 .probe = bcm7038_wdt_probe, 222 .probe = bcm7038_wdt_probe,
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c
index 71ee07950e63..3d43775548e5 100644
--- a/drivers/watchdog/cpwd.c
+++ b/drivers/watchdog/cpwd.c
@@ -538,12 +538,9 @@ static int cpwd_probe(struct platform_device *op)
538 if (cpwd_device) 538 if (cpwd_device)
539 return -EINVAL; 539 return -EINVAL;
540 540
541 p = kzalloc(sizeof(*p), GFP_KERNEL); 541 p = devm_kzalloc(&op->dev, sizeof(*p), GFP_KERNEL);
542 err = -ENOMEM; 542 if (!p)
543 if (!p) { 543 return -ENOMEM;
544 pr_err("Unable to allocate struct cpwd\n");
545 goto out;
546 }
547 544
548 p->irq = op->archdata.irqs[0]; 545 p->irq = op->archdata.irqs[0];
549 546
@@ -553,12 +550,12 @@ static int cpwd_probe(struct platform_device *op)
553 4 * WD_TIMER_REGSZ, DRIVER_NAME); 550 4 * WD_TIMER_REGSZ, DRIVER_NAME);
554 if (!p->regs) { 551 if (!p->regs) {
555 pr_err("Unable to map registers\n"); 552 pr_err("Unable to map registers\n");
556 goto out_free; 553 return -ENOMEM;
557 } 554 }
558 555
559 options = of_find_node_by_path("/options"); 556 options = of_find_node_by_path("/options");
560 err = -ENODEV;
561 if (!options) { 557 if (!options) {
558 err = -ENODEV;
562 pr_err("Unable to find /options node\n"); 559 pr_err("Unable to find /options node\n");
563 goto out_iounmap; 560 goto out_iounmap;
564 } 561 }
@@ -620,10 +617,7 @@ static int cpwd_probe(struct platform_device *op)
620 617
621 platform_set_drvdata(op, p); 618 platform_set_drvdata(op, p);
622 cpwd_device = p; 619 cpwd_device = p;
623 err = 0; 620 return 0;
624
625out:
626 return err;
627 621
628out_unregister: 622out_unregister:
629 for (i--; i >= 0; i--) 623 for (i--; i >= 0; i--)
@@ -632,9 +626,7 @@ out_unregister:
632out_iounmap: 626out_iounmap:
633 of_iounmap(&op->resource[0], p->regs, 4 * WD_TIMER_REGSZ); 627 of_iounmap(&op->resource[0], p->regs, 4 * WD_TIMER_REGSZ);
634 628
635out_free: 629 return err;
636 kfree(p);
637 goto out;
638} 630}
639 631
640static int cpwd_remove(struct platform_device *op) 632static int cpwd_remove(struct platform_device *op)
@@ -659,7 +651,6 @@ static int cpwd_remove(struct platform_device *op)
659 free_irq(p->irq, p); 651 free_irq(p->irq, p);
660 652
661 of_iounmap(&op->resource[0], p->regs, 4 * WD_TIMER_REGSZ); 653 of_iounmap(&op->resource[0], p->regs, 4 * WD_TIMER_REGSZ);
662 kfree(p);
663 654
664 cpwd_device = NULL; 655 cpwd_device = NULL;
665 656
diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c
index 7386111220d5..a02cee6820a1 100644
--- a/drivers/watchdog/da9062_wdt.c
+++ b/drivers/watchdog/da9062_wdt.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * da9062_wdt.c - WDT device driver for DA9062 2 * Watchdog device driver for DA9062 and DA9061 PMICs
3 * Copyright (C) 2015 Dialog Semiconductor Ltd. 3 * Copyright (C) 2015 Dialog Semiconductor Ltd.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -188,6 +188,13 @@ static const struct watchdog_ops da9062_watchdog_ops = {
188 .set_timeout = da9062_wdt_set_timeout, 188 .set_timeout = da9062_wdt_set_timeout,
189}; 189};
190 190
191static const struct of_device_id da9062_compatible_id_table[] = {
192 { .compatible = "dlg,da9062-watchdog", },
193 { },
194};
195
196MODULE_DEVICE_TABLE(of, da9062_compatible_id_table);
197
191static int da9062_wdt_probe(struct platform_device *pdev) 198static int da9062_wdt_probe(struct platform_device *pdev)
192{ 199{
193 int ret; 200 int ret;
@@ -244,11 +251,12 @@ static struct platform_driver da9062_wdt_driver = {
244 .remove = da9062_wdt_remove, 251 .remove = da9062_wdt_remove,
245 .driver = { 252 .driver = {
246 .name = "da9062-watchdog", 253 .name = "da9062-watchdog",
254 .of_match_table = da9062_compatible_id_table,
247 }, 255 },
248}; 256};
249module_platform_driver(da9062_wdt_driver); 257module_platform_driver(da9062_wdt_driver);
250 258
251MODULE_AUTHOR("S Twiss <stwiss.opensource@diasemi.com>"); 259MODULE_AUTHOR("S Twiss <stwiss.opensource@diasemi.com>");
252MODULE_DESCRIPTION("WDT device driver for Dialog DA9062"); 260MODULE_DESCRIPTION("WDT device driver for Dialog DA9062 and DA9061");
253MODULE_LICENSE("GPL"); 261MODULE_LICENSE("GPL");
254MODULE_ALIAS("platform:da9062-watchdog"); 262MODULE_ALIAS("platform:da9062-watchdog");
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 17454ca653f4..0e731d797a2a 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -166,8 +166,12 @@ static int davinci_wdt_probe(struct platform_device *pdev)
166 return -ENOMEM; 166 return -ENOMEM;
167 167
168 davinci_wdt->clk = devm_clk_get(dev, NULL); 168 davinci_wdt->clk = devm_clk_get(dev, NULL);
169 if (WARN_ON(IS_ERR(davinci_wdt->clk))) 169
170 if (IS_ERR(davinci_wdt->clk)) {
171 if (PTR_ERR(davinci_wdt->clk) != -EPROBE_DEFER)
172 dev_err(&pdev->dev, "failed to get clock node\n");
170 return PTR_ERR(davinci_wdt->clk); 173 return PTR_ERR(davinci_wdt->clk);
174 }
171 175
172 clk_prepare_enable(davinci_wdt->clk); 176 clk_prepare_enable(davinci_wdt->clk);
173 177
diff --git a/drivers/watchdog/intel-mid_wdt.c b/drivers/watchdog/intel-mid_wdt.c
index db36d12e2b52..a4b729259b12 100644
--- a/drivers/watchdog/intel-mid_wdt.c
+++ b/drivers/watchdog/intel-mid_wdt.c
@@ -43,6 +43,7 @@ static inline int wdt_command(int sub, u32 *in, int inlen)
43 43
44static int wdt_start(struct watchdog_device *wd) 44static int wdt_start(struct watchdog_device *wd)
45{ 45{
46 struct device *dev = watchdog_get_drvdata(wd);
46 int ret, in_size; 47 int ret, in_size;
47 int timeout = wd->timeout; 48 int timeout = wd->timeout;
48 struct ipc_wd_start { 49 struct ipc_wd_start {
@@ -57,36 +58,32 @@ static int wdt_start(struct watchdog_device *wd)
57 in_size = DIV_ROUND_UP(sizeof(ipc_wd_start), 4); 58 in_size = DIV_ROUND_UP(sizeof(ipc_wd_start), 4);
58 59
59 ret = wdt_command(SCU_WATCHDOG_START, (u32 *)&ipc_wd_start, in_size); 60 ret = wdt_command(SCU_WATCHDOG_START, (u32 *)&ipc_wd_start, in_size);
60 if (ret) { 61 if (ret)
61 struct device *dev = watchdog_get_drvdata(wd);
62 dev_crit(dev, "error starting watchdog: %d\n", ret); 62 dev_crit(dev, "error starting watchdog: %d\n", ret);
63 }
64 63
65 return ret; 64 return ret;
66} 65}
67 66
68static int wdt_ping(struct watchdog_device *wd) 67static int wdt_ping(struct watchdog_device *wd)
69{ 68{
69 struct device *dev = watchdog_get_drvdata(wd);
70 int ret; 70 int ret;
71 71
72 ret = wdt_command(SCU_WATCHDOG_KEEPALIVE, NULL, 0); 72 ret = wdt_command(SCU_WATCHDOG_KEEPALIVE, NULL, 0);
73 if (ret) { 73 if (ret)
74 struct device *dev = watchdog_get_drvdata(wd); 74 dev_crit(dev, "Error executing keepalive: %d\n", ret);
75 dev_crit(dev, "Error executing keepalive: 0x%x\n", ret);
76 }
77 75
78 return ret; 76 return ret;
79} 77}
80 78
81static int wdt_stop(struct watchdog_device *wd) 79static int wdt_stop(struct watchdog_device *wd)
82{ 80{
81 struct device *dev = watchdog_get_drvdata(wd);
83 int ret; 82 int ret;
84 83
85 ret = wdt_command(SCU_WATCHDOG_STOP, NULL, 0); 84 ret = wdt_command(SCU_WATCHDOG_STOP, NULL, 0);
86 if (ret) { 85 if (ret)
87 struct device *dev = watchdog_get_drvdata(wd); 86 dev_crit(dev, "Error stopping watchdog: %d\n", ret);
88 dev_crit(dev, "Error stopping watchdog: 0x%x\n", ret);
89 }
90 87
91 return ret; 88 return ret;
92} 89}
@@ -151,6 +148,9 @@ static int mid_wdt_probe(struct platform_device *pdev)
151 return ret; 148 return ret;
152 } 149 }
153 150
151 /* Make sure the watchdog is not running */
152 wdt_stop(wdt_dev);
153
154 ret = watchdog_register_device(wdt_dev); 154 ret = watchdog_register_device(wdt_dev);
155 if (ret) { 155 if (ret) {
156 dev_err(&pdev->dev, "error registering watchdog device\n"); 156 dev_err(&pdev->dev, "error registering watchdog device\n");
diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c
index e54839b12650..b9878c41598f 100644
--- a/drivers/watchdog/it87_wdt.c
+++ b/drivers/watchdog/it87_wdt.c
@@ -12,7 +12,7 @@
12 * http://www.ite.com.tw/ 12 * http://www.ite.com.tw/
13 * 13 *
14 * Support of the watchdog timers, which are available on 14 * Support of the watchdog timers, which are available on
15 * IT8702, IT8712, IT8716, IT8718, IT8720, IT8721, IT8726, 15 * IT8620, IT8702, IT8712, IT8716, IT8718, IT8720, IT8721, IT8726,
16 * IT8728 and IT8783. 16 * IT8728 and IT8783.
17 * 17 *
18 * This program is free software; you can redistribute it and/or 18 * This program is free software; you can redistribute it and/or
@@ -78,6 +78,7 @@
78 78
79/* Chip Id numbers */ 79/* Chip Id numbers */
80#define NO_DEV_ID 0xffff 80#define NO_DEV_ID 0xffff
81#define IT8620_ID 0x8620
81#define IT8702_ID 0x8702 82#define IT8702_ID 0x8702
82#define IT8705_ID 0x8705 83#define IT8705_ID 0x8705
83#define IT8712_ID 0x8712 84#define IT8712_ID 0x8712
@@ -630,6 +631,7 @@ static int __init it87_wdt_init(void)
630 case IT8726_ID: 631 case IT8726_ID:
631 max_units = 65535; 632 max_units = 65535;
632 break; 633 break;
634 case IT8620_ID:
633 case IT8718_ID: 635 case IT8718_ID:
634 case IT8720_ID: 636 case IT8720_ID:
635 case IT8721_ID: 637 case IT8721_ID:
diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c
index c8d51ddb26d5..20627f22baf6 100644
--- a/drivers/watchdog/jz4740_wdt.c
+++ b/drivers/watchdog/jz4740_wdt.c
@@ -148,7 +148,7 @@ static const struct of_device_id jz4740_wdt_of_matches[] = {
148 { .compatible = "ingenic,jz4740-watchdog", }, 148 { .compatible = "ingenic,jz4740-watchdog", },
149 { /* sentinel */ } 149 { /* sentinel */ }
150}; 150};
151MODULE_DEVICE_TABLE(of, jz4740_wdt_of_matches) 151MODULE_DEVICE_TABLE(of, jz4740_wdt_of_matches);
152#endif 152#endif
153 153
154static int jz4740_wdt_probe(struct platform_device *pdev) 154static int jz4740_wdt_probe(struct platform_device *pdev)
diff --git a/drivers/watchdog/loongson1_wdt.c b/drivers/watchdog/loongson1_wdt.c
new file mode 100644
index 000000000000..3aee50c64a36
--- /dev/null
+++ b/drivers/watchdog/loongson1_wdt.c
@@ -0,0 +1,170 @@
1/*
2 * Copyright (c) 2016 Yang Ling <gnaygnil@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#include <linux/clk.h>
11#include <linux/module.h>
12#include <linux/platform_device.h>
13#include <linux/watchdog.h>
14#include <loongson1.h>
15
16#define DEFAULT_HEARTBEAT 30
17
18static bool nowayout = WATCHDOG_NOWAYOUT;
19module_param(nowayout, bool, 0444);
20
21static unsigned int heartbeat;
22module_param(heartbeat, uint, 0444);
23
24struct ls1x_wdt_drvdata {
25 void __iomem *base;
26 struct clk *clk;
27 unsigned long clk_rate;
28 struct watchdog_device wdt;
29};
30
31static int ls1x_wdt_ping(struct watchdog_device *wdt_dev)
32{
33 struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
34
35 writel(0x1, drvdata->base + WDT_SET);
36
37 return 0;
38}
39
40static int ls1x_wdt_set_timeout(struct watchdog_device *wdt_dev,
41 unsigned int timeout)
42{
43 struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
44 unsigned int max_hw_heartbeat = wdt_dev->max_hw_heartbeat_ms / 1000;
45 unsigned int counts;
46
47 wdt_dev->timeout = timeout;
48
49 counts = drvdata->clk_rate * min(timeout, max_hw_heartbeat);
50 writel(counts, drvdata->base + WDT_TIMER);
51
52 return 0;
53}
54
55static int ls1x_wdt_start(struct watchdog_device *wdt_dev)
56{
57 struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
58
59 writel(0x1, drvdata->base + WDT_EN);
60
61 return 0;
62}
63
64static int ls1x_wdt_stop(struct watchdog_device *wdt_dev)
65{
66 struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
67
68 writel(0x0, drvdata->base + WDT_EN);
69
70 return 0;
71}
72
73static const struct watchdog_info ls1x_wdt_info = {
74 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
75 .identity = "Loongson1 Watchdog",
76};
77
78static const struct watchdog_ops ls1x_wdt_ops = {
79 .owner = THIS_MODULE,
80 .start = ls1x_wdt_start,
81 .stop = ls1x_wdt_stop,
82 .ping = ls1x_wdt_ping,
83 .set_timeout = ls1x_wdt_set_timeout,
84};
85
86static int ls1x_wdt_probe(struct platform_device *pdev)
87{
88 struct ls1x_wdt_drvdata *drvdata;
89 struct watchdog_device *ls1x_wdt;
90 unsigned long clk_rate;
91 struct resource *res;
92 int err;
93
94 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
95 if (!drvdata)
96 return -ENOMEM;
97
98 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
99 drvdata->base = devm_ioremap_resource(&pdev->dev, res);
100 if (IS_ERR(drvdata->base))
101 return PTR_ERR(drvdata->base);
102
103 drvdata->clk = devm_clk_get(&pdev->dev, pdev->name);
104 if (IS_ERR(drvdata->clk))
105 return PTR_ERR(drvdata->clk);
106
107 err = clk_prepare_enable(drvdata->clk);
108 if (err) {
109 dev_err(&pdev->dev, "clk enable failed\n");
110 return err;
111 }
112
113 clk_rate = clk_get_rate(drvdata->clk);
114 if (!clk_rate) {
115 err = -EINVAL;
116 goto err0;
117 }
118 drvdata->clk_rate = clk_rate;
119
120 ls1x_wdt = &drvdata->wdt;
121 ls1x_wdt->info = &ls1x_wdt_info;
122 ls1x_wdt->ops = &ls1x_wdt_ops;
123 ls1x_wdt->timeout = DEFAULT_HEARTBEAT;
124 ls1x_wdt->min_timeout = 1;
125 ls1x_wdt->max_hw_heartbeat_ms = U32_MAX / clk_rate * 1000;
126 ls1x_wdt->parent = &pdev->dev;
127
128 watchdog_init_timeout(ls1x_wdt, heartbeat, &pdev->dev);
129 watchdog_set_nowayout(ls1x_wdt, nowayout);
130 watchdog_set_drvdata(ls1x_wdt, drvdata);
131
132 err = watchdog_register_device(&drvdata->wdt);
133 if (err) {
134 dev_err(&pdev->dev, "failed to register watchdog device\n");
135 goto err0;
136 }
137
138 platform_set_drvdata(pdev, drvdata);
139
140 dev_info(&pdev->dev, "Loongson1 Watchdog driver registered\n");
141
142 return 0;
143err0:
144 clk_disable_unprepare(drvdata->clk);
145 return err;
146}
147
148static int ls1x_wdt_remove(struct platform_device *pdev)
149{
150 struct ls1x_wdt_drvdata *drvdata = platform_get_drvdata(pdev);
151
152 watchdog_unregister_device(&drvdata->wdt);
153 clk_disable_unprepare(drvdata->clk);
154
155 return 0;
156}
157
158static struct platform_driver ls1x_wdt_driver = {
159 .probe = ls1x_wdt_probe,
160 .remove = ls1x_wdt_remove,
161 .driver = {
162 .name = "ls1x-wdt",
163 },
164};
165
166module_platform_driver(ls1x_wdt_driver);
167
168MODULE_AUTHOR("Yang Ling <gnaygnil@gmail.com>");
169MODULE_DESCRIPTION("Loongson1 Watchdog Driver");
170MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/max77620_wdt.c b/drivers/watchdog/max77620_wdt.c
index 48b84df2afda..68c41fa2be27 100644
--- a/drivers/watchdog/max77620_wdt.c
+++ b/drivers/watchdog/max77620_wdt.c
@@ -205,6 +205,7 @@ static struct platform_device_id max77620_wdt_devtype[] = {
205 { .name = "max77620-watchdog", }, 205 { .name = "max77620-watchdog", },
206 { }, 206 { },
207}; 207};
208MODULE_DEVICE_TABLE(platform, max77620_wdt_devtype);
208 209
209static struct platform_driver max77620_wdt_driver = { 210static struct platform_driver max77620_wdt_driver = {
210 .driver = { 211 .driver = {
diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c
index 79b35515904e..b29c6fde7473 100644
--- a/drivers/watchdog/mei_wdt.c
+++ b/drivers/watchdog/mei_wdt.c
@@ -389,6 +389,8 @@ static int mei_wdt_register(struct mei_wdt *wdt)
389 wdt->wdd.max_timeout = MEI_WDT_MAX_TIMEOUT; 389 wdt->wdd.max_timeout = MEI_WDT_MAX_TIMEOUT;
390 390
391 watchdog_set_drvdata(&wdt->wdd, wdt); 391 watchdog_set_drvdata(&wdt->wdd, wdt);
392 watchdog_stop_on_reboot(&wdt->wdd);
393
392 ret = watchdog_register_device(&wdt->wdd); 394 ret = watchdog_register_device(&wdt->wdd);
393 if (ret) { 395 if (ret) {
394 dev_err(dev, "unable to register watchdog device = %d.\n", ret); 396 dev_err(dev, "unable to register watchdog device = %d.\n", ret);
diff --git a/drivers/watchdog/meson_gxbb_wdt.c b/drivers/watchdog/meson_gxbb_wdt.c
index 44d180a2c5e5..45d47664a00a 100644
--- a/drivers/watchdog/meson_gxbb_wdt.c
+++ b/drivers/watchdog/meson_gxbb_wdt.c
@@ -264,7 +264,6 @@ static struct platform_driver meson_gxbb_wdt_driver = {
264 264
265module_platform_driver(meson_gxbb_wdt_driver); 265module_platform_driver(meson_gxbb_wdt_driver);
266 266
267MODULE_ALIAS("platform:meson-gxbb-wdt");
268MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); 267MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
269MODULE_DESCRIPTION("Amlogic Meson GXBB Watchdog timer driver"); 268MODULE_DESCRIPTION("Amlogic Meson GXBB Watchdog timer driver");
270MODULE_LICENSE("Dual BSD/GPL"); 269MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
index 5f2273aac37d..366e5c7e650b 100644
--- a/drivers/watchdog/mpc8xxx_wdt.c
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -23,7 +23,6 @@
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/timer.h> 25#include <linux/timer.h>
26#include <linux/miscdevice.h>
27#include <linux/of_address.h> 26#include <linux/of_address.h>
28#include <linux/of_platform.h> 27#include <linux/of_platform.h>
29#include <linux/module.h> 28#include <linux/module.h>
diff --git a/drivers/watchdog/octeon-wdt-main.c b/drivers/watchdog/octeon-wdt-main.c
index 529182d7d8a7..b5cdceb36cff 100644
--- a/drivers/watchdog/octeon-wdt-main.c
+++ b/drivers/watchdog/octeon-wdt-main.c
@@ -56,7 +56,6 @@
56 56
57#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 57#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
58 58
59#include <linux/miscdevice.h>
60#include <linux/interrupt.h> 59#include <linux/interrupt.h>
61#include <linux/watchdog.h> 60#include <linux/watchdog.h>
62#include <linux/cpumask.h> 61#include <linux/cpumask.h>
diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
index 5796b5d1b3f2..4f47b5e90956 100644
--- a/drivers/watchdog/qcom-wdt.c
+++ b/drivers/watchdog/qcom-wdt.c
@@ -209,7 +209,7 @@ static int qcom_wdt_probe(struct platform_device *pdev)
209 wdt->wdd.parent = &pdev->dev; 209 wdt->wdd.parent = &pdev->dev;
210 wdt->layout = regs; 210 wdt->layout = regs;
211 211
212 if (readl(wdt->base + WDT_STS) & 1) 212 if (readl(wdt_addr(wdt, WDT_STS)) & 1)
213 wdt->wdd.bootstatus = WDIOF_CARDRESET; 213 wdt->wdd.bootstatus = WDIOF_CARDRESET;
214 214
215 /* 215 /*