diff options
author | Magnus Damm <damm@opensource.se> | 2011-04-28 12:32:44 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-04-28 12:36:43 -0400 |
commit | b6d2a3e6ff6a7019b4a240b6bc4a4d74ce82d533 (patch) | |
tree | 90cde4dc7ed09a55316aa471c46bd44c8bcdcf7d /drivers/input/keyboard | |
parent | e490ebdc3ce1a58e66aeacc485294a45710067f5 (diff) |
Input: sh_keysc - implement runtime PM support
Convert the KEYSC driver from MSTP bit control through a magic clock
string to making use of Runtime PM.
Also, update the system suspend/resume callbacks to drop the Runtime
PM reference in the case of wakeup disabled.
Signed-off-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r-- | drivers/input/keyboard/sh_keysc.c | 40 |
1 files changed, 15 insertions, 25 deletions
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index d7dafd9425b6..429ac2b77438 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | #include <linux/input/sh_keysc.h> | 21 | #include <linux/input/sh_keysc.h> |
22 | #include <linux/bitmap.h> | 22 | #include <linux/bitmap.h> |
23 | #include <linux/clk.h> | 23 | #include <linux/pm_runtime.h> |
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | 26 | ||
@@ -37,7 +37,6 @@ static const struct { | |||
37 | 37 | ||
38 | struct sh_keysc_priv { | 38 | struct sh_keysc_priv { |
39 | void __iomem *iomem_base; | 39 | void __iomem *iomem_base; |
40 | struct clk *clk; | ||
41 | DECLARE_BITMAP(last_keys, SH_KEYSC_MAXKEYS); | 40 | DECLARE_BITMAP(last_keys, SH_KEYSC_MAXKEYS); |
42 | struct input_dev *input; | 41 | struct input_dev *input; |
43 | struct sh_keysc_info pdata; | 42 | struct sh_keysc_info pdata; |
@@ -169,7 +168,6 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
169 | struct sh_keysc_info *pdata; | 168 | struct sh_keysc_info *pdata; |
170 | struct resource *res; | 169 | struct resource *res; |
171 | struct input_dev *input; | 170 | struct input_dev *input; |
172 | char clk_name[8]; | ||
173 | int i; | 171 | int i; |
174 | int irq, error; | 172 | int irq, error; |
175 | 173 | ||
@@ -210,19 +208,11 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
210 | goto err1; | 208 | goto err1; |
211 | } | 209 | } |
212 | 210 | ||
213 | snprintf(clk_name, sizeof(clk_name), "keysc%d", pdev->id); | ||
214 | priv->clk = clk_get(&pdev->dev, clk_name); | ||
215 | if (IS_ERR(priv->clk)) { | ||
216 | dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); | ||
217 | error = PTR_ERR(priv->clk); | ||
218 | goto err2; | ||
219 | } | ||
220 | |||
221 | priv->input = input_allocate_device(); | 211 | priv->input = input_allocate_device(); |
222 | if (!priv->input) { | 212 | if (!priv->input) { |
223 | dev_err(&pdev->dev, "failed to allocate input device\n"); | 213 | dev_err(&pdev->dev, "failed to allocate input device\n"); |
224 | error = -ENOMEM; | 214 | error = -ENOMEM; |
225 | goto err3; | 215 | goto err2; |
226 | } | 216 | } |
227 | 217 | ||
228 | input = priv->input; | 218 | input = priv->input; |
@@ -244,7 +234,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
244 | error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev); | 234 | error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev); |
245 | if (error) { | 235 | if (error) { |
246 | dev_err(&pdev->dev, "failed to request IRQ\n"); | 236 | dev_err(&pdev->dev, "failed to request IRQ\n"); |
247 | goto err4; | 237 | goto err3; |
248 | } | 238 | } |
249 | 239 | ||
250 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) | 240 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) |
@@ -254,10 +244,11 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
254 | error = input_register_device(input); | 244 | error = input_register_device(input); |
255 | if (error) { | 245 | if (error) { |
256 | dev_err(&pdev->dev, "failed to register input device\n"); | 246 | dev_err(&pdev->dev, "failed to register input device\n"); |
257 | goto err5; | 247 | goto err4; |
258 | } | 248 | } |
259 | 249 | ||
260 | clk_enable(priv->clk); | 250 | pm_runtime_enable(&pdev->dev); |
251 | pm_runtime_get_sync(&pdev->dev); | ||
261 | 252 | ||
262 | sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) | | 253 | sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) | |
263 | pdata->scan_timing); | 254 | pdata->scan_timing); |
@@ -267,12 +258,10 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
267 | 258 | ||
268 | return 0; | 259 | return 0; |
269 | 260 | ||
270 | err5: | ||
271 | free_irq(irq, pdev); | ||
272 | err4: | 261 | err4: |
273 | input_free_device(input); | 262 | free_irq(irq, pdev); |
274 | err3: | 263 | err3: |
275 | clk_put(priv->clk); | 264 | input_free_device(input); |
276 | err2: | 265 | err2: |
277 | iounmap(priv->iomem_base); | 266 | iounmap(priv->iomem_base); |
278 | err1: | 267 | err1: |
@@ -292,8 +281,8 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) | |||
292 | free_irq(platform_get_irq(pdev, 0), pdev); | 281 | free_irq(platform_get_irq(pdev, 0), pdev); |
293 | iounmap(priv->iomem_base); | 282 | iounmap(priv->iomem_base); |
294 | 283 | ||
295 | clk_disable(priv->clk); | 284 | pm_runtime_put_sync(&pdev->dev); |
296 | clk_put(priv->clk); | 285 | pm_runtime_disable(&pdev->dev); |
297 | 286 | ||
298 | platform_set_drvdata(pdev, NULL); | 287 | platform_set_drvdata(pdev, NULL); |
299 | kfree(priv); | 288 | kfree(priv); |
@@ -311,14 +300,13 @@ static int sh_keysc_suspend(struct device *dev) | |||
311 | value = sh_keysc_read(priv, KYCR1); | 300 | value = sh_keysc_read(priv, KYCR1); |
312 | 301 | ||
313 | if (device_may_wakeup(dev)) { | 302 | if (device_may_wakeup(dev)) { |
314 | value |= 0x80; | 303 | sh_keysc_write(priv, KYCR1, value | 0x80); |
315 | enable_irq_wake(irq); | 304 | enable_irq_wake(irq); |
316 | } else { | 305 | } else { |
317 | value &= ~0x80; | 306 | sh_keysc_write(priv, KYCR1, value & ~0x80); |
307 | pm_runtime_put_sync(dev); | ||
318 | } | 308 | } |
319 | 309 | ||
320 | sh_keysc_write(priv, KYCR1, value); | ||
321 | |||
322 | return 0; | 310 | return 0; |
323 | } | 311 | } |
324 | 312 | ||
@@ -329,6 +317,8 @@ static int sh_keysc_resume(struct device *dev) | |||
329 | 317 | ||
330 | if (device_may_wakeup(dev)) | 318 | if (device_may_wakeup(dev)) |
331 | disable_irq_wake(irq); | 319 | disable_irq_wake(irq); |
320 | else | ||
321 | pm_runtime_get_sync(dev); | ||
332 | 322 | ||
333 | return 0; | 323 | return 0; |
334 | } | 324 | } |