diff options
Diffstat (limited to 'drivers/input/keyboard/twl4030_keypad.c')
-rw-r--r-- | drivers/input/keyboard/twl4030_keypad.c | 70 |
1 files changed, 22 insertions, 48 deletions
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index f663c1953bad..71eb0411e379 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c | |||
@@ -339,12 +339,13 @@ static int twl4030_kp_probe(struct platform_device *pdev) | |||
339 | u8 reg; | 339 | u8 reg; |
340 | int error; | 340 | int error; |
341 | 341 | ||
342 | kp = kzalloc(sizeof(*kp), GFP_KERNEL); | 342 | kp = devm_kzalloc(&pdev->dev, sizeof(*kp), GFP_KERNEL); |
343 | input = input_allocate_device(); | 343 | if (!kp) |
344 | if (!kp || !input) { | 344 | return -ENOMEM; |
345 | error = -ENOMEM; | 345 | |
346 | goto err1; | 346 | input = devm_input_allocate_device(&pdev->dev); |
347 | } | 347 | if (!input) |
348 | return -ENOMEM; | ||
348 | 349 | ||
349 | /* get the debug device */ | 350 | /* get the debug device */ |
350 | kp->dbg_dev = &pdev->dev; | 351 | kp->dbg_dev = &pdev->dev; |
@@ -353,7 +354,6 @@ static int twl4030_kp_probe(struct platform_device *pdev) | |||
353 | /* setup input device */ | 354 | /* setup input device */ |
354 | input->name = "TWL4030 Keypad"; | 355 | input->name = "TWL4030 Keypad"; |
355 | input->phys = "twl4030_keypad/input0"; | 356 | input->phys = "twl4030_keypad/input0"; |
356 | input->dev.parent = &pdev->dev; | ||
357 | 357 | ||
358 | input->id.bustype = BUS_HOST; | 358 | input->id.bustype = BUS_HOST; |
359 | input->id.vendor = 0x0001; | 359 | input->id.vendor = 0x0001; |
@@ -363,8 +363,7 @@ static int twl4030_kp_probe(struct platform_device *pdev) | |||
363 | if (pdata) { | 363 | if (pdata) { |
364 | if (!pdata->rows || !pdata->cols || !pdata->keymap_data) { | 364 | if (!pdata->rows || !pdata->cols || !pdata->keymap_data) { |
365 | dev_err(&pdev->dev, "Missing platform_data\n"); | 365 | dev_err(&pdev->dev, "Missing platform_data\n"); |
366 | error = -EINVAL; | 366 | return -EINVAL; |
367 | goto err1; | ||
368 | } | 367 | } |
369 | 368 | ||
370 | kp->n_rows = pdata->rows; | 369 | kp->n_rows = pdata->rows; |
@@ -375,7 +374,7 @@ static int twl4030_kp_probe(struct platform_device *pdev) | |||
375 | error = matrix_keypad_parse_of_params(&pdev->dev, &kp->n_rows, | 374 | error = matrix_keypad_parse_of_params(&pdev->dev, &kp->n_rows, |
376 | &kp->n_cols); | 375 | &kp->n_cols); |
377 | if (error) | 376 | if (error) |
378 | goto err1; | 377 | return error; |
379 | 378 | ||
380 | kp->autorepeat = true; | 379 | kp->autorepeat = true; |
381 | } | 380 | } |
@@ -383,15 +382,13 @@ static int twl4030_kp_probe(struct platform_device *pdev) | |||
383 | if (kp->n_rows > TWL4030_MAX_ROWS || kp->n_cols > TWL4030_MAX_COLS) { | 382 | if (kp->n_rows > TWL4030_MAX_ROWS || kp->n_cols > TWL4030_MAX_COLS) { |
384 | dev_err(&pdev->dev, | 383 | dev_err(&pdev->dev, |
385 | "Invalid rows/cols amount specified in platform/devicetree data\n"); | 384 | "Invalid rows/cols amount specified in platform/devicetree data\n"); |
386 | error = -EINVAL; | 385 | return -EINVAL; |
387 | goto err1; | ||
388 | } | 386 | } |
389 | 387 | ||
390 | kp->irq = platform_get_irq(pdev, 0); | 388 | kp->irq = platform_get_irq(pdev, 0); |
391 | if (!kp->irq) { | 389 | if (!kp->irq) { |
392 | dev_err(&pdev->dev, "no keyboard irq assigned\n"); | 390 | dev_err(&pdev->dev, "no keyboard irq assigned\n"); |
393 | error = -EINVAL; | 391 | return -EINVAL; |
394 | goto err1; | ||
395 | } | 392 | } |
396 | 393 | ||
397 | error = matrix_keypad_build_keymap(keymap_data, NULL, | 394 | error = matrix_keypad_build_keymap(keymap_data, NULL, |
@@ -400,7 +397,7 @@ static int twl4030_kp_probe(struct platform_device *pdev) | |||
400 | kp->keymap, input); | 397 | kp->keymap, input); |
401 | if (error) { | 398 | if (error) { |
402 | dev_err(kp->dbg_dev, "Failed to build keymap\n"); | 399 | dev_err(kp->dbg_dev, "Failed to build keymap\n"); |
403 | goto err1; | 400 | return error; |
404 | } | 401 | } |
405 | 402 | ||
406 | input_set_capability(input, EV_MSC, MSC_SCAN); | 403 | input_set_capability(input, EV_MSC, MSC_SCAN); |
@@ -412,12 +409,12 @@ static int twl4030_kp_probe(struct platform_device *pdev) | |||
412 | if (error) { | 409 | if (error) { |
413 | dev_err(kp->dbg_dev, | 410 | dev_err(kp->dbg_dev, |
414 | "Unable to register twl4030 keypad device\n"); | 411 | "Unable to register twl4030 keypad device\n"); |
415 | goto err1; | 412 | return error; |
416 | } | 413 | } |
417 | 414 | ||
418 | error = twl4030_kp_program(kp); | 415 | error = twl4030_kp_program(kp); |
419 | if (error) | 416 | if (error) |
420 | goto err2; | 417 | return error; |
421 | 418 | ||
422 | /* | 419 | /* |
423 | * This ISR will always execute in kernel thread context because of | 420 | * This ISR will always execute in kernel thread context because of |
@@ -425,46 +422,24 @@ static int twl4030_kp_probe(struct platform_device *pdev) | |||
425 | * | 422 | * |
426 | * NOTE: we assume this host is wired to TWL4040 INT1, not INT2 ... | 423 | * NOTE: we assume this host is wired to TWL4040 INT1, not INT2 ... |
427 | */ | 424 | */ |
428 | error = request_threaded_irq(kp->irq, NULL, do_kp_irq, | 425 | error = devm_request_threaded_irq(&pdev->dev, kp->irq, NULL, do_kp_irq, |
429 | 0, pdev->name, kp); | 426 | 0, pdev->name, kp); |
430 | if (error) { | 427 | if (error) { |
431 | dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n", | 428 | dev_info(kp->dbg_dev, "request_irq failed for irq no=%d: %d\n", |
432 | kp->irq); | 429 | kp->irq, error); |
433 | goto err2; | 430 | return error; |
434 | } | 431 | } |
435 | 432 | ||
436 | /* Enable KP and TO interrupts now. */ | 433 | /* Enable KP and TO interrupts now. */ |
437 | reg = (u8) ~(KEYP_IMR1_KP | KEYP_IMR1_TO); | 434 | reg = (u8) ~(KEYP_IMR1_KP | KEYP_IMR1_TO); |
438 | if (twl4030_kpwrite_u8(kp, reg, KEYP_IMR1)) { | 435 | if (twl4030_kpwrite_u8(kp, reg, KEYP_IMR1)) { |
439 | error = -EIO; | 436 | /* mask all events - we don't care about the result */ |
440 | goto err3; | 437 | (void) twl4030_kpwrite_u8(kp, 0xff, KEYP_IMR1); |
438 | return -EIO; | ||
441 | } | 439 | } |
442 | 440 | ||
443 | platform_set_drvdata(pdev, kp); | 441 | platform_set_drvdata(pdev, kp); |
444 | return 0; | 442 | return 0; |
445 | |||
446 | err3: | ||
447 | /* mask all events - we don't care about the result */ | ||
448 | (void) twl4030_kpwrite_u8(kp, 0xff, KEYP_IMR1); | ||
449 | free_irq(kp->irq, kp); | ||
450 | err2: | ||
451 | input_unregister_device(input); | ||
452 | input = NULL; | ||
453 | err1: | ||
454 | input_free_device(input); | ||
455 | kfree(kp); | ||
456 | return error; | ||
457 | } | ||
458 | |||
459 | static int twl4030_kp_remove(struct platform_device *pdev) | ||
460 | { | ||
461 | struct twl4030_keypad *kp = platform_get_drvdata(pdev); | ||
462 | |||
463 | free_irq(kp->irq, kp); | ||
464 | input_unregister_device(kp->input); | ||
465 | kfree(kp); | ||
466 | |||
467 | return 0; | ||
468 | } | 443 | } |
469 | 444 | ||
470 | #ifdef CONFIG_OF | 445 | #ifdef CONFIG_OF |
@@ -483,7 +458,6 @@ MODULE_DEVICE_TABLE(of, twl4030_keypad_dt_match_table); | |||
483 | 458 | ||
484 | static struct platform_driver twl4030_kp_driver = { | 459 | static struct platform_driver twl4030_kp_driver = { |
485 | .probe = twl4030_kp_probe, | 460 | .probe = twl4030_kp_probe, |
486 | .remove = twl4030_kp_remove, | ||
487 | .driver = { | 461 | .driver = { |
488 | .name = "twl4030_keypad", | 462 | .name = "twl4030_keypad", |
489 | .owner = THIS_MODULE, | 463 | .owner = THIS_MODULE, |