diff options
author | Sang-Hun Lee <sanlee@nvidia.com> | 2014-05-17 18:34:48 -0700 |
---|---|---|
committer | Riham Haidar <rhaidar@nvidia.com> | 2014-05-23 22:36:00 -0700 |
commit | 830db980d3a6e76ffcde8d588a8b6ef487e26283 (patch) | |
tree | a03c01f3c874c5327ddadc59cf380cb3bf4c0e86 /drivers/staging | |
parent | 87839a56e4a1537e4af0bfdd6eeb26389fc3d7c2 (diff) |
iio: adc: palmas: disallow access post-shutdown
- Once the shutdown has been called, any access to
i2c needs to be disallowed to avoid a race
Bug 1510778
Change-Id: I93cc1ec4cdadfe2084b6aa5a8bc9d2b6cf56e879
Signed-off-by: Sang-Hun Lee <sanlee@nvidia.com>
Reviewed-on: http://git-master/r/411189
Reviewed-by: Riham Haidar <rhaidar@nvidia.com>
Tested-by: Riham Haidar <rhaidar@nvidia.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/iio/adc/palmas_gpadc.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/staging/iio/adc/palmas_gpadc.c b/drivers/staging/iio/adc/palmas_gpadc.c index eec770fd1459..dc2e03fd2a48 100644 --- a/drivers/staging/iio/adc/palmas_gpadc.c +++ b/drivers/staging/iio/adc/palmas_gpadc.c @@ -37,6 +37,7 @@ #include <linux/iio/iio.h> #include <linux/iio/machine.h> #include <linux/iio/driver.h> +#include <linux/mutex.h> #define MOD_NAME "palmas-gpadc" #define ADC_CONVERTION_TIMEOUT (msecs_to_jiffies(5000)) @@ -103,6 +104,8 @@ struct palmas_gpadc { int auto_conversion_period; struct dentry *dentry; + bool is_shutdown; + struct mutex lock; }; /* @@ -586,8 +589,13 @@ static int palmas_gpadc_read_raw(struct iio_dev *indio_dev, if (adc_chan > PALMAS_ADC_CH_MAX) return -EINVAL; - mutex_lock(&indio_dev->mlock); + mutex_lock(&adc->lock); + if (adc->is_shutdown) { + mutex_unlock(&adc->lock); + return -EINVAL; + } + mutex_lock(&indio_dev->mlock); switch (mask) { case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_PROCESSED: @@ -664,11 +672,13 @@ static int palmas_gpadc_read_raw(struct iio_dev *indio_dev, } mutex_unlock(&indio_dev->mlock); + mutex_unlock(&adc->lock); return ret; out: palmas_gpadc_read_done(adc, adc_chan); mutex_unlock(&indio_dev->mlock); + mutex_unlock(&adc->lock); return ret; } @@ -1055,6 +1065,9 @@ static int palmas_gpadc_probe(struct platform_device *pdev) init_completion(&adc->conv_completion); dev_set_drvdata(&pdev->dev, iodev); + adc->is_shutdown = false; + mutex_init(&adc->lock); + adc->auto_conversion_period = gpadc_pdata->auto_conversion_period_ms; adc->irq = palmas_irq_get_virq(adc->palmas, PALMAS_GPADC_EOC_SW_IRQ); ret = request_threaded_irq(adc->irq, NULL, @@ -1207,8 +1220,11 @@ static void palmas_gpadc_shutdown(struct platform_device *pdev) struct iio_dev *iodev = dev_get_drvdata(&pdev->dev); struct palmas_gpadc *adc = iio_priv(iodev); + mutex_lock(&adc->lock); + adc->is_shutdown = true; if (adc->auto_conv0_enable || adc->auto_conv1_enable) palmas_gpadc_auto_conv_reset(adc); + mutex_unlock(&adc->lock); } #ifdef CONFIG_PM_SLEEP |