aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorJohn Crispin <blogic@openwrt.org>2012-04-12 15:21:56 -0400
committerRalf Baechle <ralf@linux-mips.org>2012-05-21 09:31:54 -0400
commitcdb8612147b7fba751e6fa193f32b09937a7e16b (patch)
treec395b2e3da6c0a8914adaf4bf82b38565442c89c /drivers/watchdog
parentceff2676b04943638c6f599ffe4e99efb89aa625 (diff)
watchdog: MIPS: lantiq: implement OF support and minor fixes
Add support for OF. We also apply the following small fixes * reduce boiler plate by using devm_request_and_ioremap * sane error path for the clock * move LTQ_RST_CAUSE_WDTRST to a soc specific header file * add a message to show that the driver loaded Signed-off-by: John Crispin <blogic@openwrt.org> Acked-by: Wim Van Sebroeck <wim@iguana.be> Cc: linux-watchdog@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3810/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/lantiq_wdt.c56
1 files changed, 25 insertions, 31 deletions
diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c
index a9593a3a32a0..2e74c3a8ee58 100644
--- a/drivers/watchdog/lantiq_wdt.c
+++ b/drivers/watchdog/lantiq_wdt.c
@@ -13,14 +13,15 @@
13#include <linux/fs.h> 13#include <linux/fs.h>
14#include <linux/miscdevice.h> 14#include <linux/miscdevice.h>
15#include <linux/watchdog.h> 15#include <linux/watchdog.h>
16#include <linux/platform_device.h> 16#include <linux/of_platform.h>
17#include <linux/uaccess.h> 17#include <linux/uaccess.h>
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/io.h> 19#include <linux/io.h>
20 20
21#include <lantiq.h> 21#include <lantiq_soc.h>
22 22
23/* Section 3.4 of the datasheet 23/*
24 * Section 3.4 of the datasheet
24 * The password sequence protects the WDT control register from unintended 25 * The password sequence protects the WDT control register from unintended
25 * write actions, which might cause malfunction of the WDT. 26 * write actions, which might cause malfunction of the WDT.
26 * 27 *
@@ -70,7 +71,8 @@ ltq_wdt_disable(void)
70{ 71{
71 /* write the first password magic */ 72 /* write the first password magic */
72 ltq_w32(LTQ_WDT_PW1, ltq_wdt_membase + LTQ_WDT_CR); 73 ltq_w32(LTQ_WDT_PW1, ltq_wdt_membase + LTQ_WDT_CR);
73 /* write the second password magic with no config 74 /*
75 * write the second password magic with no config
74 * this turns the watchdog off 76 * this turns the watchdog off
75 */ 77 */
76 ltq_w32(LTQ_WDT_PW2, ltq_wdt_membase + LTQ_WDT_CR); 78 ltq_w32(LTQ_WDT_PW2, ltq_wdt_membase + LTQ_WDT_CR);
@@ -184,7 +186,7 @@ static struct miscdevice ltq_wdt_miscdev = {
184 .fops = &ltq_wdt_fops, 186 .fops = &ltq_wdt_fops,
185}; 187};
186 188
187static int __init 189static int __devinit
188ltq_wdt_probe(struct platform_device *pdev) 190ltq_wdt_probe(struct platform_device *pdev)
189{ 191{
190 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 192 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -194,28 +196,27 @@ ltq_wdt_probe(struct platform_device *pdev)
194 dev_err(&pdev->dev, "cannot obtain I/O memory region"); 196 dev_err(&pdev->dev, "cannot obtain I/O memory region");
195 return -ENOENT; 197 return -ENOENT;
196 } 198 }
197 res = devm_request_mem_region(&pdev->dev, res->start, 199
198 resource_size(res), dev_name(&pdev->dev)); 200 ltq_wdt_membase = devm_request_and_ioremap(&pdev->dev, res);
199 if (!res) {
200 dev_err(&pdev->dev, "cannot request I/O memory region");
201 return -EBUSY;
202 }
203 ltq_wdt_membase = devm_ioremap_nocache(&pdev->dev, res->start,
204 resource_size(res));
205 if (!ltq_wdt_membase) { 201 if (!ltq_wdt_membase) {
206 dev_err(&pdev->dev, "cannot remap I/O memory region\n"); 202 dev_err(&pdev->dev, "cannot remap I/O memory region\n");
207 return -ENOMEM; 203 return -ENOMEM;
208 } 204 }
209 205
210 /* we do not need to enable the clock as it is always running */ 206 /* we do not need to enable the clock as it is always running */
211 clk = clk_get(&pdev->dev, "io"); 207 clk = clk_get_io();
212 WARN_ON(!clk); 208 if (IS_ERR(clk)) {
209 dev_err(&pdev->dev, "Failed to get clock\n");
210 return -ENOENT;
211 }
213 ltq_io_region_clk_rate = clk_get_rate(clk); 212 ltq_io_region_clk_rate = clk_get_rate(clk);
214 clk_put(clk); 213 clk_put(clk);
215 214
215 /* find out if the watchdog caused the last reboot */
216 if (ltq_reset_cause() == LTQ_RST_CAUSE_WDTRST) 216 if (ltq_reset_cause() == LTQ_RST_CAUSE_WDTRST)
217 ltq_wdt_bootstatus = WDIOF_CARDRESET; 217 ltq_wdt_bootstatus = WDIOF_CARDRESET;
218 218
219 dev_info(&pdev->dev, "Init done\n");
219 return misc_register(&ltq_wdt_miscdev); 220 return misc_register(&ltq_wdt_miscdev);
220} 221}
221 222
@@ -227,33 +228,26 @@ ltq_wdt_remove(struct platform_device *pdev)
227 return 0; 228 return 0;
228} 229}
229 230
231static const struct of_device_id ltq_wdt_match[] = {
232 { .compatible = "lantiq,wdt" },
233 {},
234};
235MODULE_DEVICE_TABLE(of, ltq_wdt_match);
230 236
231static struct platform_driver ltq_wdt_driver = { 237static struct platform_driver ltq_wdt_driver = {
238 .probe = ltq_wdt_probe,
232 .remove = __devexit_p(ltq_wdt_remove), 239 .remove = __devexit_p(ltq_wdt_remove),
233 .driver = { 240 .driver = {
234 .name = "ltq_wdt", 241 .name = "wdt",
235 .owner = THIS_MODULE, 242 .owner = THIS_MODULE,
243 .of_match_table = ltq_wdt_match,
236 }, 244 },
237}; 245};
238 246
239static int __init 247module_platform_driver(ltq_wdt_driver);
240init_ltq_wdt(void)
241{
242 return platform_driver_probe(&ltq_wdt_driver, ltq_wdt_probe);
243}
244
245static void __exit
246exit_ltq_wdt(void)
247{
248 return platform_driver_unregister(&ltq_wdt_driver);
249}
250
251module_init(init_ltq_wdt);
252module_exit(exit_ltq_wdt);
253 248
254module_param(nowayout, bool, 0); 249module_param(nowayout, bool, 0);
255MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); 250MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
256
257MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); 251MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
258MODULE_DESCRIPTION("Lantiq SoC Watchdog"); 252MODULE_DESCRIPTION("Lantiq SoC Watchdog");
259MODULE_LICENSE("GPL"); 253MODULE_LICENSE("GPL");