aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorSachin Kamat <sachin.kamat@linaro.org>2012-11-28 01:34:38 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-11-28 01:38:37 -0500
commita57da34795452bbe44b55e2b69c3ab6b117cc4b4 (patch)
tree049d65cd15dd174103aec81e5fae42c23db0472c /drivers/input
parent9336648978c2e9de9bf3c026918db386ace19a86 (diff)
Input: samsung-keypad - switch to using managed resources
devm_* functions are device managed and make error handling and code simpler. While at it also fix error exit paths. Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/keyboard/samsung-keypad.c103
1 files changed, 31 insertions, 72 deletions
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c
index acc161966c3e..22e357b51024 100644
--- a/drivers/input/keyboard/samsung-keypad.c
+++ b/drivers/input/keyboard/samsung-keypad.c
@@ -309,7 +309,7 @@ static void samsung_keypad_parse_dt_gpio(struct device *dev,
309 struct samsung_keypad *keypad) 309 struct samsung_keypad *keypad)
310{ 310{
311 struct device_node *np = dev->of_node; 311 struct device_node *np = dev->of_node;
312 int gpio, ret, row, col; 312 int gpio, error, row, col;
313 313
314 for (row = 0; row < keypad->rows; row++) { 314 for (row = 0; row < keypad->rows; row++) {
315 gpio = of_get_named_gpio(np, "row-gpios", row); 315 gpio = of_get_named_gpio(np, "row-gpios", row);
@@ -320,10 +320,11 @@ static void samsung_keypad_parse_dt_gpio(struct device *dev,
320 continue; 320 continue;
321 } 321 }
322 322
323 ret = gpio_request(gpio, "keypad-row"); 323 error = devm_gpio_request(dev, gpio, "keypad-row");
324 if (ret) 324 if (error)
325 dev_err(dev, "keypad row[%d] gpio request failed\n", 325 dev_err(dev,
326 row); 326 "keypad row[%d] gpio request failed: %d\n",
327 row, error);
327 } 328 }
328 329
329 for (col = 0; col < keypad->cols; col++) { 330 for (col = 0; col < keypad->cols; col++) {
@@ -335,35 +336,19 @@ static void samsung_keypad_parse_dt_gpio(struct device *dev,
335 continue; 336 continue;
336 } 337 }
337 338
338 ret = gpio_request(gpio, "keypad-col"); 339 error = devm_gpio_request(dev, gpio, "keypad-col");
339 if (ret) 340 if (error)
340 dev_err(dev, "keypad column[%d] gpio request failed\n", 341 dev_err(dev,
341 col); 342 "keypad column[%d] gpio request failed: %d\n",
343 col, error);
342 } 344 }
343} 345}
344
345static void samsung_keypad_dt_gpio_free(struct samsung_keypad *keypad)
346{
347 int cnt;
348
349 for (cnt = 0; cnt < keypad->rows; cnt++)
350 if (gpio_is_valid(keypad->row_gpios[cnt]))
351 gpio_free(keypad->row_gpios[cnt]);
352
353 for (cnt = 0; cnt < keypad->cols; cnt++)
354 if (gpio_is_valid(keypad->col_gpios[cnt]))
355 gpio_free(keypad->col_gpios[cnt]);
356}
357#else 346#else
358static 347static
359struct samsung_keypad_platdata *samsung_keypad_parse_dt(struct device *dev) 348struct samsung_keypad_platdata *samsung_keypad_parse_dt(struct device *dev)
360{ 349{
361 return NULL; 350 return NULL;
362} 351}
363
364static void samsung_keypad_dt_gpio_free(struct samsung_keypad *keypad)
365{
366}
367#endif 352#endif
368 353
369static int samsung_keypad_probe(struct platform_device *pdev) 354static int samsung_keypad_probe(struct platform_device *pdev)
@@ -405,36 +390,30 @@ static int samsung_keypad_probe(struct platform_device *pdev)
405 row_shift = get_count_order(pdata->cols); 390 row_shift = get_count_order(pdata->cols);
406 keymap_size = (pdata->rows << row_shift) * sizeof(keypad->keycodes[0]); 391 keymap_size = (pdata->rows << row_shift) * sizeof(keypad->keycodes[0]);
407 392
408 keypad = kzalloc(sizeof(*keypad) + keymap_size, GFP_KERNEL); 393 keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad) + keymap_size,
409 input_dev = input_allocate_device(); 394 GFP_KERNEL);
410 if (!keypad || !input_dev) { 395 input_dev = devm_input_allocate_device(&pdev->dev);
411 error = -ENOMEM; 396 if (!keypad || !input_dev)
412 goto err_free_mem; 397 return -ENOMEM;
413 }
414 398
415 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 399 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
416 if (!res) { 400 if (!res)
417 error = -ENODEV; 401 return -ENODEV;
418 goto err_free_mem;
419 }
420 402
421 keypad->base = ioremap(res->start, resource_size(res)); 403 keypad->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
422 if (!keypad->base) { 404 if (!keypad->base)
423 error = -EBUSY; 405 return -EBUSY;
424 goto err_free_mem;
425 }
426 406
427 keypad->clk = clk_get(&pdev->dev, "keypad"); 407 keypad->clk = devm_clk_get(&pdev->dev, "keypad");
428 if (IS_ERR(keypad->clk)) { 408 if (IS_ERR(keypad->clk)) {
429 dev_err(&pdev->dev, "failed to get keypad clk\n"); 409 dev_err(&pdev->dev, "failed to get keypad clk\n");
430 error = PTR_ERR(keypad->clk); 410 return PTR_ERR(keypad->clk);
431 goto err_unmap_base;
432 } 411 }
433 412
434 error = clk_prepare(keypad->clk); 413 error = clk_prepare(keypad->clk);
435 if (error) { 414 if (error) {
436 dev_err(&pdev->dev, "keypad clock prepare failed\n"); 415 dev_err(&pdev->dev, "keypad clock prepare failed\n");
437 goto err_put_clk; 416 return error;
438 } 417 }
439 418
440 keypad->input_dev = input_dev; 419 keypad->input_dev = input_dev;
@@ -479,14 +458,15 @@ static int samsung_keypad_probe(struct platform_device *pdev)
479 keypad->irq = platform_get_irq(pdev, 0); 458 keypad->irq = platform_get_irq(pdev, 0);
480 if (keypad->irq < 0) { 459 if (keypad->irq < 0) {
481 error = keypad->irq; 460 error = keypad->irq;
482 goto err_put_clk; 461 goto err_unprepare_clk;
483 } 462 }
484 463
485 error = request_threaded_irq(keypad->irq, NULL, samsung_keypad_irq, 464 error = devm_request_threaded_irq(&pdev->dev, keypad->irq, NULL,
486 IRQF_ONESHOT, dev_name(&pdev->dev), keypad); 465 samsung_keypad_irq, IRQF_ONESHOT,
466 dev_name(&pdev->dev), keypad);
487 if (error) { 467 if (error) {
488 dev_err(&pdev->dev, "failed to register keypad interrupt\n"); 468 dev_err(&pdev->dev, "failed to register keypad interrupt\n");
489 goto err_put_clk; 469 goto err_unprepare_clk;
490 } 470 }
491 471
492 device_init_wakeup(&pdev->dev, pdata->wakeup); 472 device_init_wakeup(&pdev->dev, pdata->wakeup);
@@ -495,7 +475,7 @@ static int samsung_keypad_probe(struct platform_device *pdev)
495 475
496 error = input_register_device(keypad->input_dev); 476 error = input_register_device(keypad->input_dev);
497 if (error) 477 if (error)
498 goto err_free_irq; 478 goto err_disable_runtime_pm;
499 479
500 if (pdev->dev.of_node) { 480 if (pdev->dev.of_node) {
501 devm_kfree(&pdev->dev, (void *)pdata->keymap_data->keymap); 481 devm_kfree(&pdev->dev, (void *)pdata->keymap_data->keymap);
@@ -504,22 +484,12 @@ static int samsung_keypad_probe(struct platform_device *pdev)
504 } 484 }
505 return 0; 485 return 0;
506 486
507err_free_irq: 487err_disable_runtime_pm:
508 free_irq(keypad->irq, keypad);
509 pm_runtime_disable(&pdev->dev); 488 pm_runtime_disable(&pdev->dev);
510 device_init_wakeup(&pdev->dev, 0); 489 device_init_wakeup(&pdev->dev, 0);
511 platform_set_drvdata(pdev, NULL); 490 platform_set_drvdata(pdev, NULL);
512err_unprepare_clk: 491err_unprepare_clk:
513 clk_unprepare(keypad->clk); 492 clk_unprepare(keypad->clk);
514err_put_clk:
515 clk_put(keypad->clk);
516 samsung_keypad_dt_gpio_free(keypad);
517err_unmap_base:
518 iounmap(keypad->base);
519err_free_mem:
520 input_free_device(input_dev);
521 kfree(keypad);
522
523 return error; 493 return error;
524} 494}
525 495
@@ -533,18 +503,7 @@ static int samsung_keypad_remove(struct platform_device *pdev)
533 503
534 input_unregister_device(keypad->input_dev); 504 input_unregister_device(keypad->input_dev);
535 505
536 /*
537 * It is safe to free IRQ after unregistering device because
538 * samsung_keypad_close will shut off interrupts.
539 */
540 free_irq(keypad->irq, keypad);
541
542 clk_unprepare(keypad->clk); 506 clk_unprepare(keypad->clk);
543 clk_put(keypad->clk);
544 samsung_keypad_dt_gpio_free(keypad);
545
546 iounmap(keypad->base);
547 kfree(keypad);
548 507
549 return 0; 508 return 0;
550} 509}