Commit 9d6b4efc16b3e8e7414fcd6aab8fec42756ba920
Committed by
Wim Van Sebroeck
1 parent
d2a0015174
watchdog: xilinx: Add clock support
Add support for the clock. Currently we enable at probe and relinquish at remove. Reviewed-by: Guenter Roeck <linux@roeck-us.net> Acked-by: Sören Brinkmann <soren.brinkmann@xilinx.com> Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com> Acked-by: Rob Herring <robh@kernel.org> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Showing 2 changed files with 26 additions and 2 deletions Side-by-side Diff
Documentation/devicetree/bindings/watchdog/of-xilinx-wdt.txt
... | ... | @@ -7,6 +7,8 @@ |
7 | 7 | - reg : Physical base address and size |
8 | 8 | |
9 | 9 | Optional properties: |
10 | +- clocks : Input clock specifier. Refer to common clock | |
11 | + bindings. | |
10 | 12 | - clock-frequency : Frequency of clock in Hz |
11 | 13 | - xlnx,wdt-enable-once : 0 - Watchdog can be restarted |
12 | 14 | 1 - Watchdog can be enabled just once |
... | ... | @@ -17,6 +19,7 @@ |
17 | 19 | axi-timebase-wdt@40100000 { |
18 | 20 | clock-frequency = <50000000>; |
19 | 21 | compatible = "xlnx,xps-timebase-wdt-1.00.a"; |
22 | + clocks = <&clkc 15>; | |
20 | 23 | reg = <0x40100000 0x10000>; |
21 | 24 | xlnx,wdt-enable-once = <0x0>; |
22 | 25 | xlnx,wdt-interval = <0x1b>; |
drivers/watchdog/of_xilinx_wdt.c
... | ... | @@ -10,6 +10,7 @@ |
10 | 10 | * 2 of the License, or (at your option) any later version. |
11 | 11 | */ |
12 | 12 | |
13 | +#include <linux/clk.h> | |
13 | 14 | #include <linux/err.h> |
14 | 15 | #include <linux/module.h> |
15 | 16 | #include <linux/types.h> |
... | ... | @@ -45,6 +46,7 @@ |
45 | 46 | u32 wdt_interval; |
46 | 47 | spinlock_t spinlock; |
47 | 48 | struct watchdog_device xilinx_wdt_wdd; |
49 | + struct clk *clk; | |
48 | 50 | }; |
49 | 51 | |
50 | 52 | static int xilinx_wdt_start(struct watchdog_device *wdd) |
51 | 53 | |
52 | 54 | |
... | ... | @@ -195,16 +197,30 @@ |
195 | 197 | spin_lock_init(&xdev->spinlock); |
196 | 198 | watchdog_set_drvdata(xilinx_wdt_wdd, xdev); |
197 | 199 | |
200 | + xdev->clk = devm_clk_get(&pdev->dev, NULL); | |
201 | + if (IS_ERR(xdev->clk)) { | |
202 | + if (PTR_ERR(xdev->clk) == -ENOENT) | |
203 | + xdev->clk = NULL; | |
204 | + else | |
205 | + return PTR_ERR(xdev->clk); | |
206 | + } | |
207 | + | |
208 | + rc = clk_prepare_enable(xdev->clk); | |
209 | + if (rc) { | |
210 | + dev_err(&pdev->dev, "unable to enable clock\n"); | |
211 | + return rc; | |
212 | + } | |
213 | + | |
198 | 214 | rc = xwdt_selftest(xdev); |
199 | 215 | if (rc == XWT_TIMER_FAILED) { |
200 | 216 | dev_err(&pdev->dev, "SelfTest routine error\n"); |
201 | - return rc; | |
217 | + goto err_clk_disable; | |
202 | 218 | } |
203 | 219 | |
204 | 220 | rc = watchdog_register_device(xilinx_wdt_wdd); |
205 | 221 | if (rc) { |
206 | 222 | dev_err(&pdev->dev, "Cannot register watchdog (err=%d)\n", rc); |
207 | - return rc; | |
223 | + goto err_clk_disable; | |
208 | 224 | } |
209 | 225 | |
210 | 226 | dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds\n", |
... | ... | @@ -213,6 +229,10 @@ |
213 | 229 | platform_set_drvdata(pdev, xdev); |
214 | 230 | |
215 | 231 | return 0; |
232 | +err_clk_disable: | |
233 | + clk_disable_unprepare(xdev->clk); | |
234 | + | |
235 | + return rc; | |
216 | 236 | } |
217 | 237 | |
218 | 238 | static int xwdt_remove(struct platform_device *pdev) |
... | ... | @@ -220,6 +240,7 @@ |
220 | 240 | struct xwdt_device *xdev = platform_get_drvdata(pdev); |
221 | 241 | |
222 | 242 | watchdog_unregister_device(&xdev->xilinx_wdt_wdd); |
243 | + clk_disable_unprepare(xdev->clk); | |
223 | 244 | |
224 | 245 | return 0; |
225 | 246 | } |