aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2011-04-28 12:32:44 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-04-28 12:36:43 -0400
commitb6d2a3e6ff6a7019b4a240b6bc4a4d74ce82d533 (patch)
tree90cde4dc7ed09a55316aa471c46bd44c8bcdcf7d /drivers
parente490ebdc3ce1a58e66aeacc485294a45710067f5 (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')
-rw-r--r--drivers/input/keyboard/sh_keysc.c40
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
38struct sh_keysc_priv { 38struct 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}