aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2012-04-21 01:33:09 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-04-21 02:06:52 -0400
commitb83643ebf2242388585e95c9a8d2353745d77cfd (patch)
tree453d51b7f20c37d90d3b8d168379ee50978669dc
parent01111fcd42b050bdb7113a7c2c0aed2eaef67b53 (diff)
Input: matrix-keypad - undo GPIO setup if input_register_device fails
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/keyboard/matrix_keypad.c53
1 files changed, 30 insertions, 23 deletions
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index a4ff08caa44b..98ae281bedb0 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -299,11 +299,11 @@ static int matrix_keypad_resume(struct device *dev)
299static SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops, 299static SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops,
300 matrix_keypad_suspend, matrix_keypad_resume); 300 matrix_keypad_suspend, matrix_keypad_resume);
301 301
302static int __devinit init_matrix_gpio(struct platform_device *pdev, 302static int __devinit matrix_keypad_init_gpio(struct platform_device *pdev,
303 struct matrix_keypad *keypad) 303 struct matrix_keypad *keypad)
304{ 304{
305 const struct matrix_keypad_platform_data *pdata = keypad->pdata; 305 const struct matrix_keypad_platform_data *pdata = keypad->pdata;
306 int i, err = -EINVAL; 306 int i, err;
307 307
308 /* initialized strobe lines as outputs, activated */ 308 /* initialized strobe lines as outputs, activated */
309 for (i = 0; i < pdata->num_col_gpios; i++) { 309 for (i = 0; i < pdata->num_col_gpios; i++) {
@@ -349,8 +349,7 @@ static int __devinit init_matrix_gpio(struct platform_device *pdev,
349 "matrix-keypad", keypad); 349 "matrix-keypad", keypad);
350 if (err) { 350 if (err) {
351 dev_err(&pdev->dev, 351 dev_err(&pdev->dev,
352 "Unable to acquire interrupt " 352 "Unable to acquire interrupt for GPIO line %i\n",
353 "for GPIO line %i\n",
354 pdata->row_gpios[i]); 353 pdata->row_gpios[i]);
355 goto err_free_irqs; 354 goto err_free_irqs;
356 } 355 }
@@ -376,6 +375,25 @@ err_free_cols:
376 return err; 375 return err;
377} 376}
378 377
378static void matrix_keypad_free_gpio(struct matrix_keypad *keypad)
379{
380 const struct matrix_keypad_platform_data *pdata = keypad->pdata;
381 int i;
382
383 if (pdata->clustered_irq > 0) {
384 free_irq(pdata->clustered_irq, keypad);
385 } else {
386 for (i = 0; i < pdata->num_row_gpios; i++)
387 free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad);
388 }
389
390 for (i = 0; i < pdata->num_row_gpios; i++)
391 gpio_free(pdata->row_gpios[i]);
392
393 for (i = 0; i < pdata->num_col_gpios; i++)
394 gpio_free(pdata->col_gpios[i]);
395}
396
379static int __devinit matrix_keypad_probe(struct platform_device *pdev) 397static int __devinit matrix_keypad_probe(struct platform_device *pdev)
380{ 398{
381 const struct matrix_keypad_platform_data *pdata; 399 const struct matrix_keypad_platform_data *pdata;
@@ -435,19 +453,21 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
435 input_set_capability(input_dev, EV_MSC, MSC_SCAN); 453 input_set_capability(input_dev, EV_MSC, MSC_SCAN);
436 input_set_drvdata(input_dev, keypad); 454 input_set_drvdata(input_dev, keypad);
437 455
438 err = init_matrix_gpio(pdev, keypad); 456 err = matrix_keypad_init_gpio(pdev, keypad);
439 if (err) 457 if (err)
440 goto err_free_mem; 458 goto err_free_mem;
441 459
442 err = input_register_device(keypad->input_dev); 460 err = input_register_device(keypad->input_dev);
443 if (err) 461 if (err)
444 goto err_free_mem; 462 goto err_free_gpio;
445 463
446 device_init_wakeup(&pdev->dev, pdata->wakeup); 464 device_init_wakeup(&pdev->dev, pdata->wakeup);
447 platform_set_drvdata(pdev, keypad); 465 platform_set_drvdata(pdev, keypad);
448 466
449 return 0; 467 return 0;
450 468
469err_free_gpio:
470 matrix_keypad_free_gpio(keypad);
451err_free_mem: 471err_free_mem:
452 input_free_device(input_dev); 472 input_free_device(input_dev);
453 kfree(keypad); 473 kfree(keypad);
@@ -457,28 +477,15 @@ err_free_mem:
457static int __devexit matrix_keypad_remove(struct platform_device *pdev) 477static int __devexit matrix_keypad_remove(struct platform_device *pdev)
458{ 478{
459 struct matrix_keypad *keypad = platform_get_drvdata(pdev); 479 struct matrix_keypad *keypad = platform_get_drvdata(pdev);
460 const struct matrix_keypad_platform_data *pdata = keypad->pdata;
461 int i;
462 480
463 device_init_wakeup(&pdev->dev, 0); 481 device_init_wakeup(&pdev->dev, 0);
464 482
465 if (pdata->clustered_irq > 0) { 483 matrix_keypad_free_gpio(keypad);
466 free_irq(pdata->clustered_irq, keypad);
467 } else {
468 for (i = 0; i < pdata->num_row_gpios; i++)
469 free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad);
470 }
471
472 for (i = 0; i < pdata->num_row_gpios; i++)
473 gpio_free(pdata->row_gpios[i]);
474
475 for (i = 0; i < pdata->num_col_gpios; i++)
476 gpio_free(pdata->col_gpios[i]);
477
478 input_unregister_device(keypad->input_dev); 484 input_unregister_device(keypad->input_dev);
479 platform_set_drvdata(pdev, NULL);
480 kfree(keypad); 485 kfree(keypad);
481 486
487 platform_set_drvdata(pdev, NULL);
488
482 return 0; 489 return 0;
483} 490}
484 491