diff options
author | Ezequiel Garcia <ezequiel.garcia@free-electrons.com> | 2014-02-10 18:00:20 -0500 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2014-02-21 22:42:25 -0500 |
commit | bb02c662d641d51ea8c3ae9c828e89fbcfe04ba7 (patch) | |
tree | b8c1a4dac2d02eed023d671b85ecd06396b14ae3 | |
parent | d86e9af6336c0ad586a5dbd70064253d40bbb5ff (diff) |
watchdog: orion: Add clock error handling
This commit adds a check for clk_prepare_enable success and introduces
an error path to disable the clock properly.
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Tested-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Acked-by: Wim Van Sebroeck <wim@iguana.be>
Tested-By: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r-- | drivers/watchdog/orion_wdt.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c index f7722a424676..7f19fa3b543d 100644 --- a/drivers/watchdog/orion_wdt.c +++ b/drivers/watchdog/orion_wdt.c | |||
@@ -151,17 +151,24 @@ static int orion_wdt_probe(struct platform_device *pdev) | |||
151 | clk = devm_clk_get(&pdev->dev, NULL); | 151 | clk = devm_clk_get(&pdev->dev, NULL); |
152 | if (IS_ERR(clk)) { | 152 | if (IS_ERR(clk)) { |
153 | dev_err(&pdev->dev, "Orion Watchdog missing clock\n"); | 153 | dev_err(&pdev->dev, "Orion Watchdog missing clock\n"); |
154 | return -ENODEV; | 154 | return PTR_ERR(clk); |
155 | } | 155 | } |
156 | clk_prepare_enable(clk); | 156 | ret = clk_prepare_enable(clk); |
157 | if (ret) | ||
158 | return ret; | ||
157 | wdt_tclk = clk_get_rate(clk); | 159 | wdt_tclk = clk_get_rate(clk); |
158 | 160 | ||
159 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 161 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
160 | if (!res) | 162 | if (!res) { |
161 | return -ENODEV; | 163 | ret = -ENODEV; |
164 | goto disable_clk; | ||
165 | } | ||
166 | |||
162 | wdt_reg = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | 167 | wdt_reg = devm_ioremap(&pdev->dev, res->start, resource_size(res)); |
163 | if (!wdt_reg) | 168 | if (!wdt_reg) { |
164 | return -ENOMEM; | 169 | ret = -ENOMEM; |
170 | goto disable_clk; | ||
171 | } | ||
165 | 172 | ||
166 | wdt_max_duration = WDT_MAX_CYCLE_COUNT / wdt_tclk; | 173 | wdt_max_duration = WDT_MAX_CYCLE_COUNT / wdt_tclk; |
167 | 174 | ||
@@ -171,14 +178,16 @@ static int orion_wdt_probe(struct platform_device *pdev) | |||
171 | 178 | ||
172 | watchdog_set_nowayout(&orion_wdt, nowayout); | 179 | watchdog_set_nowayout(&orion_wdt, nowayout); |
173 | ret = watchdog_register_device(&orion_wdt); | 180 | ret = watchdog_register_device(&orion_wdt); |
174 | if (ret) { | 181 | if (ret) |
175 | clk_disable_unprepare(clk); | 182 | goto disable_clk; |
176 | return ret; | ||
177 | } | ||
178 | 183 | ||
179 | pr_info("Initial timeout %d sec%s\n", | 184 | pr_info("Initial timeout %d sec%s\n", |
180 | orion_wdt.timeout, nowayout ? ", nowayout" : ""); | 185 | orion_wdt.timeout, nowayout ? ", nowayout" : ""); |
181 | return 0; | 186 | return 0; |
187 | |||
188 | disable_clk: | ||
189 | clk_disable_unprepare(clk); | ||
190 | return ret; | ||
182 | } | 191 | } |
183 | 192 | ||
184 | static int orion_wdt_remove(struct platform_device *pdev) | 193 | static int orion_wdt_remove(struct platform_device *pdev) |