Root/
1 | /* |
2 | * Copyright (C) Nokia Corporation |
3 | * |
4 | * Written by Timo Kokkonen <timo.t.kokkonen at nokia.com> |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ |
20 | |
21 | #include <linux/module.h> |
22 | #include <linux/types.h> |
23 | #include <linux/slab.h> |
24 | #include <linux/kernel.h> |
25 | #include <linux/watchdog.h> |
26 | #include <linux/platform_device.h> |
27 | #include <linux/i2c/twl.h> |
28 | |
29 | #define TWL4030_WATCHDOG_CFG_REG_OFFS 0x3 |
30 | |
31 | static bool nowayout = WATCHDOG_NOWAYOUT; |
32 | module_param(nowayout, bool, 0); |
33 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " |
34 | "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
35 | |
36 | static int twl4030_wdt_write(unsigned char val) |
37 | { |
38 | return twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, val, |
39 | TWL4030_WATCHDOG_CFG_REG_OFFS); |
40 | } |
41 | |
42 | static int twl4030_wdt_start(struct watchdog_device *wdt) |
43 | { |
44 | return twl4030_wdt_write(wdt->timeout + 1); |
45 | } |
46 | |
47 | static int twl4030_wdt_stop(struct watchdog_device *wdt) |
48 | { |
49 | return twl4030_wdt_write(0); |
50 | } |
51 | |
52 | static int twl4030_wdt_set_timeout(struct watchdog_device *wdt, |
53 | unsigned int timeout) |
54 | { |
55 | wdt->timeout = timeout; |
56 | return 0; |
57 | } |
58 | |
59 | static const struct watchdog_info twl4030_wdt_info = { |
60 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
61 | .identity = "TWL4030 Watchdog", |
62 | }; |
63 | |
64 | static const struct watchdog_ops twl4030_wdt_ops = { |
65 | .owner = THIS_MODULE, |
66 | .start = twl4030_wdt_start, |
67 | .stop = twl4030_wdt_stop, |
68 | .set_timeout = twl4030_wdt_set_timeout, |
69 | }; |
70 | |
71 | static int twl4030_wdt_probe(struct platform_device *pdev) |
72 | { |
73 | int ret = 0; |
74 | struct watchdog_device *wdt; |
75 | |
76 | wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); |
77 | if (!wdt) |
78 | return -ENOMEM; |
79 | |
80 | wdt->info = &twl4030_wdt_info; |
81 | wdt->ops = &twl4030_wdt_ops; |
82 | wdt->status = 0; |
83 | wdt->timeout = 30; |
84 | wdt->min_timeout = 1; |
85 | wdt->max_timeout = 30; |
86 | |
87 | watchdog_set_nowayout(wdt, nowayout); |
88 | platform_set_drvdata(pdev, wdt); |
89 | |
90 | twl4030_wdt_stop(wdt); |
91 | |
92 | ret = watchdog_register_device(wdt); |
93 | if (ret) { |
94 | platform_set_drvdata(pdev, NULL); |
95 | return ret; |
96 | } |
97 | |
98 | return 0; |
99 | } |
100 | |
101 | static int twl4030_wdt_remove(struct platform_device *pdev) |
102 | { |
103 | struct watchdog_device *wdt = platform_get_drvdata(pdev); |
104 | |
105 | watchdog_unregister_device(wdt); |
106 | platform_set_drvdata(pdev, NULL); |
107 | |
108 | return 0; |
109 | } |
110 | |
111 | #ifdef CONFIG_PM |
112 | static int twl4030_wdt_suspend(struct platform_device *pdev, pm_message_t state) |
113 | { |
114 | struct watchdog_device *wdt = platform_get_drvdata(pdev); |
115 | if (watchdog_active(wdt)) |
116 | return twl4030_wdt_stop(wdt); |
117 | |
118 | return 0; |
119 | } |
120 | |
121 | static int twl4030_wdt_resume(struct platform_device *pdev) |
122 | { |
123 | struct watchdog_device *wdt = platform_get_drvdata(pdev); |
124 | if (watchdog_active(wdt)) |
125 | return twl4030_wdt_start(wdt); |
126 | |
127 | return 0; |
128 | } |
129 | #else |
130 | #define twl4030_wdt_suspend NULL |
131 | #define twl4030_wdt_resume NULL |
132 | #endif |
133 | |
134 | static const struct of_device_id twl_wdt_of_match[] = { |
135 | { .compatible = "ti,twl4030-wdt", }, |
136 | { }, |
137 | }; |
138 | MODULE_DEVICE_TABLE(of, twl_wdt_of_match); |
139 | |
140 | static struct platform_driver twl4030_wdt_driver = { |
141 | .probe = twl4030_wdt_probe, |
142 | .remove = twl4030_wdt_remove, |
143 | .suspend = twl4030_wdt_suspend, |
144 | .resume = twl4030_wdt_resume, |
145 | .driver = { |
146 | .owner = THIS_MODULE, |
147 | .name = "twl4030_wdt", |
148 | .of_match_table = twl_wdt_of_match, |
149 | }, |
150 | }; |
151 | |
152 | module_platform_driver(twl4030_wdt_driver); |
153 | |
154 | MODULE_AUTHOR("Nokia Corporation"); |
155 | MODULE_LICENSE("GPL"); |
156 | MODULE_ALIAS("platform:twl4030_wdt"); |
157 | |
158 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9