diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-24 14:27:45 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-24 14:27:45 -0500 |
commit | 3a77fa854477a12fc543a69d00ff8a42adefc586 (patch) | |
tree | 2902fe8b833cb64f9a5eb5e1276e9dcc6426c123 | |
parent | 01e0d6037de687fd3bb8b45ab1376e8322c1fcc9 (diff) | |
parent | 067161281f428aa7c6e153e06aab7b5fe1ed1e98 (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-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | drivers/watchdog/Kconfig | 49 | ||||
-rw-r--r-- | drivers/watchdog/Makefile | 1 | ||||
-rw-r--r-- | drivers/watchdog/bcm2835_wdt.c | 20 | ||||
-rw-r--r-- | drivers/watchdog/bcm7038_wdt.c | 1 | ||||
-rw-r--r-- | drivers/watchdog/cpwd.c | 23 | ||||
-rw-r--r-- | drivers/watchdog/da9062_wdt.c | 12 | ||||
-rw-r--r-- | drivers/watchdog/davinci_wdt.c | 6 | ||||
-rw-r--r-- | drivers/watchdog/intel-mid_wdt.c | 22 | ||||
-rw-r--r-- | drivers/watchdog/it87_wdt.c | 4 | ||||
-rw-r--r-- | drivers/watchdog/jz4740_wdt.c | 2 | ||||
-rw-r--r-- | drivers/watchdog/loongson1_wdt.c | 170 | ||||
-rw-r--r-- | drivers/watchdog/max77620_wdt.c | 1 | ||||
-rw-r--r-- | drivers/watchdog/mei_wdt.c | 2 | ||||
-rw-r--r-- | drivers/watchdog/meson_gxbb_wdt.c | 1 | ||||
-rw-r--r-- | drivers/watchdog/mpc8xxx_wdt.c | 1 | ||||
-rw-r--r-- | drivers/watchdog/octeon-wdt-main.c | 1 | ||||
-rw-r--r-- | drivers/watchdog/qcom-wdt.c | 2 |
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 | |||
5735 | F: drivers/media/dvb-frontends/hd29l2* | 5735 | F: drivers/media/dvb-frontends/hd29l2* |
5736 | 5736 | ||
5737 | HEWLETT PACKARD ENTERPRISE ILO NMI WATCHDOG DRIVER | 5737 | HEWLETT PACKARD ENTERPRISE ILO NMI WATCHDOG DRIVER |
5738 | M: Brian Boylston <brian.boylston@hpe.com> | 5738 | M: Jimmy Vance <jimmy.vance@hpe.com> |
5739 | S: Supported | 5739 | S: Supported |
5740 | F: Documentation/watchdog/hpwdt.txt | 5740 | F: Documentation/watchdog/hpwdt.txt |
5741 | F: drivers/watchdog/hpwdt.c | 5741 | F: 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 | ||
74 | config DA9052_WATCHDOG | 74 | config 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 | ||
86 | config DA9055_WATCHDOG | 86 | config 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 | ||
106 | config DA9062_WATCHDOG | 106 | config 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 | ||
1517 | config 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 | |||
1517 | config RALINK_WDT | 1524 | config 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 | ||
1626 | config MEN_A21_WDT | 1633 | config 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 | |||
163 | obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o | 163 | obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o |
164 | octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o | 164 | octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o |
165 | obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o | 165 | obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o |
166 | obj-$(CONFIG_LOONGSON1_WDT) += loongson1_wdt.o | ||
166 | obj-$(CONFIG_RALINK_WDT) += rt2880_wdt.o | 167 | obj-$(CONFIG_RALINK_WDT) += rt2880_wdt.o |
167 | obj-$(CONFIG_IMGPDC_WDT) += imgpdc_wdt.o | 168 | obj-$(CONFIG_IMGPDC_WDT) += imgpdc_wdt.o |
168 | obj-$(CONFIG_MT7621_WDT) += mt7621_wdt.o | 169 | obj-$(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 { | |||
55 | static unsigned int heartbeat; | 55 | static unsigned int heartbeat; |
56 | static bool nowayout = WATCHDOG_NOWAYOUT; | 56 | static bool nowayout = WATCHDOG_NOWAYOUT; |
57 | 57 | ||
58 | static 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 | |||
58 | static int bcm2835_wdt_start(struct watchdog_device *wdog) | 67 | static 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 | }; |
219 | MODULE_DEVICE_TABLE(of, bcm7038_wdt_match); | ||
219 | 220 | ||
220 | static struct platform_driver bcm7038_wdt_driver = { | 221 | static 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 | |||
625 | out: | ||
626 | return err; | ||
627 | 621 | ||
628 | out_unregister: | 622 | out_unregister: |
629 | for (i--; i >= 0; i--) | 623 | for (i--; i >= 0; i--) |
@@ -632,9 +626,7 @@ out_unregister: | |||
632 | out_iounmap: | 626 | out_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 | ||
635 | out_free: | 629 | return err; |
636 | kfree(p); | ||
637 | goto out; | ||
638 | } | 630 | } |
639 | 631 | ||
640 | static int cpwd_remove(struct platform_device *op) | 632 | static 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 | ||
191 | static const struct of_device_id da9062_compatible_id_table[] = { | ||
192 | { .compatible = "dlg,da9062-watchdog", }, | ||
193 | { }, | ||
194 | }; | ||
195 | |||
196 | MODULE_DEVICE_TABLE(of, da9062_compatible_id_table); | ||
197 | |||
191 | static int da9062_wdt_probe(struct platform_device *pdev) | 198 | static 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 | }; |
249 | module_platform_driver(da9062_wdt_driver); | 257 | module_platform_driver(da9062_wdt_driver); |
250 | 258 | ||
251 | MODULE_AUTHOR("S Twiss <stwiss.opensource@diasemi.com>"); | 259 | MODULE_AUTHOR("S Twiss <stwiss.opensource@diasemi.com>"); |
252 | MODULE_DESCRIPTION("WDT device driver for Dialog DA9062"); | 260 | MODULE_DESCRIPTION("WDT device driver for Dialog DA9062 and DA9061"); |
253 | MODULE_LICENSE("GPL"); | 261 | MODULE_LICENSE("GPL"); |
254 | MODULE_ALIAS("platform:da9062-watchdog"); | 262 | MODULE_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 | ||
44 | static int wdt_start(struct watchdog_device *wd) | 44 | static 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 | ||
68 | static int wdt_ping(struct watchdog_device *wd) | 67 | static 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 | ||
81 | static int wdt_stop(struct watchdog_device *wd) | 79 | static 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 | }; |
151 | MODULE_DEVICE_TABLE(of, jz4740_wdt_of_matches) | 151 | MODULE_DEVICE_TABLE(of, jz4740_wdt_of_matches); |
152 | #endif | 152 | #endif |
153 | 153 | ||
154 | static int jz4740_wdt_probe(struct platform_device *pdev) | 154 | static 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 | |||
18 | static bool nowayout = WATCHDOG_NOWAYOUT; | ||
19 | module_param(nowayout, bool, 0444); | ||
20 | |||
21 | static unsigned int heartbeat; | ||
22 | module_param(heartbeat, uint, 0444); | ||
23 | |||
24 | struct ls1x_wdt_drvdata { | ||
25 | void __iomem *base; | ||
26 | struct clk *clk; | ||
27 | unsigned long clk_rate; | ||
28 | struct watchdog_device wdt; | ||
29 | }; | ||
30 | |||
31 | static 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 | |||
40 | static 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 | |||
55 | static 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 | |||
64 | static 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 | |||
73 | static const struct watchdog_info ls1x_wdt_info = { | ||
74 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | ||
75 | .identity = "Loongson1 Watchdog", | ||
76 | }; | ||
77 | |||
78 | static 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 | |||
86 | static 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; | ||
143 | err0: | ||
144 | clk_disable_unprepare(drvdata->clk); | ||
145 | return err; | ||
146 | } | ||
147 | |||
148 | static 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 | |||
158 | static 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 | |||
166 | module_platform_driver(ls1x_wdt_driver); | ||
167 | |||
168 | MODULE_AUTHOR("Yang Ling <gnaygnil@gmail.com>"); | ||
169 | MODULE_DESCRIPTION("Loongson1 Watchdog Driver"); | ||
170 | MODULE_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 | }; |
208 | MODULE_DEVICE_TABLE(platform, max77620_wdt_devtype); | ||
208 | 209 | ||
209 | static struct platform_driver max77620_wdt_driver = { | 210 | static 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 | ||
265 | module_platform_driver(meson_gxbb_wdt_driver); | 265 | module_platform_driver(meson_gxbb_wdt_driver); |
266 | 266 | ||
267 | MODULE_ALIAS("platform:meson-gxbb-wdt"); | ||
268 | MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); | 267 | MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); |
269 | MODULE_DESCRIPTION("Amlogic Meson GXBB Watchdog timer driver"); | 268 | MODULE_DESCRIPTION("Amlogic Meson GXBB Watchdog timer driver"); |
270 | MODULE_LICENSE("Dual BSD/GPL"); | 269 | MODULE_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 | /* |