diff options
author | John Crispin <blogic@openwrt.org> | 2012-04-12 15:21:56 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2012-05-21 09:31:54 -0400 |
commit | cdb8612147b7fba751e6fa193f32b09937a7e16b (patch) | |
tree | c395b2e3da6c0a8914adaf4bf82b38565442c89c /drivers/watchdog | |
parent | ceff2676b04943638c6f599ffe4e99efb89aa625 (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.c | 56 |
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 = <q_wdt_fops, | 186 | .fops = <q_wdt_fops, |
185 | }; | 187 | }; |
186 | 188 | ||
187 | static int __init | 189 | static int __devinit |
188 | ltq_wdt_probe(struct platform_device *pdev) | 190 | ltq_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(<q_wdt_miscdev); | 220 | return misc_register(<q_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 | ||
231 | static const struct of_device_id ltq_wdt_match[] = { | ||
232 | { .compatible = "lantiq,wdt" }, | ||
233 | {}, | ||
234 | }; | ||
235 | MODULE_DEVICE_TABLE(of, ltq_wdt_match); | ||
230 | 236 | ||
231 | static struct platform_driver ltq_wdt_driver = { | 237 | static 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 | ||
239 | static int __init | 247 | module_platform_driver(ltq_wdt_driver); |
240 | init_ltq_wdt(void) | ||
241 | { | ||
242 | return platform_driver_probe(<q_wdt_driver, ltq_wdt_probe); | ||
243 | } | ||
244 | |||
245 | static void __exit | ||
246 | exit_ltq_wdt(void) | ||
247 | { | ||
248 | return platform_driver_unregister(<q_wdt_driver); | ||
249 | } | ||
250 | |||
251 | module_init(init_ltq_wdt); | ||
252 | module_exit(exit_ltq_wdt); | ||
253 | 248 | ||
254 | module_param(nowayout, bool, 0); | 249 | module_param(nowayout, bool, 0); |
255 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); | 250 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); |
256 | |||
257 | MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); | 251 | MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); |
258 | MODULE_DESCRIPTION("Lantiq SoC Watchdog"); | 252 | MODULE_DESCRIPTION("Lantiq SoC Watchdog"); |
259 | MODULE_LICENSE("GPL"); | 253 | MODULE_LICENSE("GPL"); |