summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Cameron <jic23@kernel.org>2016-10-08 19:39:15 +0300
committerJonathan Cameron <jic23@kernel.org>2016-10-23 21:34:05 +0300
commit9a4936dc89a34e002946a6c08b330918ec6afab8 (patch)
tree86406aa54107c8c071946dbc2247ff48db6bad21
parent7ab9fa0052878c331670ef5a2a1ef09ec3111dea (diff)
downloadlinux-9a4936dc89a34e002946a6c08b330918ec6afab8.tar.xz
staging:iio:accel:sca3000 Tidy up probe order to avoid a race.
Previously the device was exposed to userspace and in kernel consumers before the interrupts had been configured. As nothing stopped them being enabled in the interval this could cause unhandled interrupts. Signed-off-by: Jonathan Cameron <jic23@kernel.org> Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
-rw-r--r--drivers/staging/iio/accel/sca3000.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/drivers/staging/iio/accel/sca3000.c b/drivers/staging/iio/accel/sca3000.c
index 586c120dbf41..6ffd608a2b36 100644
--- a/drivers/staging/iio/accel/sca3000.c
+++ b/drivers/staging/iio/accel/sca3000.c
@@ -1440,9 +1440,6 @@ static int sca3000_probe(struct spi_device *spi)
indio_dev->modes = INDIO_DIRECT_MODE;
sca3000_configure_ring(indio_dev);
- ret = iio_device_register(indio_dev);
- if (ret < 0)
- return ret;
if (spi->irq) {
ret = request_threaded_irq(spi->irq,
@@ -1452,7 +1449,7 @@ static int sca3000_probe(struct spi_device *spi)
"sca3000",
indio_dev);
if (ret)
- goto error_unregister_dev;
+ return ret;
}
indio_dev->setup_ops = &sca3000_ring_setup_ops;
ret = sca3000_clean_setup(st);
@@ -1463,13 +1460,12 @@ static int sca3000_probe(struct spi_device *spi)
if (ret)
goto error_free_irq;
- return 0;
+ return iio_device_register(indio_dev);
error_free_irq:
if (spi->irq)
free_irq(spi->irq, indio_dev);
-error_unregister_dev:
- iio_device_unregister(indio_dev);
+
return ret;
}
@@ -1496,11 +1492,13 @@ static int sca3000_remove(struct spi_device *spi)
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct sca3000_state *st = iio_priv(indio_dev);
+ iio_device_unregister(indio_dev);
+
/* Must ensure no interrupts can be generated after this! */
sca3000_stop_all_interrupts(st);
if (spi->irq)
free_irq(spi->irq, indio_dev);
- iio_device_unregister(indio_dev);
+
sca3000_unconfigure_ring(indio_dev);
return 0;