Input: synaptics-rmi4 - fix error handling in SPI transport driver
authorGuenter Roeck <linux@roeck-us.net>
Tue, 4 Oct 2016 18:48:55 +0000 (11:48 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Tue, 4 Oct 2016 18:52:23 +0000 (11:52 -0700)
Instantiating the rmi4 SPI transport driver without an interrupt assigned
caused the driver to fail to load, but it does not clean up its transport
device registration. Result may be a crash at a later time, for example
when rebooting the system.

Fixes: 8d99758dee31 ("Input: synaptics-rmi4 - add SPI transport driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/rmi4/rmi_spi.c

index 55bd1b34970c90a62005264e257ed774280cfd22..4ebef607e2141ad574fe161366308c08e101dc68 100644 (file)
@@ -396,6 +396,13 @@ static inline int rmi_spi_of_probe(struct spi_device *spi,
 }
 #endif
 
+static void rmi_spi_unregister_transport(void *data)
+{
+       struct rmi_spi_xport *rmi_spi = data;
+
+       rmi_unregister_transport_device(&rmi_spi->xport);
+}
+
 static int rmi_spi_probe(struct spi_device *spi)
 {
        struct rmi_spi_xport *rmi_spi;
@@ -464,6 +471,11 @@ static int rmi_spi_probe(struct spi_device *spi)
                dev_err(&spi->dev, "failed to register transport.\n");
                return retval;
        }
+       retval = devm_add_action_or_reset(&spi->dev,
+                                         rmi_spi_unregister_transport,
+                                         rmi_spi);
+       if (retval)
+               return retval;
 
        retval = rmi_spi_init_irq(spi);
        if (retval < 0)
@@ -473,15 +485,6 @@ static int rmi_spi_probe(struct spi_device *spi)
        return 0;
 }
 
-static int rmi_spi_remove(struct spi_device *spi)
-{
-       struct rmi_spi_xport *rmi_spi = spi_get_drvdata(spi);
-
-       rmi_unregister_transport_device(&rmi_spi->xport);
-
-       return 0;
-}
-
 #ifdef CONFIG_PM_SLEEP
 static int rmi_spi_suspend(struct device *dev)
 {
@@ -577,7 +580,6 @@ static struct spi_driver rmi_spi_driver = {
        },
        .id_table       = rmi_id,
        .probe          = rmi_spi_probe,
-       .remove         = rmi_spi_remove,
 };
 
 module_spi_driver(rmi_spi_driver);