summaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorWolfram Sang <wsa+renesas@sang-engineering.com>2017-07-26 17:54:37 -0400
committerWim Van Sebroeck <wim@iguana.be>2017-09-09 15:11:52 -0400
commit3be42941dd9df9b7c5062fc98c416a15bf4bbc0f (patch)
tree808da097e4025ebdd960e359d7f75426edb29d40 /drivers/watchdog
parent012c04601f9dc6a268ebff87a890b339af6d25bf (diff)
watchdog: renesas_wdt: consistently use RuntimePM for clock management
On Renesas R-Car archs, RuntimePM does all the clock handling. So, use it consistently to enable/disable the clocks. Also make sure that clocks are really enabled around clk_get_rate(). clk_summary looks proper now: clock enable_cnt prepare_cnt rate ... Before this commit: At boot: rwdt 1 1 32768 0 0 WDT running: rwdt 2 2 32768 0 0 After this commit: At boot: rwdt 0 1 32768 0 0 WDT running rwdt 1 1 32768 0 0 Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/renesas_wdt.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c
index e3f204bb8802..a03997b418ba 100644
--- a/drivers/watchdog/renesas_wdt.c
+++ b/drivers/watchdog/renesas_wdt.c
@@ -76,7 +76,7 @@ static int rwdt_start(struct watchdog_device *wdev)
76{ 76{
77 struct rwdt_priv *priv = watchdog_get_drvdata(wdev); 77 struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
78 78
79 clk_prepare_enable(priv->clk); 79 pm_runtime_get_sync(wdev->parent);
80 80
81 rwdt_write(priv, 0, RWTCSRB); 81 rwdt_write(priv, 0, RWTCSRB);
82 rwdt_write(priv, priv->cks, RWTCSRA); 82 rwdt_write(priv, priv->cks, RWTCSRA);
@@ -95,7 +95,7 @@ static int rwdt_stop(struct watchdog_device *wdev)
95 struct rwdt_priv *priv = watchdog_get_drvdata(wdev); 95 struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
96 96
97 rwdt_write(priv, priv->cks, RWTCSRA); 97 rwdt_write(priv, priv->cks, RWTCSRA);
98 clk_disable_unprepare(priv->clk); 98 pm_runtime_put(wdev->parent);
99 99
100 return 0; 100 return 0;
101} 101}
@@ -141,9 +141,16 @@ static int rwdt_probe(struct platform_device *pdev)
141 if (IS_ERR(priv->clk)) 141 if (IS_ERR(priv->clk))
142 return PTR_ERR(priv->clk); 142 return PTR_ERR(priv->clk);
143 143
144 pm_runtime_enable(&pdev->dev);
145
146 pm_runtime_get_sync(&pdev->dev);
144 priv->clk_rate = clk_get_rate(priv->clk); 147 priv->clk_rate = clk_get_rate(priv->clk);
145 if (!priv->clk_rate) 148 pm_runtime_put(&pdev->dev);
146 return -ENOENT; 149
150 if (!priv->clk_rate) {
151 ret = -ENOENT;
152 goto out_pm_disable;
153 }
147 154
148 for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) { 155 for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) {
149 clks_per_sec = priv->clk_rate / clk_divs[i]; 156 clks_per_sec = priv->clk_rate / clk_divs[i];
@@ -155,12 +162,10 @@ static int rwdt_probe(struct platform_device *pdev)
155 162
156 if (i < 0) { 163 if (i < 0) {
157 dev_err(&pdev->dev, "Can't find suitable clock divider\n"); 164 dev_err(&pdev->dev, "Can't find suitable clock divider\n");
158 return -ERANGE; 165 ret = -ERANGE;
166 goto out_pm_disable;
159 } 167 }
160 168
161 pm_runtime_enable(&pdev->dev);
162 pm_runtime_get_sync(&pdev->dev);
163
164 priv->wdev.info = &rwdt_ident, 169 priv->wdev.info = &rwdt_ident,
165 priv->wdev.ops = &rwdt_ops, 170 priv->wdev.ops = &rwdt_ops,
166 priv->wdev.parent = &pdev->dev; 171 priv->wdev.parent = &pdev->dev;
@@ -178,13 +183,14 @@ static int rwdt_probe(struct platform_device *pdev)
178 dev_warn(&pdev->dev, "Specified timeout value invalid, using default\n"); 183 dev_warn(&pdev->dev, "Specified timeout value invalid, using default\n");
179 184
180 ret = watchdog_register_device(&priv->wdev); 185 ret = watchdog_register_device(&priv->wdev);
181 if (ret < 0) { 186 if (ret < 0)
182 pm_runtime_put(&pdev->dev); 187 goto out_pm_disable;
183 pm_runtime_disable(&pdev->dev);
184 return ret;
185 }
186 188
187 return 0; 189 return 0;
190
191 out_pm_disable:
192 pm_runtime_disable(&pdev->dev);
193 return ret;
188} 194}
189 195
190static int rwdt_remove(struct platform_device *pdev) 196static int rwdt_remove(struct platform_device *pdev)
@@ -192,7 +198,6 @@ static int rwdt_remove(struct platform_device *pdev)
192 struct rwdt_priv *priv = platform_get_drvdata(pdev); 198 struct rwdt_priv *priv = platform_get_drvdata(pdev);
193 199
194 watchdog_unregister_device(&priv->wdev); 200 watchdog_unregister_device(&priv->wdev);
195 pm_runtime_put(&pdev->dev);
196 pm_runtime_disable(&pdev->dev); 201 pm_runtime_disable(&pdev->dev);
197 202
198 return 0; 203 return 0;