diff options
Diffstat (limited to 'drivers/input/keyboard/nomadik-ske-keypad.c')
-rw-r--r-- | drivers/input/keyboard/nomadik-ske-keypad.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index 49f5fa64e0b1..0e6a8151fee3 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c | |||
@@ -67,6 +67,7 @@ struct ske_keypad { | |||
67 | const struct ske_keypad_platform_data *board; | 67 | const struct ske_keypad_platform_data *board; |
68 | unsigned short keymap[SKE_KPD_NUM_ROWS * SKE_KPD_NUM_COLS]; | 68 | unsigned short keymap[SKE_KPD_NUM_ROWS * SKE_KPD_NUM_COLS]; |
69 | struct clk *clk; | 69 | struct clk *clk; |
70 | struct clk *pclk; | ||
70 | spinlock_t ske_keypad_lock; | 71 | spinlock_t ske_keypad_lock; |
71 | }; | 72 | }; |
72 | 73 | ||
@@ -271,11 +272,18 @@ static int __init ske_keypad_probe(struct platform_device *pdev) | |||
271 | goto err_free_mem_region; | 272 | goto err_free_mem_region; |
272 | } | 273 | } |
273 | 274 | ||
275 | keypad->pclk = clk_get(&pdev->dev, "apb_pclk"); | ||
276 | if (IS_ERR(keypad->pclk)) { | ||
277 | dev_err(&pdev->dev, "failed to get pclk\n"); | ||
278 | error = PTR_ERR(keypad->pclk); | ||
279 | goto err_iounmap; | ||
280 | } | ||
281 | |||
274 | keypad->clk = clk_get(&pdev->dev, NULL); | 282 | keypad->clk = clk_get(&pdev->dev, NULL); |
275 | if (IS_ERR(keypad->clk)) { | 283 | if (IS_ERR(keypad->clk)) { |
276 | dev_err(&pdev->dev, "failed to get clk\n"); | 284 | dev_err(&pdev->dev, "failed to get clk\n"); |
277 | error = PTR_ERR(keypad->clk); | 285 | error = PTR_ERR(keypad->clk); |
278 | goto err_iounmap; | 286 | goto err_pclk; |
279 | } | 287 | } |
280 | 288 | ||
281 | input->id.bustype = BUS_HOST; | 289 | input->id.bustype = BUS_HOST; |
@@ -287,14 +295,25 @@ static int __init ske_keypad_probe(struct platform_device *pdev) | |||
287 | keypad->keymap, input); | 295 | keypad->keymap, input); |
288 | if (error) { | 296 | if (error) { |
289 | dev_err(&pdev->dev, "Failed to build keymap\n"); | 297 | dev_err(&pdev->dev, "Failed to build keymap\n"); |
290 | goto err_iounmap; | 298 | goto err_clk; |
291 | } | 299 | } |
292 | 300 | ||
293 | input_set_capability(input, EV_MSC, MSC_SCAN); | 301 | input_set_capability(input, EV_MSC, MSC_SCAN); |
294 | if (!plat->no_autorepeat) | 302 | if (!plat->no_autorepeat) |
295 | __set_bit(EV_REP, input->evbit); | 303 | __set_bit(EV_REP, input->evbit); |
296 | 304 | ||
297 | clk_enable(keypad->clk); | 305 | error = clk_prepare_enable(keypad->pclk); |
306 | if (error) { | ||
307 | dev_err(&pdev->dev, "Failed to prepare/enable pclk\n"); | ||
308 | goto err_clk; | ||
309 | } | ||
310 | |||
311 | error = clk_prepare_enable(keypad->clk); | ||
312 | if (error) { | ||
313 | dev_err(&pdev->dev, "Failed to prepare/enable clk\n"); | ||
314 | goto err_pclk_disable; | ||
315 | } | ||
316 | |||
298 | 317 | ||
299 | /* go through board initialization helpers */ | 318 | /* go through board initialization helpers */ |
300 | if (keypad->board->init) | 319 | if (keypad->board->init) |
@@ -330,8 +349,13 @@ static int __init ske_keypad_probe(struct platform_device *pdev) | |||
330 | err_free_irq: | 349 | err_free_irq: |
331 | free_irq(keypad->irq, keypad); | 350 | free_irq(keypad->irq, keypad); |
332 | err_clk_disable: | 351 | err_clk_disable: |
333 | clk_disable(keypad->clk); | 352 | clk_disable_unprepare(keypad->clk); |
353 | err_pclk_disable: | ||
354 | clk_disable_unprepare(keypad->pclk); | ||
355 | err_clk: | ||
334 | clk_put(keypad->clk); | 356 | clk_put(keypad->clk); |
357 | err_pclk: | ||
358 | clk_put(keypad->pclk); | ||
335 | err_iounmap: | 359 | err_iounmap: |
336 | iounmap(keypad->reg_base); | 360 | iounmap(keypad->reg_base); |
337 | err_free_mem_region: | 361 | err_free_mem_region: |
@@ -342,7 +366,7 @@ err_free_mem: | |||
342 | return error; | 366 | return error; |
343 | } | 367 | } |
344 | 368 | ||
345 | static int __devexit ske_keypad_remove(struct platform_device *pdev) | 369 | static int ske_keypad_remove(struct platform_device *pdev) |
346 | { | 370 | { |
347 | struct ske_keypad *keypad = platform_get_drvdata(pdev); | 371 | struct ske_keypad *keypad = platform_get_drvdata(pdev); |
348 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 372 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -351,7 +375,7 @@ static int __devexit ske_keypad_remove(struct platform_device *pdev) | |||
351 | 375 | ||
352 | input_unregister_device(keypad->input); | 376 | input_unregister_device(keypad->input); |
353 | 377 | ||
354 | clk_disable(keypad->clk); | 378 | clk_disable_unprepare(keypad->clk); |
355 | clk_put(keypad->clk); | 379 | clk_put(keypad->clk); |
356 | 380 | ||
357 | if (keypad->board->exit) | 381 | if (keypad->board->exit) |
@@ -403,7 +427,7 @@ static struct platform_driver ske_keypad_driver = { | |||
403 | .owner = THIS_MODULE, | 427 | .owner = THIS_MODULE, |
404 | .pm = &ske_keypad_dev_pm_ops, | 428 | .pm = &ske_keypad_dev_pm_ops, |
405 | }, | 429 | }, |
406 | .remove = __devexit_p(ske_keypad_remove), | 430 | .remove = ske_keypad_remove, |
407 | }; | 431 | }; |
408 | 432 | ||
409 | static int __init ske_keypad_init(void) | 433 | static int __init ske_keypad_init(void) |