aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard/sh_keysc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-24 14:58:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-24 14:58:49 -0400
commit4637f40f200063973553ce3c4c1ac6c247e4535c (patch)
treeff317a0dfb67cae313a208d120edd5102730044d /drivers/input/keyboard/sh_keysc.c
parent5129df03d0c44b2d5a5f9d7d52f3b079706b9a8f (diff)
parentb73077eb03f510a84b102fb97640e595a958403c (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (40 commits) Input: ADP5589 - new driver for I2C Keypad Decoder and I/O Expander Input: tsc2007 - add X, Y and Z fuzz factors to platform data Input: tsc2007 - add poll_period parameter to platform data Input: tsc2007 - add poll_delay parameter to platform data Input: tsc2007 - add max_rt parameter to platform data Input: tsc2007 - debounce pressure measurement Input: ad714x - fix captouch wheel option algorithm Input: ad714x - allow platform code to specify irqflags Input: ad714x - fix threshold and completion interrupt masks Input: ad714x - fix up input configuration Input: elantech - remove support for proprietary X driver Input: elantech - report multitouch with proper ABS_MT messages Input: elantech - export pressure and width when supported Input: elantech - describe further the protocol Input: atmel_tsadcc - correct call to input_free_device Input: add driver FSL MPR121 capacitive touch sensor Input: remove useless synchronize_rcu() calls Input: ads7846 - fix gpio_pendown configuration Input: ads7846 - add possibility to use external vref on ads7846 Input: rotary-encoder - add support for half-period encoders ...
Diffstat (limited to 'drivers/input/keyboard/sh_keysc.c')
-rw-r--r--drivers/input/keyboard/sh_keysc.c53
1 files changed, 22 insertions, 31 deletions
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index d7dafd9425b6..834cf98e7efb 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;
@@ -241,10 +231,11 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
241 input->keycodesize = sizeof(pdata->keycodes[0]); 231 input->keycodesize = sizeof(pdata->keycodes[0]);
242 input->keycodemax = ARRAY_SIZE(pdata->keycodes); 232 input->keycodemax = ARRAY_SIZE(pdata->keycodes);
243 233
244 error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev); 234 error = request_threaded_irq(irq, NULL, sh_keysc_isr, IRQF_ONESHOT,
235 dev_name(&pdev->dev), pdev);
245 if (error) { 236 if (error) {
246 dev_err(&pdev->dev, "failed to request IRQ\n"); 237 dev_err(&pdev->dev, "failed to request IRQ\n");
247 goto err4; 238 goto err3;
248 } 239 }
249 240
250 for (i = 0; i < SH_KEYSC_MAXKEYS; i++) 241 for (i = 0; i < SH_KEYSC_MAXKEYS; i++)
@@ -254,10 +245,11 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
254 error = input_register_device(input); 245 error = input_register_device(input);
255 if (error) { 246 if (error) {
256 dev_err(&pdev->dev, "failed to register input device\n"); 247 dev_err(&pdev->dev, "failed to register input device\n");
257 goto err5; 248 goto err4;
258 } 249 }
259 250
260 clk_enable(priv->clk); 251 pm_runtime_enable(&pdev->dev);
252 pm_runtime_get_sync(&pdev->dev);
261 253
262 sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) | 254 sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) |
263 pdata->scan_timing); 255 pdata->scan_timing);
@@ -267,12 +259,10 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
267 259
268 return 0; 260 return 0;
269 261
270 err5:
271 free_irq(irq, pdev);
272 err4: 262 err4:
273 input_free_device(input); 263 free_irq(irq, pdev);
274 err3: 264 err3:
275 clk_put(priv->clk); 265 input_free_device(input);
276 err2: 266 err2:
277 iounmap(priv->iomem_base); 267 iounmap(priv->iomem_base);
278 err1: 268 err1:
@@ -292,8 +282,8 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev)
292 free_irq(platform_get_irq(pdev, 0), pdev); 282 free_irq(platform_get_irq(pdev, 0), pdev);
293 iounmap(priv->iomem_base); 283 iounmap(priv->iomem_base);
294 284
295 clk_disable(priv->clk); 285 pm_runtime_put_sync(&pdev->dev);
296 clk_put(priv->clk); 286 pm_runtime_disable(&pdev->dev);
297 287
298 platform_set_drvdata(pdev, NULL); 288 platform_set_drvdata(pdev, NULL);
299 kfree(priv); 289 kfree(priv);
@@ -301,6 +291,7 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev)
301 return 0; 291 return 0;
302} 292}
303 293
294#if CONFIG_PM_SLEEP
304static int sh_keysc_suspend(struct device *dev) 295static int sh_keysc_suspend(struct device *dev)
305{ 296{
306 struct platform_device *pdev = to_platform_device(dev); 297 struct platform_device *pdev = to_platform_device(dev);
@@ -311,14 +302,13 @@ static int sh_keysc_suspend(struct device *dev)
311 value = sh_keysc_read(priv, KYCR1); 302 value = sh_keysc_read(priv, KYCR1);
312 303
313 if (device_may_wakeup(dev)) { 304 if (device_may_wakeup(dev)) {
314 value |= 0x80; 305 sh_keysc_write(priv, KYCR1, value | 0x80);
315 enable_irq_wake(irq); 306 enable_irq_wake(irq);
316 } else { 307 } else {
317 value &= ~0x80; 308 sh_keysc_write(priv, KYCR1, value & ~0x80);
309 pm_runtime_put_sync(dev);
318 } 310 }
319 311
320 sh_keysc_write(priv, KYCR1, value);
321
322 return 0; 312 return 0;
323} 313}
324 314
@@ -329,16 +319,17 @@ static int sh_keysc_resume(struct device *dev)
329 319
330 if (device_may_wakeup(dev)) 320 if (device_may_wakeup(dev))
331 disable_irq_wake(irq); 321 disable_irq_wake(irq);
322 else
323 pm_runtime_get_sync(dev);
332 324
333 return 0; 325 return 0;
334} 326}
327#endif
335 328
336static const struct dev_pm_ops sh_keysc_dev_pm_ops = { 329static SIMPLE_DEV_PM_OPS(sh_keysc_dev_pm_ops,
337 .suspend = sh_keysc_suspend, 330 sh_keysc_suspend, sh_keysc_resume);
338 .resume = sh_keysc_resume,
339};
340 331
341struct platform_driver sh_keysc_device_driver = { 332static struct platform_driver sh_keysc_device_driver = {
342 .probe = sh_keysc_probe, 333 .probe = sh_keysc_probe,
343 .remove = __devexit_p(sh_keysc_remove), 334 .remove = __devexit_p(sh_keysc_remove),
344 .driver = { 335 .driver = {