aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen/tsc2007.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/tsc2007.c')
-rw-r--r--drivers/input/touchscreen/tsc2007.c79
1 files changed, 40 insertions, 39 deletions
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
index 03fbdf1e8613..1bf9906b5a3f 100644
--- a/drivers/input/touchscreen/tsc2007.c
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -365,6 +365,14 @@ static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts,
365 return 0; 365 return 0;
366} 366}
367 367
368static void tsc2007_call_exit_platform_hw(void *data)
369{
370 struct device *dev = data;
371 const struct tsc2007_platform_data *pdata = dev_get_platdata(dev);
372
373 pdata->exit_platform_hw();
374}
375
368static int tsc2007_probe(struct i2c_client *client, 376static int tsc2007_probe(struct i2c_client *client,
369 const struct i2c_device_id *id) 377 const struct i2c_device_id *id)
370{ 378{
@@ -388,11 +396,9 @@ static int tsc2007_probe(struct i2c_client *client,
388 if (err) 396 if (err)
389 return err; 397 return err;
390 398
391 input_dev = input_allocate_device(); 399 input_dev = devm_input_allocate_device(&client->dev);
392 if (!input_dev) { 400 if (!input_dev)
393 err = -ENOMEM; 401 return -ENOMEM;
394 goto err_free_input;
395 };
396 402
397 i2c_set_clientdata(client, ts); 403 i2c_set_clientdata(client, ts);
398 404
@@ -421,45 +427,41 @@ static int tsc2007_probe(struct i2c_client *client,
421 input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 427 input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT,
422 ts->fuzzz, 0); 428 ts->fuzzz, 0);
423 429
424 if (pdata && pdata->init_platform_hw) 430 if (pdata) {
425 pdata->init_platform_hw(); 431 if (pdata->exit_platform_hw) {
432 err = devm_add_action(&client->dev,
433 tsc2007_call_exit_platform_hw,
434 &client->dev);
435 if (err) {
436 dev_err(&client->dev,
437 "Failed to register exit_platform_hw action, %d\n",
438 err);
439 return err;
440 }
441 }
442
443 if (pdata->init_platform_hw)
444 pdata->init_platform_hw();
445 }
426 446
427 err = request_threaded_irq(ts->irq, tsc2007_hard_irq, tsc2007_soft_irq, 447 err = devm_request_threaded_irq(&client->dev, ts->irq,
428 IRQF_ONESHOT, client->dev.driver->name, ts); 448 tsc2007_hard_irq, tsc2007_soft_irq,
429 if (err < 0) { 449 IRQF_ONESHOT,
430 dev_err(&client->dev, "irq %d busy?\n", ts->irq); 450 client->dev.driver->name, ts);
431 goto err_free_input; 451 if (err) {
452 dev_err(&client->dev, "Failed to request irq %d: %d\n",
453 ts->irq, err);
454 return err;
432 } 455 }
433 456
434 tsc2007_stop(ts); 457 tsc2007_stop(ts);
435 458
436 err = input_register_device(input_dev); 459 err = input_register_device(input_dev);
437 if (err) 460 if (err) {
438 goto err_free_irq; 461 dev_err(&client->dev,
439 462 "Failed to register input device: %d\n", err);
440 return 0; 463 return err;
441 464 }
442 err_free_irq:
443 free_irq(ts->irq, ts);
444 if (pdata && pdata->exit_platform_hw)
445 pdata->exit_platform_hw();
446 err_free_input:
447 input_free_device(input_dev);
448 return err;
449}
450
451static int tsc2007_remove(struct i2c_client *client)
452{
453 const struct tsc2007_platform_data *pdata = dev_get_platdata(&client->dev);
454 struct tsc2007 *ts = i2c_get_clientdata(client);
455
456 free_irq(ts->irq, ts);
457
458 if (pdata && pdata->exit_platform_hw)
459 pdata->exit_platform_hw();
460
461 input_unregister_device(ts->input);
462 kfree(ts);
463 465
464 return 0; 466 return 0;
465} 467}
@@ -487,7 +489,6 @@ static struct i2c_driver tsc2007_driver = {
487 }, 489 },
488 .id_table = tsc2007_idtable, 490 .id_table = tsc2007_idtable,
489 .probe = tsc2007_probe, 491 .probe = tsc2007_probe,
490 .remove = tsc2007_remove,
491}; 492};
492 493
493module_i2c_driver(tsc2007_driver); 494module_i2c_driver(tsc2007_driver);