| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * watchdog driver for ZTE's zx2967 family |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2017 ZTE Ltd. |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Author: Baoyou Xie <baoyou.xie@linaro.org> |
|---|
| 7 | | - * |
|---|
| 8 | | - * License terms: GNU General Public License (GPL) version 2 |
|---|
| 9 | 8 | */ |
|---|
| 10 | 9 | |
|---|
| 11 | 10 | #include <linux/clk.h> |
|---|
| .. | .. |
|---|
| 188 | 187 | of_node_put(out_args.np); |
|---|
| 189 | 188 | } |
|---|
| 190 | 189 | |
|---|
| 190 | +static void zx2967_clk_disable_unprepare(void *data) |
|---|
| 191 | +{ |
|---|
| 192 | + clk_disable_unprepare(data); |
|---|
| 193 | +} |
|---|
| 194 | + |
|---|
| 191 | 195 | static int zx2967_wdt_probe(struct platform_device *pdev) |
|---|
| 192 | 196 | { |
|---|
| 193 | 197 | struct device *dev = &pdev->dev; |
|---|
| 194 | 198 | struct zx2967_wdt *wdt; |
|---|
| 195 | | - struct resource *base; |
|---|
| 196 | 199 | int ret; |
|---|
| 197 | 200 | struct reset_control *rstc; |
|---|
| 198 | 201 | |
|---|
| .. | .. |
|---|
| 207 | 210 | wdt->wdt_device.timeout = ZX2967_WDT_DEFAULT_TIMEOUT; |
|---|
| 208 | 211 | wdt->wdt_device.max_timeout = ZX2967_WDT_MAX_TIMEOUT; |
|---|
| 209 | 212 | wdt->wdt_device.min_timeout = ZX2967_WDT_MIN_TIMEOUT; |
|---|
| 210 | | - wdt->wdt_device.parent = &pdev->dev; |
|---|
| 213 | + wdt->wdt_device.parent = dev; |
|---|
| 211 | 214 | |
|---|
| 212 | | - base = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 213 | | - wdt->reg_base = devm_ioremap_resource(dev, base); |
|---|
| 215 | + wdt->reg_base = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 214 | 216 | if (IS_ERR(wdt->reg_base)) |
|---|
| 215 | 217 | return PTR_ERR(wdt->reg_base); |
|---|
| 216 | 218 | |
|---|
| .. | .. |
|---|
| 227 | 229 | dev_err(dev, "failed to enable clock\n"); |
|---|
| 228 | 230 | return ret; |
|---|
| 229 | 231 | } |
|---|
| 232 | + ret = devm_add_action_or_reset(dev, zx2967_clk_disable_unprepare, |
|---|
| 233 | + wdt->clock); |
|---|
| 234 | + if (ret) |
|---|
| 235 | + return ret; |
|---|
| 230 | 236 | clk_set_rate(wdt->clock, ZX2967_WDT_CLK_FREQ); |
|---|
| 231 | 237 | |
|---|
| 232 | 238 | rstc = devm_reset_control_get_exclusive(dev, NULL); |
|---|
| 233 | 239 | if (IS_ERR(rstc)) { |
|---|
| 234 | 240 | dev_err(dev, "failed to get rstc"); |
|---|
| 235 | | - ret = PTR_ERR(rstc); |
|---|
| 236 | | - goto err; |
|---|
| 241 | + return PTR_ERR(rstc); |
|---|
| 237 | 242 | } |
|---|
| 238 | 243 | |
|---|
| 239 | 244 | reset_control_assert(rstc); |
|---|
| .. | .. |
|---|
| 244 | 249 | ZX2967_WDT_DEFAULT_TIMEOUT, dev); |
|---|
| 245 | 250 | watchdog_set_nowayout(&wdt->wdt_device, WATCHDOG_NOWAYOUT); |
|---|
| 246 | 251 | |
|---|
| 247 | | - ret = watchdog_register_device(&wdt->wdt_device); |
|---|
| 252 | + ret = devm_watchdog_register_device(dev, &wdt->wdt_device); |
|---|
| 248 | 253 | if (ret) |
|---|
| 249 | | - goto err; |
|---|
| 254 | + return ret; |
|---|
| 250 | 255 | |
|---|
| 251 | 256 | dev_info(dev, "watchdog enabled (timeout=%d sec, nowayout=%d)", |
|---|
| 252 | 257 | wdt->wdt_device.timeout, WATCHDOG_NOWAYOUT); |
|---|
| 253 | | - |
|---|
| 254 | | - return 0; |
|---|
| 255 | | - |
|---|
| 256 | | -err: |
|---|
| 257 | | - clk_disable_unprepare(wdt->clock); |
|---|
| 258 | | - return ret; |
|---|
| 259 | | -} |
|---|
| 260 | | - |
|---|
| 261 | | -static int zx2967_wdt_remove(struct platform_device *pdev) |
|---|
| 262 | | -{ |
|---|
| 263 | | - struct zx2967_wdt *wdt = platform_get_drvdata(pdev); |
|---|
| 264 | | - |
|---|
| 265 | | - watchdog_unregister_device(&wdt->wdt_device); |
|---|
| 266 | | - clk_disable_unprepare(wdt->clock); |
|---|
| 267 | 258 | |
|---|
| 268 | 259 | return 0; |
|---|
| 269 | 260 | } |
|---|
| .. | .. |
|---|
| 276 | 267 | |
|---|
| 277 | 268 | static struct platform_driver zx2967_wdt_driver = { |
|---|
| 278 | 269 | .probe = zx2967_wdt_probe, |
|---|
| 279 | | - .remove = zx2967_wdt_remove, |
|---|
| 280 | 270 | .driver = { |
|---|
| 281 | 271 | .name = "zx2967-wdt", |
|---|
| 282 | 272 | .of_match_table = of_match_ptr(zx2967_wdt_match), |
|---|