diff options
author | Wolfram Sang <wsa+renesas@sang-engineering.com> | 2017-07-26 17:54:37 -0400 |
---|---|---|
committer | Wim Van Sebroeck <wim@iguana.be> | 2017-09-09 15:11:52 -0400 |
commit | 3be42941dd9df9b7c5062fc98c416a15bf4bbc0f (patch) | |
tree | 808da097e4025ebdd960e359d7f75426edb29d40 /drivers/watchdog | |
parent | 012c04601f9dc6a268ebff87a890b339af6d25bf (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.c | 33 |
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 | ||
190 | static int rwdt_remove(struct platform_device *pdev) | 196 | static 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; |