diff options
Diffstat (limited to 'drivers/iio')
82 files changed, 944 insertions, 749 deletions
diff --git a/drivers/iio/accel/adis16201.c b/drivers/iio/accel/adis16201.c index 59a24c355a1a..f955cccb3e77 100644 --- a/drivers/iio/accel/adis16201.c +++ b/drivers/iio/accel/adis16201.c @@ -281,34 +281,15 @@ static int adis16201_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) return ret; ret = adis_initial_startup(st); if (ret) - goto error_cleanup_buffer_trigger; - - ret = iio_device_register(indio_dev); - if (ret < 0) - goto error_cleanup_buffer_trigger; - - return 0; - -error_cleanup_buffer_trigger: - adis_cleanup_buffer_and_trigger(st, indio_dev); - return ret; -} - -static int adis16201_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - adis_cleanup_buffer_and_trigger(st, indio_dev); + return ret; - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static struct spi_driver adis16201_driver = { @@ -316,7 +297,6 @@ static struct spi_driver adis16201_driver = { .name = "adis16201", }, .probe = adis16201_probe, - .remove = adis16201_remove, }; module_spi_driver(adis16201_driver); diff --git a/drivers/iio/accel/adis16209.c b/drivers/iio/accel/adis16209.c index 3d5538e2f76e..4a841aec6268 100644 --- a/drivers/iio/accel/adis16209.c +++ b/drivers/iio/accel/adis16209.c @@ -291,33 +291,15 @@ static int adis16209_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) return ret; ret = adis_initial_startup(st); if (ret) - goto error_cleanup_buffer_trigger; - ret = iio_device_register(indio_dev); - if (ret) - goto error_cleanup_buffer_trigger; - - return 0; - -error_cleanup_buffer_trigger: - adis_cleanup_buffer_and_trigger(st, indio_dev); - return ret; -} - -static int adis16209_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - adis_cleanup_buffer_and_trigger(st, indio_dev); + return ret; - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static struct spi_driver adis16209_driver = { @@ -325,7 +307,6 @@ static struct spi_driver adis16209_driver = { .name = "adis16209", }, .probe = adis16209_probe, - .remove = adis16209_remove, }; module_spi_driver(adis16209_driver); diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 448faed001fd..6b74c2b04c15 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -673,7 +673,7 @@ static const struct iio_chan_spec_ext_info bma023_ext_info[] = { }; static const struct iio_chan_spec_ext_info bma180_ext_info[] = { - IIO_ENUM("power_mode", true, &bma180_power_mode_enum), + IIO_ENUM("power_mode", IIO_SHARED_BY_TYPE, &bma180_power_mode_enum), IIO_ENUM_AVAILABLE("power_mode", &bma180_power_mode_enum), IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bma180_accel_get_mount_matrix), { } diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 406a4b00fb1f..91ae90514aff 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -863,7 +863,7 @@ config RN5T618_ADC config ROCKCHIP_SARADC tristate "Rockchip SARADC driver" - depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST) + depends on ARCH_ROCKCHIP || COMPILE_TEST depends on RESET_CONTROLLER select IIO_BUFFER select IIO_TRIGGERED_BUFFER diff --git a/drivers/iio/adc/ad7949.c b/drivers/iio/adc/ad7949.c index d9566a83988a..5d597e5050f6 100644 --- a/drivers/iio/adc/ad7949.c +++ b/drivers/iio/adc/ad7949.c @@ -39,7 +39,7 @@ static const struct ad7949_adc_spec ad7949_adc_spec[] = { * struct ad7949_adc_chip - AD ADC chip * @lock: protects write sequences * @vref: regulator generating Vref - * @iio_dev: reference to iio structure + * @indio_dev: reference to iio structure * @spi: reference to spi structure * @resolution: resolution of the chip * @cfg: copy of the configuration register diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c index 1e8fd83b9bc2..f068256cfca9 100644 --- a/drivers/iio/adc/ad9467.c +++ b/drivers/iio/adc/ad9467.c @@ -324,7 +324,7 @@ static int ad9467_setup(struct ad9467_state *st, unsigned int chip_id) AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT; return 0; default: - return -EINVAL; + return -ENODEV; } } @@ -390,7 +390,8 @@ static int ad9467_probe(struct spi_device *spi) id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID); if (id != conv->chip_info->id) { - dev_err(&spi->dev, "Unrecognized CHIP_ID 0x%X\n", id); + dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n", + id, conv->chip_info->id); return -ENODEV; } diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index 20477b249f2a..99f4404e9fd1 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -138,6 +138,16 @@ struct exynos_adc { bool read_ts; u32 ts_x; u32 ts_y; + + /* + * Lock to protect from potential concurrent access to the + * completion callback during a manual conversion. For this driver + * a wait-callback is used to wait for the conversion result, + * so in the meantime no other read request (or conversion start) + * must be performed, otherwise it would interfere with the + * current conversion result. + */ + struct mutex lock; }; struct exynos_adc_data { @@ -542,7 +552,7 @@ static int exynos_read_raw(struct iio_dev *indio_dev, return -EINVAL; } - mutex_lock(&indio_dev->mlock); + mutex_lock(&info->lock); reinit_completion(&info->completion); /* Select the channel to be used and Trigger conversion */ @@ -562,7 +572,7 @@ static int exynos_read_raw(struct iio_dev *indio_dev, ret = IIO_VAL_INT; } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return ret; } @@ -573,7 +583,7 @@ static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y) unsigned long timeout; int ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&info->lock); info->read_ts = true; reinit_completion(&info->completion); @@ -598,7 +608,7 @@ static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y) } info->read_ts = false; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return ret; } @@ -868,6 +878,8 @@ static int exynos_adc_probe(struct platform_device *pdev) indio_dev->channels = exynos_adc_iio_channels; indio_dev->num_channels = info->data->num_channels; + mutex_init(&info->lock); + ret = request_irq(info->irq, exynos_adc_isr, 0, dev_name(&pdev->dev), info); if (ret < 0) { diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c index 8cb51cf7a816..ab5139e911c3 100644 --- a/drivers/iio/adc/fsl-imx25-gcq.c +++ b/drivers/iio/adc/fsl-imx25-gcq.c @@ -40,6 +40,15 @@ struct mx25_gcq_priv { int irq; struct regulator *vref[4]; u32 channel_vref_mv[MX25_NUM_CFGS]; + /* + * Lock to protect the device state during a potential concurrent + * read access from userspace. Reading a raw value requires a sequence + * of register writes, then a wait for a completion callback, + * and finally a register read, during which userspace could issue + * another read request. This lock protects a read access from + * ocurring before another one has finished. + */ + struct mutex lock; }; #define MX25_CQG_CHAN(chan, id) {\ @@ -137,9 +146,9 @@ static int mx25_gcq_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); + mutex_lock(&priv->lock); ret = mx25_gcq_get_raw_value(&indio_dev->dev, chan, priv, val); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&priv->lock); return ret; case IIO_CHAN_INFO_SCALE: @@ -314,6 +323,8 @@ static int mx25_gcq_probe(struct platform_device *pdev) return PTR_ERR(priv->regs); } + mutex_init(&priv->lock); + init_completion(&priv->completed); ret = mx25_gcq_setup_cfgs(pdev, priv); diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c index 95bd187de1cb..e03988698755 100644 --- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c @@ -1150,16 +1150,13 @@ static const struct of_device_id meson_sar_adc_of_match[] = { { .compatible = "amlogic,meson8-saradc", .data = &meson_sar_adc_meson8_data, - }, - { + }, { .compatible = "amlogic,meson8b-saradc", .data = &meson_sar_adc_meson8b_data, - }, - { + }, { .compatible = "amlogic,meson8m2-saradc", .data = &meson_sar_adc_meson8m2_data, - }, - { + }, { .compatible = "amlogic,meson-gxbb-saradc", .data = &meson_sar_adc_gxbb_data, }, { @@ -1175,7 +1172,7 @@ static const struct of_device_id meson_sar_adc_of_match[] = { .compatible = "amlogic,meson-g12a-saradc", .data = &meson_sar_adc_g12a_data, }, - {}, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, meson_sar_adc_of_match); diff --git a/drivers/iio/adc/palmas_gpadc.c b/drivers/iio/adc/palmas_gpadc.c index 1ca6570be66a..889b88768b63 100644 --- a/drivers/iio/adc/palmas_gpadc.c +++ b/drivers/iio/adc/palmas_gpadc.c @@ -834,18 +834,7 @@ static struct platform_driver palmas_gpadc_driver = { .of_match_table = of_palmas_gpadc_match_tbl, }, }; - -static int __init palmas_gpadc_init(void) -{ - return platform_driver_register(&palmas_gpadc_driver); -} -module_init(palmas_gpadc_init); - -static void __exit palmas_gpadc_exit(void) -{ - platform_driver_unregister(&palmas_gpadc_driver); -} -module_exit(palmas_gpadc_exit); +module_platform_driver(palmas_gpadc_driver); MODULE_DESCRIPTION("palmas GPADC driver"); MODULE_AUTHOR("Pradeep Goudagunta<pgoudagunta@nvidia.com>"); diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c index 3f27b4817a42..6a0338d33bd8 100644 --- a/drivers/iio/adc/stm32-adc-core.c +++ b/drivers/iio/adc/stm32-adc-core.c @@ -595,7 +595,7 @@ static int stm32_adc_core_switches_probe(struct device *dev, if (IS_ERR(priv->booster)) { ret = PTR_ERR(priv->booster); if (ret != -ENODEV) - dev_err_probe(dev, ret, "can't get booster\n"); + return dev_err_probe(dev, ret, "can't get booster\n"); priv->booster = NULL; } diff --git a/drivers/iio/adc/ti-adc0832.c b/drivers/iio/adc/ti-adc0832.c index c7a085dce1f4..0261b3cfc92b 100644 --- a/drivers/iio/adc/ti-adc0832.c +++ b/drivers/iio/adc/ti-adc0832.c @@ -29,6 +29,12 @@ struct adc0832 { struct regulator *reg; struct mutex lock; u8 mux_bits; + /* + * Max size needed: 16x 1 byte ADC data + 8 bytes timestamp + * May be shorter if not all channels are enabled subject + * to the timestamp remaining 8 byte aligned. + */ + u8 data[24] __aligned(8); u8 tx_buf[2] ____cacheline_aligned; u8 rx_buf[2]; @@ -200,7 +206,6 @@ static irqreturn_t adc0832_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adc0832 *adc = iio_priv(indio_dev); - u8 data[24] = { }; /* 16x 1 byte ADC data + 8 bytes timestamp */ int scan_index; int i = 0; @@ -218,10 +223,10 @@ static irqreturn_t adc0832_trigger_handler(int irq, void *p) goto out; } - data[i] = ret; + adc->data[i] = ret; i++; } - iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_push_to_buffers_with_timestamp(indio_dev, adc->data, iio_get_time_ns(indio_dev)); out: mutex_unlock(&adc->lock); diff --git a/drivers/iio/adc/ti-adc12138.c b/drivers/iio/adc/ti-adc12138.c index e485719cd2c4..fcd5d39dd03e 100644 --- a/drivers/iio/adc/ti-adc12138.c +++ b/drivers/iio/adc/ti-adc12138.c @@ -47,6 +47,12 @@ struct adc12138 { struct completion complete; /* The number of cclk periods for the S/H's acquisition time */ unsigned int acquisition_time; + /* + * Maximum size needed: 16x 2 bytes ADC data + 8 bytes timestamp. + * Less may be need if not all channels are enabled, as long as + * the 8 byte alignment of the timestamp is maintained. + */ + __be16 data[20] __aligned(8); u8 tx_buf[2] ____cacheline_aligned; u8 rx_buf[2]; @@ -329,7 +335,6 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adc12138 *adc = iio_priv(indio_dev); - __be16 data[20] = { }; /* 16x 2 bytes ADC data + 8 bytes timestamp */ __be16 trash; int ret; int scan_index; @@ -345,7 +350,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) reinit_completion(&adc->complete); ret = adc12138_start_and_read_conv(adc, scan_chan, - i ? &data[i - 1] : &trash); + i ? &adc->data[i - 1] : &trash); if (ret) { dev_warn(&adc->spi->dev, "failed to start conversion\n"); @@ -362,7 +367,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) } if (i) { - ret = adc12138_read_conv_data(adc, &data[i - 1]); + ret = adc12138_read_conv_data(adc, &adc->data[i - 1]); if (ret) { dev_warn(&adc->spi->dev, "failed to get conversion data\n"); @@ -370,7 +375,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) } } - iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_push_to_buffers_with_timestamp(indio_dev, adc->data, iio_get_time_ns(indio_dev)); out: mutex_unlock(&adc->lock); diff --git a/drivers/iio/chemical/ams-iaq-core.c b/drivers/iio/chemical/ams-iaq-core.c index 8c1b64fd424a..97be3669c554 100644 --- a/drivers/iio/chemical/ams-iaq-core.c +++ b/drivers/iio/chemical/ams-iaq-core.c @@ -7,6 +7,7 @@ */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/mutex.h> #include <linux/init.h> #include <linux/i2c.h> @@ -177,7 +178,7 @@ MODULE_DEVICE_TABLE(of, ams_iaqcore_dt_ids); static struct i2c_driver ams_iaqcore_driver = { .driver = { .name = "ams-iaq-core", - .of_match_table = of_match_ptr(ams_iaqcore_dt_ids), + .of_match_table = ams_iaqcore_dt_ids, }, .probe = ams_iaqcore_probe, |