diff options
Diffstat (limited to 'drivers/watchdog/st_lpc_wdt.c')
-rw-r--r-- | drivers/watchdog/st_lpc_wdt.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/drivers/watchdog/st_lpc_wdt.c b/drivers/watchdog/st_lpc_wdt.c index 196fb4b72c5d..9a5ed95c3403 100644 --- a/drivers/watchdog/st_lpc_wdt.c +++ b/drivers/watchdog/st_lpc_wdt.c @@ -142,10 +142,16 @@ static struct watchdog_device st_wdog_dev = { .ops = &st_wdog_ops, }; +static void st_clk_disable_unprepare(void *data) +{ + clk_disable_unprepare(data); +} + static int st_wdog_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; const struct of_device_id *match; - struct device_node *np = pdev->dev.of_node; + struct device_node *np = dev->of_node; struct st_wdog *st_wdog; struct regmap *regmap; struct clk *clk; @@ -155,7 +161,7 @@ static int st_wdog_probe(struct platform_device *pdev) ret = of_property_read_u32(np, "st,lpc-mode", &mode); if (ret) { - dev_err(&pdev->dev, "An LPC mode must be provided\n"); + dev_err(dev, "An LPC mode must be provided\n"); return -EINVAL; } @@ -163,13 +169,13 @@ static int st_wdog_probe(struct platform_device *pdev) if (mode != ST_LPC_MODE_WDT) return -ENODEV; - st_wdog = devm_kzalloc(&pdev->dev, sizeof(*st_wdog), GFP_KERNEL); + st_wdog = devm_kzalloc(dev, sizeof(*st_wdog), GFP_KERNEL); if (!st_wdog) return -ENOMEM; - match = of_match_device(st_wdog_match, &pdev->dev); + match = of_match_device(st_wdog_match, dev); if (!match) { - dev_err(&pdev->dev, "Couldn't match device\n"); + dev_err(dev, "Couldn't match device\n"); return -ENODEV; } st_wdog->syscfg = (struct st_wdog_syscfg *)match->data; @@ -180,17 +186,17 @@ static int st_wdog_probe(struct platform_device *pdev) regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); if (IS_ERR(regmap)) { - dev_err(&pdev->dev, "No syscfg phandle specified\n"); + dev_err(dev, "No syscfg phandle specified\n"); return PTR_ERR(regmap); } - clk = devm_clk_get(&pdev->dev, NULL); + clk = devm_clk_get(dev, NULL); if (IS_ERR(clk)) { - dev_err(&pdev->dev, "Unable to request clock\n"); + dev_err(dev, "Unable to request clock\n"); return PTR_ERR(clk); } - st_wdog->dev = &pdev->dev; + st_wdog->dev = dev; st_wdog->base = base; st_wdog->clk = clk; st_wdog->regmap = regmap; @@ -198,39 +204,40 @@ static int st_wdog_probe(struct platform_device *pdev) st_wdog->clkrate = clk_get_rate(st_wdog->clk); if (!st_wdog->clkrate) { - dev_err(&pdev->dev, "Unable to fetch clock rate\n"); + dev_err(dev, "Unable to fetch clock rate\n"); return -EINVAL; } st_wdog_dev.max_timeout = 0xFFFFFFFF / st_wdog->clkrate; - st_wdog_dev.parent = &pdev->dev; + st_wdog_dev.parent = dev; ret = clk_prepare_enable(clk); if (ret) { - dev_err(&pdev->dev, "Unable to enable clock\n"); + dev_err(dev, "Unable to enable clock\n"); return ret; } + ret = devm_add_action_or_reset(dev, st_clk_disable_unprepare, clk); + if (ret) + return ret; watchdog_set_drvdata(&st_wdog_dev, st_wdog); watchdog_set_nowayout(&st_wdog_dev, WATCHDOG_NOWAYOUT); /* Init Watchdog timeout with value in DT */ - ret = watchdog_init_timeout(&st_wdog_dev, 0, &pdev->dev); + ret = watchdog_init_timeout(&st_wdog_dev, 0, dev); if (ret) { - dev_err(&pdev->dev, "Unable to initialise watchdog timeout\n"); - clk_disable_unprepare(clk); + dev_err(dev, "Unable to initialise watchdog timeout\n"); return ret; } - ret = watchdog_register_device(&st_wdog_dev); + ret = devm_watchdog_register_device(dev, &st_wdog_dev); if (ret) { - dev_err(&pdev->dev, "Unable to register watchdog\n"); - clk_disable_unprepare(clk); + dev_err(dev, "Unable to register watchdog\n"); return ret; } st_wdog_setup(st_wdog, true); - dev_info(&pdev->dev, "LPC Watchdog driver registered, reset type is %s", + dev_info(dev, "LPC Watchdog driver registered, reset type is %s", st_wdog->warm_reset ? "warm" : "cold"); return ret; @@ -241,8 +248,6 @@ static int st_wdog_remove(struct platform_device *pdev) struct st_wdog *st_wdog = watchdog_get_drvdata(&st_wdog_dev); st_wdog_setup(st_wdog, false); - watchdog_unregister_device(&st_wdog_dev); - clk_disable_unprepare(st_wdog->clk); return 0; } |