#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))
int auto_conversion_period;
struct dentry *dentry;
+ bool is_shutdown;
+ struct mutex lock;
};
/*
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:
}
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;
}
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,
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