Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: matrix_keypad - check for errors from of_get_named_gpio()

"of_get_named_gpio()" returns a negative error value if it fails
and drivers should check for this. This missing check was now
added to the matrix_keypad driver.

In my case "of_get_named_gpio()" returned -EPROBE_DEFER because
the referenced GPIOs belong to an I/O expander, which was not yet
probed at the point in time when the matrix_keypad driver was
loading. Because the driver did not check for errors from the
"of_get_named_gpio()" routine, it was assuming that "-EPROBE_DEFER"
is actually a GPIO number and continued as usual, which led to further
errors like this later on:

WARNING: CPU: 3 PID: 167 at drivers/gpio/gpiolib.c:114
gpio_to_desc+0xc8/0xd0
invalid GPIO -517

Note that the "GPIO number" -517 in the error message above is
actually "-EPROBE_DEFER".

As part of the patch a misleading error message "no platform data defined"
was also removed. This does not lead to information loss because the other
error paths in matrix_keypad_parse_dt() already print an error.

Signed-off-by: Christian Hoff <christian_hoff@gmx.net>
Suggested-by: Sebastian Reichel <sre@kernel.org>
Reviewed-by: Sebastian Reichel <sre@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Christian Hoff and committed by
Dmitry Torokhov
d55bda1b cacd9759

+14 -9
+14 -9
drivers/input/keyboard/matrix_keypad.c
··· 407 407 struct matrix_keypad_platform_data *pdata; 408 408 struct device_node *np = dev->of_node; 409 409 unsigned int *gpios; 410 - int i, nrow, ncol; 410 + int ret, i, nrow, ncol; 411 411 412 412 if (!np) { 413 413 dev_err(dev, "device lacks DT data\n"); ··· 452 452 return ERR_PTR(-ENOMEM); 453 453 } 454 454 455 - for (i = 0; i < pdata->num_row_gpios; i++) 456 - gpios[i] = of_get_named_gpio(np, "row-gpios", i); 455 + for (i = 0; i < nrow; i++) { 456 + ret = of_get_named_gpio(np, "row-gpios", i); 457 + if (ret < 0) 458 + return ERR_PTR(ret); 459 + gpios[i] = ret; 460 + } 457 461 458 - for (i = 0; i < pdata->num_col_gpios; i++) 459 - gpios[pdata->num_row_gpios + i] = 460 - of_get_named_gpio(np, "col-gpios", i); 462 + for (i = 0; i < ncol; i++) { 463 + ret = of_get_named_gpio(np, "col-gpios", i); 464 + if (ret < 0) 465 + return ERR_PTR(ret); 466 + gpios[nrow + i] = ret; 467 + } 461 468 462 469 pdata->row_gpios = gpios; 463 470 pdata->col_gpios = &gpios[pdata->num_row_gpios]; ··· 491 484 pdata = dev_get_platdata(&pdev->dev); 492 485 if (!pdata) { 493 486 pdata = matrix_keypad_parse_dt(&pdev->dev); 494 - if (IS_ERR(pdata)) { 495 - dev_err(&pdev->dev, "no platform data defined\n"); 487 + if (IS_ERR(pdata)) 496 488 return PTR_ERR(pdata); 497 - } 498 489 } else if (!pdata->keymap_data) { 499 490 dev_err(&pdev->dev, "no keymap data defined\n"); 500 491 return -EINVAL;