diff options
author | Dan Carpenter <error27@gmail.com> | 2010-11-11 08:59:20 +0100 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-11-11 09:12:13 +0100 |
commit | 17d01f28e160f8a9c9ecda2e335d0047ec9e7388 (patch) | |
tree | e5fbbdafb5dd9484fede27340582e24abdf3f5f1 /drivers/input | |
parent | Input: acecad - fix a memory leak in usb_acecad_probe error path (diff) | |
download | linux-17d01f28e160f8a9c9ecda2e335d0047ec9e7388.tar.xz linux-17d01f28e160f8a9c9ecda2e335d0047ec9e7388.zip |
Input: pcf8574_keypad - fix error handling in pcf8574_kp_probe
It is not allowed to call input_free_device() after calling
input_unregister_device() because input devices are refcounted and
unregister will free the device if we were holding he last referenc.
The preferred style in input/ is to make input_register_device() the
last function in the probe which can fail. That way we don't need to
call input_unregister_device().
Also do not need to call input_set_drvdata() as nothing in the driver
uses the data.
Signed-off-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/misc/pcf8574_keypad.c | 23 |
1 files changed, 10 insertions, 13 deletions
diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c index 4b42ffc0532a..d1583aea1721 100644 --- a/drivers/input/misc/pcf8574_keypad.c +++ b/drivers/input/misc/pcf8574_keypad.c @@ -127,14 +127,6 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2 idev->id.product = 0x0001; idev->id.version = 0x0100; - input_set_drvdata(idev, lp); - - ret = input_register_device(idev); - if (ret) { - dev_err(&client->dev, "input_register_device() failed\n"); - goto fail_register; - } - lp->laststate = read_state(lp); ret = request_threaded_irq(client->irq, NULL, pcf8574_kp_irq_handler, @@ -142,16 +134,21 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2 DRV_NAME, lp); if (ret) { dev_err(&client->dev, "IRQ %d is not free\n", client->irq); - goto fail_irq; + goto fail_free_device; + } + + ret = input_register_device(idev); + if (ret) { + dev_err(&client->dev, "input_register_device() failed\n"); + goto fail_free_irq; } i2c_set_clientdata(client, lp); return 0; - fail_irq: - input_unregister_device(idev); - fail_register: - input_set_drvdata(idev, NULL); + fail_free_irq: + free_irq(client->irq, lp); + fail_free_device: input_free_device(idev); fail_allocate: kfree(lp); |