input: touch: raydium: fix panic when touch panel not attached
Xiaohui Tao [Tue, 29 Jan 2013 23:02:01 +0000 (15:02 -0800)]
This issue is because the upper hal level is calling the driver
to suspend even when the driver is not installed. Cleanup the
resources when the driver fails to install.

Bug 1207093

Change-Id: I732a9748a5a3f9e084a29fe111da2b7563455a79
Signed-off-by: Xiaohui Tao <xtao@nvidia.com>
Reviewed-on: http://git-master/r/191411
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Shridhar Rasal <srasal@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Reviewed-by: Robert Collins <rcollins@nvidia.com>

drivers/input/touchscreen/rm31080a_ts.c

index fe45ed5..df45916 100644 (file)
@@ -2477,13 +2477,13 @@ static int __devinit rm31080_spi_probe(struct spi_device *spi)
 
        if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) {
                dev_err(&spi->dev, "SPI CLK %d Hz?\n", spi->max_speed_hz);
-               goto err_unregister_notifier;
+               goto err_free;
        }
 
        rm31080_init_ts_structure_part();
 
        if (!rm31080_spi_checking(0))
-               goto err_unregister_notifier;
+               goto err_free;
 
        if (misc_register(&raydium_ts_miscdev) != 0) {
                dev_err(&spi->dev, "Raydium TS: cannot register miscdev\n");
@@ -2504,11 +2504,18 @@ static int __devinit rm31080_spi_probe(struct spi_device *spi)
 
        return 0;
 
-err_unregister_notifier:
-       regulator_unregister_notifier(ts->regulator_3v3, &ts->nb_3v3);
-       regulator_unregister_notifier(ts->regulator_1v8, &ts->nb_1v8);
-       regulator_disable(ts->regulator_3v3);
-       regulator_disable(ts->regulator_1v8);
+err_free:
+       sysfs_remove_group(&ts->dev->kobj, &rm_ts_attr_group);
+       free_irq(ts->irq, ts);
+       input_unregister_device(ts->input);
+       if (ts->regulator_3v3 && ts->regulator_1v8) {
+               regulator_unregister_notifier(ts->regulator_3v3, &ts->nb_3v3);
+               regulator_unregister_notifier(ts->regulator_1v8, &ts->nb_1v8);
+               regulator_disable(ts->regulator_3v3);
+               regulator_disable(ts->regulator_1v8);
+       }
+       kfree(ts);
+       spi_set_drvdata(spi, NULL);
        return -EINVAL;
 }