From dbf20809d6e0072ad189c937761d58bf98a47b43 Mon Sep 17 00:00:00 2001 From: Nuno Sa Date: Tue, 27 Apr 2021 10:54:52 +0200 Subject: iio: adis: add burst_max_speed_hz variable Typically, in burst mode, the device cannot operate at it's full spi speed. Hence, the spi transfers for burst mode have to take this into account. With this change we avoid a potential race with the spi core as drivers were 'hacking' the device 'max_speed_hz' directly in the trigger handler. Reviewed-by: Alexandru Ardelean Signed-off-by: Nuno Sa Link: https://lore.kernel.org/r/20210427085454.30616-5-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- include/linux/iio/imu/adis.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h index f9b728d490b1..cf49997d5903 100644 --- a/include/linux/iio/imu/adis.h +++ b/include/linux/iio/imu/adis.h @@ -55,6 +55,7 @@ struct adis_timeout { * this should be the minimum size supported by the device. * @burst_max_len: Holds the maximum burst size when the device supports * more than one burst mode with different sizes + * @burst_max_speed_hz: Maximum spi speed that can be used in burst mode */ struct adis_data { unsigned int read_delay; @@ -83,6 +84,7 @@ struct adis_data { unsigned int burst_reg_cmd; unsigned int burst_len; unsigned int burst_max_len; + unsigned int burst_max_speed_hz; }; /** -- cgit v1.2.3-70-g09d2 From 15ea2878bfb255099092634d28f31177f237ccd7 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 26 Apr 2021 18:49:03 +0100 Subject: iio: core: move @id from struct iio_dev to struct iio_dev_opaque Continuing from Alexandru Ardelean's introduction of the split between driver modifiable fields and those that should only be set by the core. This could have been done in two steps to make the actual move after introducing iio_device_id() but there seemed limited point to that given how mechanical the majority of the patch is. Includes fixup from Alex for missing mxs-lradc-adc conversion. Signed-off-by: Jonathan Cameron Reviewed-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20210426174911.397061-2-jic23@kernel.org --- drivers/iio/accel/adxl372.c | 4 ++-- drivers/iio/accel/bma180.c | 2 +- drivers/iio/accel/bmc150-accel-core.c | 4 ++-- drivers/iio/accel/kxcjk-1013.c | 4 ++-- drivers/iio/accel/mma8452.c | 2 +- drivers/iio/accel/mxc4005.c | 2 +- drivers/iio/accel/stk8312.c | 2 +- drivers/iio/accel/stk8ba50.c | 2 +- drivers/iio/adc/ad7606.c | 3 ++- drivers/iio/adc/ad7766.c | 3 ++- drivers/iio/adc/ad7768-1.c | 3 ++- drivers/iio/adc/ad_sigma_delta.c | 2 +- drivers/iio/adc/at91-sama5d2_adc.c | 2 +- drivers/iio/adc/at91_adc.c | 4 ++-- drivers/iio/adc/dln2-adc.c | 3 ++- drivers/iio/adc/ina2xx-adc.c | 3 ++- drivers/iio/adc/mxs-lradc-adc.c | 2 +- drivers/iio/adc/ti-ads131e08.c | 2 +- drivers/iio/adc/xilinx-xadc-core.c | 2 +- drivers/iio/buffer/industrialio-triggered-buffer.c | 2 +- drivers/iio/chemical/atlas-sensor.c | 2 +- drivers/iio/chemical/ccs811.c | 2 +- drivers/iio/chemical/scd30_core.c | 3 ++- .../iio/common/hid-sensors/hid-sensor-trigger.c | 2 +- drivers/iio/gyro/adxrs290.c | 2 +- drivers/iio/gyro/bmg160_core.c | 4 ++-- drivers/iio/gyro/fxas21002c_core.c | 2 +- drivers/iio/gyro/itg3200_buffer.c | 2 +- drivers/iio/gyro/mpu3050-core.c | 2 +- drivers/iio/health/afe4403.c | 2 +- drivers/iio/health/afe4404.c | 2 +- drivers/iio/imu/adis_trigger.c | 3 ++- drivers/iio/imu/bmi160/bmi160_core.c | 3 ++- drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c | 2 +- drivers/iio/imu/kmx61.c | 2 +- drivers/iio/industrialio-core.c | 24 +++++++++++++++++----- drivers/iio/industrialio-triggered-event.c | 2 +- drivers/iio/light/acpi-als.c | 3 ++- drivers/iio/light/rpr0521.c | 2 +- drivers/iio/light/si1145.c | 2 +- drivers/iio/light/vcnl4000.c | 3 ++- drivers/iio/light/vcnl4035.c | 2 +- drivers/iio/magnetometer/bmc150_magn.c | 2 +- drivers/iio/magnetometer/rm3100-core.c | 2 +- drivers/iio/potentiostat/lmp91000.c | 3 ++- drivers/iio/pressure/zpa2326.c | 3 ++- drivers/iio/proximity/as3935.c | 3 ++- drivers/iio/proximity/sx9310.c | 2 +- drivers/iio/proximity/sx9500.c | 2 +- include/linux/iio/iio-opaque.h | 2 ++ include/linux/iio/iio.h | 4 ++-- 51 files changed, 89 insertions(+), 60 deletions(-) (limited to 'include/linux') diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c index 9c9a896a872a..fc9592407717 100644 --- a/drivers/iio/accel/adxl372.c +++ b/drivers/iio/accel/adxl372.c @@ -1223,14 +1223,14 @@ int adxl372_probe(struct device *dev, struct regmap *regmap, st->dready_trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (st->dready_trig == NULL) return -ENOMEM; st->peak_datardy_trig = devm_iio_trigger_alloc(dev, "%s-dev%d-peak", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!st->peak_datardy_trig) return -ENOMEM; diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index b8a7469cdae4..68d91a70de03 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -1045,7 +1045,7 @@ static int bma180_probe(struct i2c_client *client, if (client->irq > 0) { data->trig = iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!data->trig) { ret = -ENOMEM; goto err_chip_disable; diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 04d85ce34e9f..62a164a7b852 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -1470,9 +1470,9 @@ static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev, struct bmc150_accel_trigger *t = &data->triggers[i]; t->indio_trig = devm_iio_trigger_alloc(dev, - bmc150_accel_triggers[i].name, + bmc150_accel_triggers[i].name, indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!t->indio_trig) { ret = -ENOMEM; break; diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index ff724bc17a45..283e6a3feffc 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -1404,7 +1404,7 @@ static int kxcjk1013_probe(struct i2c_client *client, data->dready_trig = devm_iio_trigger_alloc(&client->dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!data->dready_trig) { ret = -ENOMEM; goto err_poweroff; @@ -1413,7 +1413,7 @@ static int kxcjk1013_probe(struct i2c_client *client, data->motion_trig = devm_iio_trigger_alloc(&client->dev, "%s-any-motion-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!data->motion_trig) { ret = -ENOMEM; goto err_poweroff; diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 4d307dfb9169..464a6bfe6746 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -1461,7 +1461,7 @@ static int mma8452_trigger_setup(struct iio_dev *indio_dev) trig = devm_iio_trigger_alloc(&data->client->dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!trig) return -ENOMEM; diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c index fb3cbaa62bd8..98c7f5f59011 100644 --- a/drivers/iio/accel/mxc4005.c +++ b/drivers/iio/accel/mxc4005.c @@ -433,7 +433,7 @@ static int mxc4005_probe(struct i2c_client *client, data->dready_trig = devm_iio_trigger_alloc(&client->dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!data->dready_trig) return -ENOMEM; diff --git a/drivers/iio/accel/stk8312.c b/drivers/iio/accel/stk8312.c index 60aecfa9fd92..aeab108c457d 100644 --- a/drivers/iio/accel/stk8312.c +++ b/drivers/iio/accel/stk8312.c @@ -552,7 +552,7 @@ static int stk8312_probe(struct i2c_client *client, data->dready_trig = devm_iio_trigger_alloc(&client->dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!data->dready_trig) { ret = -ENOMEM; goto err_power_off; diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c index 7cf9cb7e8666..3e7cf23be7e1 100644 --- a/drivers/iio/accel/stk8ba50.c +++ b/drivers/iio/accel/stk8ba50.c @@ -448,7 +448,7 @@ static int stk8ba50_probe(struct i2c_client *client, data->dready_trig = devm_iio_trigger_alloc(&client->dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!data->dready_trig) { ret = -ENOMEM; goto err_power_off; diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c index 0af0bb4d5a7f..0a60ecc69d38 100644 --- a/drivers/iio/adc/ad7606.c +++ b/drivers/iio/adc/ad7606.c @@ -663,7 +663,8 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, } st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", - indio_dev->name, indio_dev->id); + indio_dev->name, + iio_device_id(indio_dev)); if (!st->trig) return -ENOMEM; diff --git a/drivers/iio/adc/ad7766.c b/drivers/iio/adc/ad7766.c index 1e41759f3ee5..236a455aaa18 100644 --- a/drivers/iio/adc/ad7766.c +++ b/drivers/iio/adc/ad7766.c @@ -248,7 +248,8 @@ static int ad7766_probe(struct spi_device *spi) if (spi->irq > 0) { ad7766->trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d", - indio_dev->name, indio_dev->id); + indio_dev->name, + iio_device_id(indio_dev)); if (!ad7766->trig) return -ENOMEM; diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c index c945f1349623..41752777e96c 100644 --- a/drivers/iio/adc/ad7768-1.c +++ b/drivers/iio/adc/ad7768-1.c @@ -626,7 +626,8 @@ static int ad7768_probe(struct spi_device *spi) } st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d", - indio_dev->name, indio_dev->id); + indio_dev->name, + iio_device_id(indio_dev)); if (!st->trig) return -ENOMEM; diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index e777ec718973..69b979331ccd 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -477,7 +477,7 @@ static int ad_sd_probe_trigger(struct iio_dev *indio_dev) sigma_delta->trig = iio_trigger_alloc(&sigma_delta->spi->dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (sigma_delta->trig == NULL) { ret = -ENOMEM; goto error_ret; diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index a7826f097b95..6e8c28675947 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -997,7 +997,7 @@ static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *indio, int ret; trig = devm_iio_trigger_alloc(&indio->dev, "%s-dev%d-%s", indio->name, - indio->id, trigger_name); + iio_device_id(indio), trigger_name); if (!trig) return NULL; diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 0b5f0c91d0d7..5a7d3a3a5fa8 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -547,7 +547,7 @@ static int at91_adc_get_trigger_value_by_name(struct iio_dev *idev, char *name = kasprintf(GFP_KERNEL, "%s-dev%d-%s", idev->name, - idev->id, + iio_device_id(idev), triggers[i].name); if (!name) return -ENOMEM; @@ -626,7 +626,7 @@ static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *idev, int ret; trig = iio_trigger_alloc(idev->dev.parent, "%s-dev%d-%s", idev->name, - idev->id, trigger->name); + iio_device_id(idev), trigger->name); if (trig == NULL) return NULL; diff --git a/drivers/iio/adc/dln2-adc.c b/drivers/iio/adc/dln2-adc.c index 0d53ef18e045..16407664182c 100644 --- a/drivers/iio/adc/dln2-adc.c +++ b/drivers/iio/adc/dln2-adc.c @@ -649,7 +649,8 @@ static int dln2_adc_probe(struct platform_device *pdev) indio_dev->setup_ops = &dln2_adc_buffer_setup_ops; dln2->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", - indio_dev->name, indio_dev->id); + indio_dev->name, + iio_device_id(indio_dev)); if (!dln2->trig) { dev_err(dev, "failed to allocate trigger\n"); return -ENOMEM; diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 2ae54258b221..a4b2ff9e0dd5 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -843,7 +843,8 @@ static int ina2xx_buffer_enable(struct iio_dev *indio_dev) chip->allow_async_readout); task = kthread_create(ina2xx_capture_thread, (void *)indio_dev, - "%s:%d-%uus", indio_dev->name, indio_dev->id, + "%s:%d-%uus", indio_dev->name, + iio_device_id(indio_dev), sampling_us); if (IS_ERR(task)) return PTR_ERR(task); diff --git a/drivers/iio/adc/mxs-lradc-adc.c b/drivers/iio/adc/mxs-lradc-adc.c index 30e29f44ebd2..1d99170d3328 100644 --- a/drivers/iio/adc/mxs-lradc-adc.c +++ b/drivers/iio/adc/mxs-lradc-adc.c @@ -455,7 +455,7 @@ static int mxs_lradc_adc_trigger_init(struct iio_dev *iio) struct mxs_lradc_adc *adc = iio_priv(iio); trig = devm_iio_trigger_alloc(&iio->dev, "%s-dev%i", iio->name, - iio->id); + iio_device_id(iio)); if (!trig) return -ENOMEM; diff --git a/drivers/iio/adc/ti-ads131e08.c b/drivers/iio/adc/ti-ads131e08.c index 2c20dbed8ada..0c2025a22575 100644 --- a/drivers/iio/adc/ti-ads131e08.c +++ b/drivers/iio/adc/ti-ads131e08.c @@ -849,7 +849,7 @@ static int ads131e08_probe(struct spi_device *spi) } st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d", - indio_dev->name, indio_dev->id); + indio_dev->name, iio_device_id(indio_dev)); if (!st->trig) { dev_err(&spi->dev, "failed to allocate IIO trigger\n"); return -ENOMEM; diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c index 6914c1900ed0..198d2916266d 100644 --- a/drivers/iio/adc/xilinx-xadc-core.c +++ b/drivers/iio/adc/xilinx-xadc-core.c @@ -743,7 +743,7 @@ static struct iio_trigger *xadc_alloc_trigger(struct iio_dev *indio_dev, int ret; trig = devm_iio_trigger_alloc(dev, "%s%d-%s", indio_dev->name, - indio_dev->id, name); + iio_device_id(indio_dev), name); if (trig == NULL) return ERR_PTR(-ENOMEM); diff --git a/drivers/iio/buffer/industrialio-triggered-buffer.c b/drivers/iio/buffer/industrialio-triggered-buffer.c index ebb4520ac291..f77c4538141e 100644 --- a/drivers/iio/buffer/industrialio-triggered-buffer.c +++ b/drivers/iio/buffer/industrialio-triggered-buffer.c @@ -56,7 +56,7 @@ int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev, indio_dev, "%s_consumer%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (indio_dev->pollfunc == NULL) { ret = -ENOMEM; goto error_kfifo_free; diff --git a/drivers/iio/chemical/atlas-sensor.c b/drivers/iio/chemical/atlas-sensor.c index 56ba6c82b501..d10f921b233a 100644 --- a/drivers/iio/chemical/atlas-sensor.c +++ b/drivers/iio/chemical/atlas-sensor.c @@ -640,7 +640,7 @@ static int atlas_probe(struct i2c_client *client, indio_dev->modes = INDIO_BUFFER_SOFTWARE | INDIO_DIRECT_MODE; trig = devm_iio_trigger_alloc(&client->dev, "%s-dev%d", - indio_dev->name, indio_dev->id); + indio_dev->name, iio_device_id(indio_dev)); if (!trig) return -ENOMEM; diff --git a/drivers/iio/chemical/ccs811.c b/drivers/iio/chemical/ccs811.c index 886e96496dbf..847194fa1e46 100644 --- a/drivers/iio/chemical/ccs811.c +++ b/drivers/iio/chemical/ccs811.c @@ -491,7 +491,7 @@ static int ccs811_probe(struct i2c_client *client, data->drdy_trig = devm_iio_trigger_alloc(&client->dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!data->drdy_trig) { ret = -ENOMEM; goto err_poweroff; diff --git a/drivers/iio/chemical/scd30_core.c b/drivers/iio/chemical/scd30_core.c index d89f117dd0ef..9fe6bbe9ee04 100644 --- a/drivers/iio/chemical/scd30_core.c +++ b/drivers/iio/chemical/scd30_core.c @@ -640,7 +640,8 @@ static int scd30_setup_trigger(struct iio_dev *indio_dev) struct iio_trigger *trig; int ret; - trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, indio_dev->id); + trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, + iio_device_id(indio_dev)); if (!trig) { dev_err(dev, "failed to allocate trigger\n"); return -ENOMEM; diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c index 95ddccb44f1c..5a7b3e253e58 100644 --- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c @@ -256,7 +256,7 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name, } trig = iio_trigger_alloc(indio_dev->dev.parent, - "%s-dev%d", name, indio_dev->id); + "%s-dev%d", name, iio_device_id(indio_dev)); if (trig == NULL) { dev_err(&indio_dev->dev, "Trigger Allocate Failed\n"); ret = -ENOMEM; diff --git a/drivers/iio/gyro/adxrs290.c b/drivers/iio/gyro/adxrs290.c index cec5e1f17c22..3e0734ddafe3 100644 --- a/drivers/iio/gyro/adxrs290.c +++ b/drivers/iio/gyro/adxrs290.c @@ -589,7 +589,7 @@ static int adxrs290_probe_trigger(struct iio_dev *indio_dev) st->dready_trig = devm_iio_trigger_alloc(&st->spi->dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!st->dready_trig) return -ENOMEM; diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c index b11ebd9bb7a4..26a9ed5770c6 100644 --- a/drivers/iio/gyro/bmg160_core.c +++ b/drivers/iio/gyro/bmg160_core.c @@ -1137,14 +1137,14 @@ int bmg160_core_probe(struct device *dev, struct regmap *regmap, int irq, data->dready_trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!data->dready_trig) return -ENOMEM; data->motion_trig = devm_iio_trigger_alloc(dev, "%s-any-motion-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!data->motion_trig) return -ENOMEM; diff --git a/drivers/iio/gyro/fxas21002c_core.c b/drivers/iio/gyro/fxas21002c_core.c index 1a20c6b88e7d..5af7b48ff01a 100644 --- a/drivers/iio/gyro/fxas21002c_core.c +++ b/drivers/iio/gyro/fxas21002c_core.c @@ -852,7 +852,7 @@ static int fxas21002c_trigger_probe(struct fxas21002c_data *data) data->dready_trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!data->dready_trig) return -ENOMEM; diff --git a/drivers/iio/gyro/itg3200_buffer.c b/drivers/iio/gyro/itg3200_buffer.c index af0aaa146f0c..04dd6a7969ea 100644 --- a/drivers/iio/gyro/itg3200_buffer.c +++ b/drivers/iio/gyro/itg3200_buffer.c @@ -114,7 +114,7 @@ int itg3200_probe_trigger(struct iio_dev *indio_dev) struct itg3200 *st = iio_priv(indio_dev); st->trig = iio_trigger_alloc(&st->i2c->dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!st->trig) return -ENOMEM; diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c index f17a93519535..2b930c7f4d86 100644 --- a/drivers/iio/gyro/mpu3050-core.c +++ b/drivers/iio/gyro/mpu3050-core.c @@ -1058,7 +1058,7 @@ static int mpu3050_trigger_probe(struct iio_dev *indio_dev, int irq) mpu3050->trig = devm_iio_trigger_alloc(&indio_dev->dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!mpu3050->trig) return -ENOMEM; diff --git a/drivers/iio/health/afe4403.c b/drivers/iio/health/afe4403.c index 1fa8d51d5080..d4921385aaf7 100644 --- a/drivers/iio/health/afe4403.c +++ b/drivers/iio/health/afe4403.c @@ -521,7 +521,7 @@ static int afe4403_probe(struct spi_device *spi) afe->trig = devm_iio_trigger_alloc(afe->dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!afe->trig) { dev_err(afe->dev, "Unable to allocate IIO trigger\n"); ret = -ENOMEM; diff --git a/drivers/iio/health/afe4404.c b/drivers/iio/health/afe4404.c index e1476bf79fe2..d8a27dfe074a 100644 --- a/drivers/iio/health/afe4404.c +++ b/drivers/iio/health/afe4404.c @@ -528,7 +528,7 @@ static int afe4404_probe(struct i2c_client *client, afe->trig = devm_iio_trigger_alloc(afe->dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!afe->trig) { dev_err(afe->dev, "Unable to allocate IIO trigger\n"); ret = -ENOMEM; diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c index fa5540fabacc..48eedc29b28a 100644 --- a/drivers/iio/imu/adis_trigger.c +++ b/drivers/iio/imu/adis_trigger.c @@ -62,7 +62,8 @@ int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) int ret; adis->trig = devm_iio_trigger_alloc(&adis->spi->dev, "%s-dev%d", - indio_dev->name, indio_dev->id); + indio_dev->name, + iio_device_id(indio_dev)); if (!adis->trig) return -ENOMEM; diff --git a/drivers/iio/imu/bmi160/bmi160_core.c b/drivers/iio/imu/bmi160/bmi160_core.c index 290b5ef83f77..b63bd7e5e5e5 100644 --- a/drivers/iio/imu/bmi160/bmi160_core.c +++ b/drivers/iio/imu/bmi160/bmi160_core.c @@ -785,7 +785,8 @@ int bmi160_probe_trigger(struct iio_dev *indio_dev, int irq, u32 irq_type) int ret; data->trig = devm_iio_trigger_alloc(&indio_dev->dev, "%s-dev%d", - indio_dev->name, indio_dev->id); + indio_dev->name, + iio_device_id(indio_dev)); if (data->trig == NULL) return -ENOMEM; diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c index de8ed1446d60..e21ba778595a 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c @@ -238,7 +238,7 @@ int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev, int irq_type) st->trig = devm_iio_trigger_alloc(&indio_dev->dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!st->trig) return -ENOMEM; diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c index fc5a60fcfec0..d3e06ce99c1e 100644 --- a/drivers/iio/imu/kmx61.c +++ b/drivers/iio/imu/kmx61.c @@ -1264,7 +1264,7 @@ static struct iio_trigger *kmx61_trigger_setup(struct kmx61_data *data, "%s-%s-dev%d", indio_dev->name, tag, - indio_dev->id); + iio_device_id(indio_dev)); if (!trig) return ERR_PTR(-ENOMEM); diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 3fdcf2d4997a..ec21341c6322 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -169,6 +169,20 @@ static const char * const iio_chan_info_postfix[] = { [IIO_CHAN_INFO_THERMOCOUPLE_TYPE] = "thermocouple_type", [IIO_CHAN_INFO_CALIBAMBIENT] = "calibambient", }; +/** + * iio_device_id() - query the unique ID for the device + * @indio_dev: Device structure whose ID is being queried + * + * The IIO device ID is a unique index used for example for the naming + * of the character device /dev/iio\:device[ID] + */ +int iio_device_id(struct iio_dev *indio_dev) +{ + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); + + return iio_dev_opaque->id; +} +EXPORT_SYMBOL_GPL(iio_device_id); /** * iio_sysfs_match_string_with_gaps - matches given string in an array with gaps @@ -1588,7 +1602,7 @@ static void iio_dev_release(struct device *device) iio_device_detach_buffers(indio_dev); - ida_simple_remove(&iio_ida, indio_dev->id); + ida_simple_remove(&iio_ida, iio_dev_opaque->id); kfree(iio_dev_opaque); } @@ -1631,14 +1645,14 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) mutex_init(&indio_dev->info_exist_lock); INIT_LIST_HEAD(&iio_dev_opaque->channel_attr_list); - indio_dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); - if (indio_dev->id < 0) { + iio_dev_opaque->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); + if (iio_dev_opaque->id < 0) { /* cannot use a dev_err as the name isn't available */ pr_err("failed to get device id\n"); kfree(iio_dev_opaque); return NULL; } - dev_set_name(&indio_dev->dev, "iio:device%d", indio_dev->id); + dev_set_name(&indio_dev->dev, "iio:device%d", iio_dev_opaque->id); INIT_LIST_HEAD(&iio_dev_opaque->buffer_list); INIT_LIST_HEAD(&iio_dev_opaque->ioctl_handlers); @@ -1891,7 +1905,7 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) cdev_init(&indio_dev->chrdev, &iio_event_fileops); if (iio_dev_opaque->attached_buffers_cnt || iio_dev_opaque->event_interface) { - indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id); + indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), iio_dev_opaque->id); indio_dev->chrdev.owner = this_mod; } diff --git a/drivers/iio/industrialio-triggered-event.c b/drivers/iio/industrialio-triggered-event.c index 53da9ab17a62..4bedc65c9fe3 100644 --- a/drivers/iio/industrialio-triggered-event.c +++ b/drivers/iio/industrialio-triggered-event.c @@ -37,7 +37,7 @@ int iio_triggered_event_setup(struct iio_dev *indio_dev, indio_dev, "%s_consumer%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (indio_dev->pollfunc_event == NULL) return -ENOMEM; diff --git a/drivers/iio/light/acpi-als.c b/drivers/iio/light/acpi-als.c index 0a6ab5761eec..e1ff6f524f4b 100644 --- a/drivers/iio/light/acpi-als.c +++ b/drivers/iio/light/acpi-als.c @@ -204,7 +204,8 @@ static int acpi_als_add(struct acpi_device *device) indio_dev->channels = acpi_als_channels; indio_dev->num_channels = ARRAY_SIZE(acpi_als_channels); - als->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, indio_dev->id); + als->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, + iio_device_id(indio_dev)); if (!als->trig) return -ENOMEM; diff --git a/drivers/iio/light/rpr0521.c b/drivers/iio/light/rpr0521.c index 033578f444e4..7e332de0e6a5 100644 --- a/drivers/iio/light/rpr0521.c +++ b/drivers/iio/light/rpr0521.c @@ -985,7 +985,7 @@ static int rpr0521_probe(struct i2c_client *client, /* Trigger0 producer setup */ data->drdy_trigger0 = devm_iio_trigger_alloc( indio_dev->dev.parent, - "%s-dev%d", indio_dev->name, indio_dev->id); + "%s-dev%d", indio_dev->name, iio_device_id(indio_dev)); if (!data->drdy_trigger0) { ret = -ENOMEM; goto err_pm_disable; diff --git a/drivers/iio/light/si1145.c b/drivers/iio/light/si1145.c index 9b5c99823943..3fb52402fcc3 100644 --- a/drivers/iio/light/si1145.c +++ b/drivers/iio/light/si1145.c @@ -1243,7 +1243,7 @@ static int si1145_probe_trigger(struct iio_dev *indio_dev) int ret; trig = devm_iio_trigger_alloc(&client->dev, - "%s-dev%d", indio_dev->name, indio_dev->id); + "%s-dev%d", indio_dev->name, iio_device_id(indio_dev)); if (!trig) return -ENOMEM; diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index 2f7916f95689..4a61865d01cd 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -998,7 +998,8 @@ static int vcnl4010_probe_trigger(struct iio_dev *indio_dev) struct iio_trigger *trigger; trigger = devm_iio_trigger_alloc(&client->dev, "%s-dev%d", - indio_dev->name, indio_dev->id); + indio_dev->name, + iio_device_id(indio_dev)); if (!trigger) return -ENOMEM; diff --git a/drivers/iio/light/vcnl4035.c b/drivers/iio/light/vcnl4035.c index ae87740d9cef..691a54b763e1 100644 --- a/drivers/iio/light/vcnl4035.c +++ b/drivers/iio/light/vcnl4035.c @@ -507,7 +507,7 @@ static int vcnl4035_probe_trigger(struct iio_dev *indio_dev) data->drdy_trigger0 = devm_iio_trigger_alloc( indio_dev->dev.parent, - "%s-dev%d", indio_dev->name, indio_dev->id); + "%s-dev%d", indio_dev->name, iio_device_id(indio_dev)); if (!data->drdy_trigger0) return -ENOMEM; diff --git a/drivers/iio/magnetometer/bmc150_magn.c b/drivers/iio/magnetometer/bmc150_magn.c index 00f9766bad5c..d75b437a43f2 100644 --- a/drivers/iio/magnetometer/bmc150_magn.c +++ b/drivers/iio/magnetometer/bmc150_magn.c @@ -915,7 +915,7 @@ int bmc150_magn_probe(struct device *dev, struct regmap *regmap, data->dready_trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!data->dready_trig) { ret = -ENOMEM; dev_err(dev, "iio trigger alloc failed\n"); diff --git a/drivers/iio/magnetometer/rm3100-core.c b/drivers/iio/magnetometer/rm3100-core.c index dd811da9cb6d..4df5887fd04c 100644 --- a/drivers/iio/magnetometer/rm3100-core.c +++ b/drivers/iio/magnetometer/rm3100-core.c @@ -575,7 +575,7 @@ int rm3100_common_probe(struct device *dev, struct regmap *regmap, int irq) data->drdy_trig = devm_iio_trigger_alloc(dev, "%s-drdy%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!data->drdy_trig) return -ENOMEM; diff --git a/drivers/iio/potentiostat/lmp91000.c b/drivers/iio/potentiostat/lmp91000.c index 8a9c576616ee..1948e2d22c27 100644 --- a/drivers/iio/potentiostat/lmp91000.c +++ b/drivers/iio/potentiostat/lmp91000.c @@ -323,7 +323,8 @@ static int lmp91000_probe(struct i2c_client *client, } data->trig = devm_iio_trigger_alloc(dev, "%s-mux%d", - indio_dev->name, indio_dev->id); + indio_dev->name, + iio_device_id(indio_dev)); if (!data->trig) { dev_err(dev, "cannot allocate iio trigger.\n"); return -ENOMEM; diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c index a93411216aee..89295c90f801 100644 --- a/drivers/iio/pressure/zpa2326.c +++ b/drivers/iio/pressure/zpa2326.c @@ -1408,7 +1408,8 @@ static int zpa2326_init_managed_trigger(struct device *parent, return 0; trigger = devm_iio_trigger_alloc(parent, "%s-dev%d", - indio_dev->name, indio_dev->id); + indio_dev->name, + iio_device_id(indio_dev)); if (!trigger) return -ENOMEM; diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c index edc4a35ae66d..dc20fe81232c 100644 --- a/drivers/iio/proximity/as3935.c +++ b/drivers/iio/proximity/as3935.c @@ -404,7 +404,8 @@ static int as3935_probe(struct spi_device *spi) indio_dev->info = &as3935_info; trig = devm_iio_trigger_alloc(dev, "%s-dev%d", - indio_dev->name, indio_dev->id); + indio_dev->name, + iio_device_id(indio_dev)); if (!trig) return -ENOMEM; diff --git a/drivers/iio/proximity/sx9310.c b/drivers/iio/proximity/sx9310.c index 327ebb7ddbb9..175f3b7c61d7 100644 --- a/drivers/iio/proximity/sx9310.c +++ b/drivers/iio/proximity/sx9310.c @@ -1473,7 +1473,7 @@ static int sx9310_probe(struct i2c_client *client) data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, - indio_dev->id); + iio_device_id(indio_dev)); if (!data->trig) return -ENOMEM; diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c index a87f4a8e4327..3e4ddb2e8c2b 100644 --- a/drivers/iio/proximity/sx9500.c +++ b/drivers/iio/proximity/sx9500.c @@ -946,7 +946,7 @@ static int sx9500_probe(struct i2c_client *client, return ret; data->trig = devm_iio_trigger_alloc(&client->dev, - "%s-dev%d", indio_dev->name, indio_dev->id); + "%s-dev%d", indio_dev->name, iio_device_id(indio_dev)); if (!data->trig) return -ENOMEM; diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h index 32addd5e790e..e66b029d99de 100644 --- a/include/linux/iio/iio-opaque.h +++ b/include/linux/iio/iio-opaque.h @@ -6,6 +6,7 @@ /** * struct iio_dev_opaque - industrial I/O device opaque information * @indio_dev: public industrial I/O device information + * @id: used to identify device internally * @event_interface: event chrdevs associated with interrupt lines * @attached_buffers: array of buffers statically attached by the driver * @attached_buffers_cnt: number of buffers in the array of statically attached buffers @@ -26,6 +27,7 @@ */ struct iio_dev_opaque { struct iio_dev indio_dev; + int id; struct iio_event_interface *event_interface; struct iio_buffer **attached_buffers; unsigned int attached_buffers_cnt; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index f2d65e2e88b6..569861d5887a 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -488,7 +488,6 @@ struct iio_buffer_setup_ops { /** * struct iio_dev - industrial I/O device - * @id: [INTERN] used to identify device internally * @driver_module: [INTERN] used to make it harder to undercut users * @modes: [DRIVER] operating modes supported by device * @currentmode: [DRIVER] current operating mode @@ -523,7 +522,6 @@ struct iio_buffer_setup_ops { * **MUST** be accessed **ONLY** via iio_priv() helper */ struct iio_dev { - int id; struct module *driver_module; int modes; @@ -559,6 +557,8 @@ struct iio_dev { void *priv; }; +int iio_device_id(struct iio_dev *indio_dev); + const struct iio_chan_spec *iio_find_channel_from_si(struct iio_dev *indio_dev, int si); /** -- cgit v1.2.3-70-g09d2 From e5333ed09e0f8ece3cbb37912c17cf9880ee3fb0 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 26 Apr 2021 18:49:04 +0100 Subject: iio: avoid shadowing of variable name in to_iio_dev_opaque() indio_dev was both the macro input parameter and the field name in this macro. That causes trouble if the instance of struct iio_dev passed in is not called indio_dev. Whilst a fix of sorts, no need to backport as it seems we never hit this previously due to some very consistent naming in IIO. Signed-off-by: Jonathan Cameron Reviewed-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20210426174911.397061-3-jic23@kernel.org --- include/linux/iio/iio-opaque.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h index e66b029d99de..f876e3aede2c 100644 --- a/include/linux/iio/iio-opaque.h +++ b/include/linux/iio/iio-opaque.h @@ -48,7 +48,7 @@ struct iio_dev_opaque { #endif }; -#define to_iio_dev_opaque(indio_dev) \ - container_of(indio_dev, struct iio_dev_opaque, indio_dev) +#define to_iio_dev_opaque(_indio_dev) \ + container_of((_indio_dev), struct iio_dev_opaque, indio_dev) #endif -- cgit v1.2.3-70-g09d2 From 6eaf9f6a2738789dedb1e962096f61aaddd81464 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 26 Apr 2021 18:49:05 +0100 Subject: iio: core: move @driver_module from struct iio_dev to struct iio_dev_opaque Continuing move to hide internal elements from drivers, move this structure element over. It's only accessed from iio core files so this one was straight forward and no accessor functions are needed. Signed-off-by: Jonathan Cameron Reviewed-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20210426174911.397061-4-jic23@kernel.org --- drivers/iio/industrialio-core.c | 2 +- drivers/iio/industrialio-trigger.c | 9 ++++++--- include/linux/iio/iio-opaque.h | 2 ++ include/linux/iio/iio.h | 3 --- 4 files changed, 9 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index ec21341c6322..58b35db00a81 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1858,7 +1858,7 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) if (!indio_dev->info) return -EINVAL; - indio_dev->driver_module = this_mod; + iio_dev_opaque->driver_module = this_mod; /* If the calling driver did not initialize of_node, do it here */ if (!indio_dev->dev.of_node && indio_dev->dev.parent) indio_dev->dev.of_node = indio_dev->dev.parent->of_node; diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 3236647b2c37..b489eeeb0004 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -13,6 +13,7 @@ #include #include +#include #include #include "iio_core.h" #include "iio_core_trigger.h" @@ -240,12 +241,13 @@ static void iio_trigger_put_irq(struct iio_trigger *trig, int irq) int iio_trigger_attach_poll_func(struct iio_trigger *trig, struct iio_poll_func *pf) { + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(pf->indio_dev); bool notinuse = bitmap_empty(trig->pool, CONFIG_IIO_CONSUMERS_PER_TRIGGER); int ret = 0; /* Prevent the module from being removed whilst attached to a trigger */ - __module_get(pf->indio_dev->driver_module); + __module_get(iio_dev_opaque->driver_module); /* Get irq number */ pf->irq = iio_trigger_get_irq(trig); @@ -284,13 +286,14 @@ out_free_irq: out_put_irq: iio_trigger_put_irq(trig, pf->irq); out_put_module: - module_put(pf->indio_dev->driver_module); + module_put(iio_dev_opaque->driver_module); return ret; } int iio_trigger_detach_poll_func(struct iio_trigger *trig, struct iio_poll_func *pf) { + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(pf->indio_dev); bool no_other_users = bitmap_weight(trig->pool, CONFIG_IIO_CONSUMERS_PER_TRIGGER) == 1; int ret = 0; @@ -304,7 +307,7 @@ int iio_trigger_detach_poll_func(struct iio_trigger *trig, trig->attached_own_device = false; iio_trigger_put_irq(trig, pf->irq); free_irq(pf->irq, pf); - module_put(pf->indio_dev->driver_module); + module_put(iio_dev_opaque->driver_module); return ret; } diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h index f876e3aede2c..96dd265103d0 100644 --- a/include/linux/iio/iio-opaque.h +++ b/include/linux/iio/iio-opaque.h @@ -7,6 +7,7 @@ * struct iio_dev_opaque - industrial I/O device opaque information * @indio_dev: public industrial I/O device information * @id: used to identify device internally + * @driver_module: used to make it harder to undercut users * @event_interface: event chrdevs associated with interrupt lines * @attached_buffers: array of buffers statically attached by the driver * @attached_buffers_cnt: number of buffers in the array of statically attached buffers @@ -28,6 +29,7 @@ struct iio_dev_opaque { struct iio_dev indio_dev; int id; + struct module *driver_module; struct iio_event_interface *event_interface; struct iio_buffer **attached_buffers; unsigned int attached_buffers_cnt; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 569861d5887a..9e8e1358a032 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -488,7 +488,6 @@ struct iio_buffer_setup_ops { /** * struct iio_dev - industrial I/O device - * @driver_module: [INTERN] used to make it harder to undercut users * @modes: [DRIVER] operating modes supported by device * @currentmode: [DRIVER] current operating mode * @dev: [DRIVER] device structure, should be assigned a parent @@ -522,8 +521,6 @@ struct iio_buffer_setup_ops { * **MUST** be accessed **ONLY** via iio_priv() helper */ struct iio_dev { - struct module *driver_module; - int modes; int currentmode; struct device dev; -- cgit v1.2.3-70-g09d2 From 3028e0c2af95dd476ccd71f4fc025990385168c2 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 26 Apr 2021 18:49:06 +0100 Subject: iio: core: move @trig_readonly from struct iio_dev to struct iio_dev_opaque This is only set via the iio_trig_set_immutable() call and later used by the IIO core so there is no benefit in drivers being able to access it. Signed-off-by: Jonathan Cameron Reviewed-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20210426174911.397061-5-jic23@kernel.org --- drivers/iio/industrialio-trigger.c | 10 +++++++--- include/linux/iio/iio-opaque.h | 2 ++ include/linux/iio/iio.h | 2 -- 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index b489eeeb0004..b23caa2f2aa1 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -117,14 +117,17 @@ EXPORT_SYMBOL(iio_trigger_unregister); int iio_trigger_set_immutable(struct iio_dev *indio_dev, struct iio_trigger *trig) { + struct iio_dev_opaque *iio_dev_opaque; + if (!indio_dev || !trig) return -EINVAL; + iio_dev_opaque = to_iio_dev_opaque(indio_dev); mutex_lock(&indio_dev->mlock); - WARN_ON(indio_dev->trig_readonly); + WARN_ON(iio_dev_opaque->trig_readonly); indio_dev->trig = iio_trigger_get(trig); - indio_dev->trig_readonly = true; + iio_dev_opaque->trig_readonly = true; mutex_unlock(&indio_dev->mlock); return 0; @@ -402,6 +405,7 @@ static ssize_t iio_trigger_write_current(struct device *dev, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); struct iio_trigger *oldtrig = indio_dev->trig; struct iio_trigger *trig; int ret; @@ -411,7 +415,7 @@ static ssize_t iio_trigger_write_current(struct device *dev, mutex_unlock(&indio_dev->mlock); return -EBUSY; } - if (indio_dev->trig_readonly) { + if (iio_dev_opaque->trig_readonly) { mutex_unlock(&indio_dev->mlock); return -EPERM; } diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h index 96dd265103d0..10aa97239117 100644 --- a/include/linux/iio/iio-opaque.h +++ b/include/linux/iio/iio-opaque.h @@ -8,6 +8,7 @@ * @indio_dev: public industrial I/O device information * @id: used to identify device internally * @driver_module: used to make it harder to undercut users + * @trig_readonly: mark the current trigger immutable * @event_interface: event chrdevs associated with interrupt lines * @attached_buffers: array of buffers statically attached by the driver * @attached_buffers_cnt: number of buffers in the array of statically attached buffers @@ -30,6 +31,7 @@ struct iio_dev_opaque { struct iio_dev indio_dev; int id; struct module *driver_module; + bool trig_readonly; struct iio_event_interface *event_interface; struct iio_buffer **attached_buffers; unsigned int attached_buffers_cnt; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 9e8e1358a032..672f141f74c5 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -503,7 +503,6 @@ struct iio_buffer_setup_ops { * @scan_timestamp: [INTERN] set if any buffers have requested timestamp * @scan_index_timestamp:[INTERN] cache of the index to the timestamp * @trig: [INTERN] current device trigger (buffer modes) - * @trig_readonly: [INTERN] mark the current trigger immutable * @pollfunc: [DRIVER] function run on trigger being received * @pollfunc_event: [DRIVER] function run on events trigger being received * @channels: [DRIVER] channel specification structure table @@ -535,7 +534,6 @@ struct iio_dev { bool scan_timestamp; unsigned scan_index_timestamp; struct iio_trigger *trig; - bool trig_readonly; struct iio_poll_func *pollfunc; struct iio_poll_func *pollfunc_event; -- cgit v1.2.3-70-g09d2 From 62f4f36cdfcdbb961bbbeab15e6595dd391d2205 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 26 Apr 2021 18:49:07 +0100 Subject: iio: core: move @scan_index_timestamp to struct iio_dev_opaque No reason for this cached value to be exposed to drivers so move it to the opaque structure. Signed-off-by: Jonathan Cameron Reviewed-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20210426174911.397061-6-jic23@kernel.org --- drivers/iio/industrialio-buffer.c | 7 +++++-- include/linux/iio/iio-opaque.h | 4 ++++ include/linux/iio/iio.h | 2 -- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 9a8e16c7e9af..9ecb3c58d94c 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -601,8 +601,10 @@ static unsigned int iio_storage_bytes_for_si(struct iio_dev *indio_dev, static unsigned int iio_storage_bytes_for_timestamp(struct iio_dev *indio_dev) { + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); + return iio_storage_bytes_for_si(indio_dev, - indio_dev->scan_index_timestamp); + iio_dev_opaque->scan_index_timestamp); } static int iio_compute_scan_bytes(struct iio_dev *indio_dev, @@ -1469,6 +1471,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, struct iio_dev *indio_dev, int index) { + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); struct iio_dev_attr *p; struct attribute **attr; int ret, i, attrn, scan_el_attrcount, buffer_attrcount; @@ -1495,7 +1498,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, goto error_cleanup_dynamic; scan_el_attrcount += ret; if (channels[i].type == IIO_TIMESTAMP) - indio_dev->scan_index_timestamp = + iio_dev_opaque->scan_index_timestamp = channels[i].scan_index; } if (indio_dev->masklength && buffer->scan_mask == NULL) { diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h index 10aa97239117..02038fb2d291 100644 --- a/include/linux/iio/iio-opaque.h +++ b/include/linux/iio/iio-opaque.h @@ -22,6 +22,7 @@ * @groupcounter: index of next attribute group * @legacy_scan_el_group: attribute group for legacy scan elements attribute group * @legacy_buffer_group: attribute group for legacy buffer attributes group + * @scan_index_timestamp: cache of the index to the timestamp * @debugfs_dentry: device specific debugfs dentry * @cached_reg_addr: cached register address for debugfs reads * @read_buf: read buffer to be used for the initial reg read @@ -44,6 +45,9 @@ struct iio_dev_opaque { int groupcounter; struct attribute_group legacy_scan_el_group; struct attribute_group legacy_buffer_group; + + unsigned int scan_index_timestamp; + #if defined(CONFIG_DEBUG_FS) struct dentry *debugfs_dentry; unsigned cached_reg_addr; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 672f141f74c5..cbc9e9ece0a6 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -501,7 +501,6 @@ struct iio_buffer_setup_ops { * channels * @active_scan_mask: [INTERN] union of all scan masks requested by buffers * @scan_timestamp: [INTERN] set if any buffers have requested timestamp - * @scan_index_timestamp:[INTERN] cache of the index to the timestamp * @trig: [INTERN] current device trigger (buffer modes) * @pollfunc: [DRIVER] function run on trigger being received * @pollfunc_event: [DRIVER] function run on events trigger being received @@ -532,7 +531,6 @@ struct iio_dev { unsigned masklength; const unsigned long *active_scan_mask; bool scan_timestamp; - unsigned scan_index_timestamp; struct iio_trigger *trig; struct iio_poll_func *pollfunc; struct iio_poll_func *pollfunc_event; -- cgit v1.2.3-70-g09d2 From b804e2b76ac6d5559b99588e0190ac97b5597497 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 26 Apr 2021 18:49:08 +0100 Subject: iio: core: move @info_exist_lock to struct iio_dev_opaque This lock is only of interest to the IIO core, so make it only visible there. Signed-off-by: Jonathan Cameron Reviewed-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20210426174911.397061-7-jic23@kernel.org --- drivers/iio/industrialio-buffer.c | 5 +++-- drivers/iio/industrialio-core.c | 10 ++++----- drivers/iio/inkern.c | 46 ++++++++++++++++++++++++--------------- include/linux/iio/iio-opaque.h | 2 ++ include/linux/iio/iio.h | 2 -- 5 files changed, 38 insertions(+), 27 deletions(-) (limited to 'include/linux') diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 9ecb3c58d94c..10923b40c76d 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1150,12 +1150,13 @@ int iio_update_buffers(struct iio_dev *indio_dev, struct iio_buffer *insert_buffer, struct iio_buffer *remove_buffer) { + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); int ret; if (insert_buffer == remove_buffer) return 0; - mutex_lock(&indio_dev->info_exist_lock); + mutex_lock(&iio_dev_opaque->info_exist_lock); mutex_lock(&indio_dev->mlock); if (insert_buffer && iio_buffer_is_active(insert_buffer)) @@ -1178,7 +1179,7 @@ int iio_update_buffers(struct iio_dev *indio_dev, out_unlock: mutex_unlock(&indio_dev->mlock); - mutex_unlock(&indio_dev->info_exist_lock); + mutex_unlock(&iio_dev_opaque->info_exist_lock); return ret; } diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 58b35db00a81..74bb977e2357 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1642,7 +1642,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) device_initialize(&indio_dev->dev); iio_device_set_drvdata(indio_dev, (void *)indio_dev); mutex_init(&indio_dev->mlock); - mutex_init(&indio_dev->info_exist_lock); + mutex_init(&iio_dev_opaque->info_exist_lock); INIT_LIST_HEAD(&iio_dev_opaque->channel_attr_list); iio_dev_opaque->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); @@ -1779,7 +1779,7 @@ static long iio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct iio_ioctl_handler *h; int ret = -ENODEV; - mutex_lock(&indio_dev->info_exist_lock); + mutex_lock(&iio_dev_opaque->info_exist_lock); /** * The NULL check here is required to prevent crashing when a device @@ -1799,7 +1799,7 @@ static long iio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ret = -ENODEV; out_unlock: - mutex_unlock(&indio_dev->info_exist_lock); + mutex_unlock(&iio_dev_opaque->info_exist_lock); return ret; } @@ -1938,7 +1938,7 @@ void iio_device_unregister(struct iio_dev *indio_dev) { cdev_device_del(&indio_dev->chrdev, &indio_dev->dev); - mutex_lock(&indio_dev->info_exist_lock); + mutex_lock(&iio_dev_opaque->info_exist_lock); iio_device_unregister_debugfs(indio_dev); @@ -1949,7 +1949,7 @@ void iio_device_unregister(struct iio_dev *indio_dev) iio_device_wakeup_eventset(indio_dev); iio_buffer_wakeup_poll(indio_dev); - mutex_unlock(&indio_dev->info_exist_lock); + mutex_unlock(&iio_dev_opaque->info_exist_lock); iio_buffers_free_sysfs_and_mask(indio_dev); } diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 5aa740cea661..391a3380a1d1 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -10,6 +10,7 @@ #include #include +#include #include "iio_core.h" #include #include @@ -538,9 +539,10 @@ static int iio_channel_read(struct iio_channel *chan, int *val, int *val2, int iio_read_channel_raw(struct iio_channel *chan, int *val) { + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); int ret; - mutex_lock(&chan->indio_dev->info_exist_lock); + mutex_lock(&iio_dev_opaque->info_exist_lock); if (chan->indio_dev->info == NULL) { ret = -ENODEV; goto err_unlock; @@ -548,7 +550,7 @@ int iio_read_channel_raw(struct iio_channel *chan, int *val) ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW); err_unlock: - mutex_unlock(&chan->indio_dev->info_exist_lock); + mutex_unlock(&iio_dev_opaque->info_exist_lock); return ret; } @@ -556,9 +558,10 @@ EXPORT_SYMBOL_GPL(iio_read_channel_raw); int iio_read_channel_average_raw(struct iio_channel *chan, int *val) { + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); int ret; - mutex_lock(&chan->indio_dev->info_exist_lock); + mutex_lock(&iio_dev_opaque->info_exist_lock); if (chan->indio_dev->info == NULL) { ret = -ENODEV; goto err_unlock; @@ -566,7 +569,7 @@ int iio_read_channel_average_raw(struct iio_channel *chan, int *val) ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_AVERAGE_RAW); err_unlock: - mutex_unlock(&chan->indio_dev->info_exist_lock); + mutex_unlock(&iio_dev_opaque->info_exist_lock); return ret; } @@ -631,9 +634,10 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan, int iio_convert_raw_to_processed(struct iio_channel *chan, int raw, int *processed, unsigned int scale) { + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); int ret; - mutex_lock(&chan->indio_dev->info_exist_lock); + mutex_lock(&iio_dev_opaque->info_exist_lock); if (chan->indio_dev->info == NULL) { ret = -ENODEV; goto err_unlock; @@ -642,7 +646,7 @@ int iio_convert_raw_to_processed(struct iio_channel *chan, int raw, ret = iio_convert_raw_to_processed_unlocked(chan, raw, processed, scale); err_unlock: - mutex_unlock(&chan->indio_dev->info_exist_lock); + mutex_unlock(&iio_dev_opaque->info_exist_lock); return ret; } @@ -651,9 +655,10 @@ EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed); int iio_read_channel_attribute(struct iio_channel *chan, int *val, int *val2, enum iio_chan_info_enum attribute) { + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); int ret; - mutex_lock(&chan->indio_dev->info_exist_lock); + mutex_lock(&iio_dev_opaque->info_exist_lock); if (chan->indio_dev->info == NULL) { ret = -ENODEV; goto err_unlock; @@ -661,7 +666,7 @@ int iio_read_channel_attribute(struct iio_channel *chan, int *val, int *val2, ret = iio_channel_read(chan, val, val2, attribute); err_unlock: - mutex_unlock(&chan->indio_dev->info_exist_lock); + mutex_unlock(&iio_dev_opaque->info_exist_lock); return ret; } @@ -676,9 +681,10 @@ EXPORT_SYMBOL_GPL(iio_read_channel_offset); int iio_read_channel_processed_scale(struct iio_channel *chan, int *val, unsigned int scale) { + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); int ret; - mutex_lock(&chan->indio_dev->info_exist_lock); + mutex_lock(&iio_dev_opaque->info_exist_lock); if (chan->indio_dev->info == NULL) { ret = -ENODEV; goto err_unlock; @@ -699,7 +705,7 @@ int iio_read_channel_processed_scale(struct iio_channel *chan, int *val, } err_unlock: - mutex_unlock(&chan->indio_dev->info_exist_lock); + mutex_unlock(&iio_dev_opaque->info_exist_lock); return ret; } @@ -733,9 +739,10 @@ int iio_read_avail_channel_attribute(struct iio_channel *chan, const int **vals, int *type, int *length, enum iio_chan_info_enum attribute) { + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); int ret; - mutex_lock(&chan->indio_dev->info_exist_lock); + mutex_lock(&iio_dev_opaque->info_exist_lock); if (!chan->indio_dev->info) { ret = -ENODEV; goto err_unlock; @@ -743,7 +750,7 @@ int iio_read_avail_channel_attribute(struct iio_channel *chan, ret = iio_channel_read_avail(chan, vals, type, length, attribute); err_unlock: - mutex_unlock(&chan->indio_dev->info_exist_lock); + mutex_unlock(&iio_dev_opaque->info_exist_lock); return ret; } @@ -815,10 +822,11 @@ static int iio_channel_read_max(struct iio_channel *chan, int iio_read_max_channel_raw(struct iio_channel *chan, int *val) { + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); int ret; int type; - mutex_lock(&chan->indio_dev->info_exist_lock); + mutex_lock(&iio_dev_opaque->info_exist_lock); if (!chan->indio_dev->info) { ret = -ENODEV; goto err_unlock; @@ -826,7 +834,7 @@ int iio_read_max_channel_raw(struct iio_channel *chan, int *val) ret = iio_channel_read_max(chan, val, NULL, &type, IIO_CHAN_INFO_RAW); err_unlock: - mutex_unlock(&chan->indio_dev->info_exist_lock); + mutex_unlock(&iio_dev_opaque->info_exist_lock); return ret; } @@ -834,10 +842,11 @@ EXPORT_SYMBOL_GPL(iio_read_max_channel_raw); int iio_get_channel_type(struct iio_channel *chan, enum iio_chan_type *type) { + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); int ret = 0; /* Need to verify underlying driver has not gone away */ - mutex_lock(&chan->indio_dev->info_exist_lock); + mutex_lock(&iio_dev_opaque->info_exist_lock); if (chan->indio_dev->info == NULL) { ret = -ENODEV; goto err_unlock; @@ -845,7 +854,7 @@ int iio_get_channel_type(struct iio_channel *chan, enum iio_chan_type *type) *type = chan->channel->type; err_unlock: - mutex_unlock(&chan->indio_dev->info_exist_lock); + mutex_unlock(&iio_dev_opaque->info_exist_lock); return ret; } @@ -861,9 +870,10 @@ static int iio_channel_write(struct iio_channel *chan, int val, int val2, int iio_write_channel_attribute(struct iio_channel *chan, int val, int val2, enum iio_chan_info_enum attribute) { + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev); int ret; - mutex_lock(&chan->indio_dev->info_exist_lock); + mutex_lock(&iio_dev_opaque->info_exist_lock); if (chan->indio_dev->info == NULL) { ret = -ENODEV; goto err_unlock; @@ -871,7 +881,7 @@ int iio_write_channel_attribute(struct iio_channel *chan, int val, int val2, ret = iio_channel_write(chan, val, val2, attribute); err_unlock: - mutex_unlock(&chan->indio_dev->info_exist_lock); + mutex_unlock(&iio_dev_opaque->info_exist_lock); return ret; } diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h index 02038fb2d291..538b4b5ef1a9 100644 --- a/include/linux/iio/iio-opaque.h +++ b/include/linux/iio/iio-opaque.h @@ -8,6 +8,7 @@ * @indio_dev: public industrial I/O device information * @id: used to identify device internally * @driver_module: used to make it harder to undercut users + * @info_exist_lock: lock to prevent use during removal * @trig_readonly: mark the current trigger immutable * @event_interface: event chrdevs associated with interrupt lines * @attached_buffers: array of buffers statically attached by the driver @@ -32,6 +33,7 @@ struct iio_dev_opaque { struct iio_dev indio_dev; int id; struct module *driver_module; + struct mutex info_exist_lock; bool trig_readonly; struct iio_event_interface *event_interface; struct iio_buffer **attached_buffers; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index cbc9e9ece0a6..a12bbd8b1e74 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -510,7 +510,6 @@ struct iio_buffer_setup_ops { * @label: [DRIVER] unique name to identify which device this is * @info: [DRIVER] callbacks and constant info from driver * @clock_id: [INTERN] timestamping clock posix identifier - * @info_exist_lock: [INTERN] lock to prevent use during removal * @setup_ops: [DRIVER] callbacks to call before and after buffer * enable/disable * @chrdev: [INTERN] associated character device @@ -542,7 +541,6 @@ struct iio_dev { const char *label; const struct iio_info *info; clockid_t clock_id; - struct mutex info_exist_lock; const struct iio_buffer_setup_ops *setup_ops; struct cdev chrdev; -- cgit v1.2.3-70-g09d2 From 396f7234856956eb29f009da6e5d846f29f87ebd Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 26 Apr 2021 18:49:09 +0100 Subject: iio: core: move @chrdev from struct iio_dev to struct iio_dev_opaque No reason for this to be exposed to the drivers, so lets move it to the opaque structure. Signed-off-by: Jonathan Cameron Reviewed-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20210426174911.397061-8-jic23@kernel.org --- drivers/iio/industrialio-core.c | 22 +++++++++++++--------- include/linux/iio/iio-opaque.h | 2 ++ include/linux/iio/iio.h | 2 -- 3 files changed, 15 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 74bb977e2357..0aba0a0085eb 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1715,8 +1715,9 @@ EXPORT_SYMBOL_GPL(devm_iio_device_alloc); **/ static int iio_chrdev_open(struct inode *inode, struct file *filp) { - struct iio_dev *indio_dev = container_of(inode->i_cdev, - struct iio_dev, chrdev); + struct iio_dev_opaque *iio_dev_opaque = + container_of(inode->i_cdev, struct iio_dev_opaque, chrdev); + struct iio_dev *indio_dev = &iio_dev_opaque->indio_dev; struct iio_dev_buffer_pair *ib; if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags)) @@ -1749,8 +1750,9 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp) static int iio_chrdev_release(struct inode *inode, struct file *filp) { struct iio_dev_buffer_pair *ib = filp->private_data; - struct iio_dev *indio_dev = container_of(inode->i_cdev, - struct iio_dev, chrdev); + struct iio_dev_opaque *iio_dev_opaque = + container_of(inode->i_cdev, struct iio_dev_opaque, chrdev); + struct iio_dev *indio_dev = &iio_dev_opaque->indio_dev; kfree(ib); clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags); iio_device_put(indio_dev); @@ -1900,19 +1902,19 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) indio_dev->setup_ops = &noop_ring_setup_ops; if (iio_dev_opaque->attached_buffers_cnt) - cdev_init(&indio_dev->chrdev, &iio_buffer_fileops); + cdev_init(&iio_dev_opaque->chrdev, &iio_buffer_fileops); else if (iio_dev_opaque->event_interface) - cdev_init(&indio_dev->chrdev, &iio_event_fileops); + cdev_init(&iio_dev_opaque->chrdev, &iio_event_fileops); if (iio_dev_opaque->attached_buffers_cnt || iio_dev_opaque->event_interface) { indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), iio_dev_opaque->id); - indio_dev->chrdev.owner = this_mod; + iio_dev_opaque->chrdev.owner = this_mod; } /* assign device groups now; they should be all registered now */ indio_dev->dev.groups = iio_dev_opaque->groups; - ret = cdev_device_add(&indio_dev->chrdev, &indio_dev->dev); + ret = cdev_device_add(&iio_dev_opaque->chrdev, &indio_dev->dev); if (ret < 0) goto error_unreg_eventset; @@ -1936,7 +1938,9 @@ EXPORT_SYMBOL(__iio_device_register); **/ void iio_device_unregister(struct iio_dev *indio_dev) { - cdev_device_del(&indio_dev->chrdev, &indio_dev->dev); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); + + cdev_device_del(&iio_dev_opaque->chrdev, &indio_dev->dev); mutex_lock(&iio_dev_opaque->info_exist_lock); diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h index 538b4b5ef1a9..2f8ef5d15a66 100644 --- a/include/linux/iio/iio-opaque.h +++ b/include/linux/iio/iio-opaque.h @@ -24,6 +24,7 @@ * @legacy_scan_el_group: attribute group for legacy scan elements attribute group * @legacy_buffer_group: attribute group for legacy buffer attributes group * @scan_index_timestamp: cache of the index to the timestamp + * @chrdev: associated character device * @debugfs_dentry: device specific debugfs dentry * @cached_reg_addr: cached register address for debugfs reads * @read_buf: read buffer to be used for the initial reg read @@ -49,6 +50,7 @@ struct iio_dev_opaque { struct attribute_group legacy_buffer_group; unsigned int scan_index_timestamp; + struct cdev chrdev; #if defined(CONFIG_DEBUG_FS) struct dentry *debugfs_dentry; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index a12bbd8b1e74..586e2dc4fbf3 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -512,7 +512,6 @@ struct iio_buffer_setup_ops { * @clock_id: [INTERN] timestamping clock posix identifier * @setup_ops: [DRIVER] callbacks to call before and after buffer * enable/disable - * @chrdev: [INTERN] associated character device * @flags: [INTERN] file ops related flags including busy flag. * @priv: [DRIVER] reference to driver's private information * **MUST** be accessed **ONLY** via iio_priv() helper @@ -542,7 +541,6 @@ struct iio_dev { const struct iio_info *info; clockid_t clock_id; const struct iio_buffer_setup_ops *setup_ops; - struct cdev chrdev; unsigned long flags; void *priv; -- cgit v1.2.3-70-g09d2 From 8b1c82cb849f8f7c758891099f2128b8fbc05744 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 26 Apr 2021 18:49:10 +0100 Subject: iio: core: move @flags from struct iio_dev to struct iio_dev_opaque No reason any driver should ever need access to this field, so hide it. Signed-off-by: Jonathan Cameron Reviewed-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20210426174911.397061-9-jic23@kernel.org --- drivers/iio/industrialio-core.c | 6 +++--- include/linux/iio/iio-opaque.h | 2 ++ include/linux/iio/iio.h | 2 -- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 0aba0a0085eb..29ff7668297e 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1720,7 +1720,7 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp) struct iio_dev *indio_dev = &iio_dev_opaque->indio_dev; struct iio_dev_buffer_pair *ib; - if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags)) + if (test_and_set_bit(IIO_BUSY_BIT_POS, &iio_dev_opaque->flags)) return -EBUSY; iio_device_get(indio_dev); @@ -1728,7 +1728,7 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp) ib = kmalloc(sizeof(*ib), GFP_KERNEL); if (!ib) { iio_device_put(indio_dev); - clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags); + clear_bit(IIO_BUSY_BIT_POS, &iio_dev_opaque->flags); return -ENOMEM; } @@ -1754,7 +1754,7 @@ static int iio_chrdev_release(struct inode *inode, struct file *filp) container_of(inode->i_cdev, struct iio_dev_opaque, chrdev); struct iio_dev *indio_dev = &iio_dev_opaque->indio_dev; kfree(ib); - clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags); + clear_bit(IIO_BUSY_BIT_POS, &iio_dev_opaque->flags); iio_device_put(indio_dev); return 0; diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h index 2f8ef5d15a66..d7c3036861ac 100644 --- a/include/linux/iio/iio-opaque.h +++ b/include/linux/iio/iio-opaque.h @@ -25,6 +25,7 @@ * @legacy_buffer_group: attribute group for legacy buffer attributes group * @scan_index_timestamp: cache of the index to the timestamp * @chrdev: associated character device + * @flags: file ops related flags including busy flag. * @debugfs_dentry: device specific debugfs dentry * @cached_reg_addr: cached register address for debugfs reads * @read_buf: read buffer to be used for the initial reg read @@ -51,6 +52,7 @@ struct iio_dev_opaque { unsigned int scan_index_timestamp; struct cdev chrdev; + unsigned long flags; #if defined(CONFIG_DEBUG_FS) struct dentry *debugfs_dentry; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 586e2dc4fbf3..ed0537015eee 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -512,7 +512,6 @@ struct iio_buffer_setup_ops { * @clock_id: [INTERN] timestamping clock posix identifier * @setup_ops: [DRIVER] callbacks to call before and after buffer * enable/disable - * @flags: [INTERN] file ops related flags including busy flag. * @priv: [DRIVER] reference to driver's private information * **MUST** be accessed **ONLY** via iio_priv() helper */ @@ -542,7 +541,6 @@ struct iio_dev { clockid_t clock_id; const struct iio_buffer_setup_ops *setup_ops; - unsigned long flags; void *priv; }; -- cgit v1.2.3-70-g09d2 From 62a486c46d61bc684967fc3f83eed15dde49cf9b Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 26 Apr 2021 18:49:11 +0100 Subject: iio: core: move @clock_id from struct iio_dev to struct iio_dev_opaque There is already an acessor function used to access it, making this move straight forward. Signed-off-by: Jonathan Cameron Reviewed-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20210426174911.397061-10-jic23@kernel.org --- drivers/iio/industrialio-core.c | 14 +++++++++++++- include/linux/iio/iio-opaque.h | 2 ++ include/linux/iio/iio.h | 12 +----------- 3 files changed, 16 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 29ff7668297e..bfa20a346f71 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -271,13 +271,25 @@ int iio_device_set_clock(struct iio_dev *indio_dev, clockid_t clock_id) mutex_unlock(&indio_dev->mlock); return -EBUSY; } - indio_dev->clock_id = clock_id; + iio_dev_opaque->clock_id = clock_id; mutex_unlock(&indio_dev->mlock); return 0; } EXPORT_SYMBOL(iio_device_set_clock); +/** + * iio_device_get_clock() - Retrieve current timestamping clock for the device + * @indio_dev: IIO device structure containing the device + */ +clockid_t iio_device_get_clock(const struct iio_dev *indio_dev) +{ + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); + + return iio_dev_opaque->clock_id; +} +EXPORT_SYMBOL(iio_device_get_clock); + /** * iio_get_time_ns() - utility function to get a time stamp for events etc * @indio_dev: device diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h index d7c3036861ac..c9504e9da571 100644 --- a/include/linux/iio/iio-opaque.h +++ b/include/linux/iio/iio-opaque.h @@ -24,6 +24,7 @@ * @legacy_scan_el_group: attribute group for legacy scan elements attribute group * @legacy_buffer_group: attribute group for legacy buffer attributes group * @scan_index_timestamp: cache of the index to the timestamp + * @clock_id: timestamping clock posix identifier * @chrdev: associated character device * @flags: file ops related flags including busy flag. * @debugfs_dentry: device specific debugfs dentry @@ -51,6 +52,7 @@ struct iio_dev_opaque { struct attribute_group legacy_buffer_group; unsigned int scan_index_timestamp; + clockid_t clock_id; struct cdev chrdev; unsigned long flags; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index ed0537015eee..5606a3f4c4cb 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -509,7 +509,6 @@ struct iio_buffer_setup_ops { * @name: [DRIVER] name of the device. * @label: [DRIVER] unique name to identify which device this is * @info: [DRIVER] callbacks and constant info from driver - * @clock_id: [INTERN] timestamping clock posix identifier * @setup_ops: [DRIVER] callbacks to call before and after buffer * enable/disable * @priv: [DRIVER] reference to driver's private information @@ -538,7 +537,6 @@ struct iio_dev { const char *name; const char *label; const struct iio_info *info; - clockid_t clock_id; const struct iio_buffer_setup_ops *setup_ops; void *priv; @@ -589,15 +587,7 @@ static inline void iio_device_put(struct iio_dev *indio_dev) put_device(&indio_dev->dev); } -/** - * iio_device_get_clock() - Retrieve current timestamping clock for the device - * @indio_dev: IIO device structure containing the device - */ -static inline clockid_t iio_device_get_clock(const struct iio_dev *indio_dev) -{ - return indio_dev->clock_id; -} - +clockid_t iio_device_get_clock(const struct iio_dev *indio_dev); int iio_device_set_clock(struct iio_dev *indio_dev, clockid_t clock_id); /** -- cgit v1.2.3-70-g09d2 From 38934daf7b5c1b35a01748cb7d4272282cc3a890 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 14 Apr 2021 22:54:50 +0300 Subject: iio: magnetometer: st_magn: Provide default platform data Provide default platform data for magnetometer in case it supports DRDY. One case is LSM9DS0 IMU, on which it is the case. Since accelerometer is using INT1, default magnetometer to INT2. While at it, update description of the drdy_int_pin field. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210414195454.84183-3-andriy.shevchenko@linux.intel.com Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/st_magn_core.c | 11 ++++++++++- include/linux/platform_data/st_sensors_pdata.h | 3 ++- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index 71faebd07feb..55357f266b8b 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c @@ -383,6 +383,11 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = { }, }; +/* Default magn DRDY is available on INT2 pin */ +static const struct st_sensors_platform_data default_magn_pdata = { + .drdy_int_pin = 2, +}; + static int st_magn_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *ch, int *val, int *val2, long mask) @@ -490,6 +495,7 @@ EXPORT_SYMBOL(st_magn_get_settings); int st_magn_common_probe(struct iio_dev *indio_dev) { struct st_sensor_data *mdata = iio_priv(indio_dev); + struct st_sensors_platform_data *pdata = dev_get_platdata(mdata->dev); int err; indio_dev->modes = INDIO_DIRECT_MODE; @@ -510,7 +516,10 @@ int st_magn_common_probe(struct iio_dev *indio_dev) mdata->current_fullscale = &mdata->sensor_settings->fs.fs_avl[0]; mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz; - err = st_sensors_init_sensor(indio_dev, NULL); + if (!pdata) + pdata = (struct st_sensors_platform_data *)&default_magn_pdata; + + err = st_sensors_init_sensor(indio_dev, pdata); if (err < 0) goto st_magn_power_off; diff --git a/include/linux/platform_data/st_sensors_pdata.h b/include/linux/platform_data/st_sensors_pdata.h index e40b28ca892e..897051e51b78 100644 --- a/include/linux/platform_data/st_sensors_pdata.h +++ b/include/linux/platform_data/st_sensors_pdata.h @@ -13,8 +13,9 @@ /** * struct st_sensors_platform_data - Platform data for the ST sensors * @drdy_int_pin: Redirect DRDY on pin 1 (1) or pin 2 (2). - * Available only for accelerometer and pressure sensors. + * Available only for accelerometer, magnetometer and pressure sensors. * Accelerometer DRDY on LSM330 available only on pin 1 (see datasheet). + * Magnetometer DRDY is supported only on LSM9DS0. * @open_drain: set the interrupt line to be open drain if possible. * @spi_3wire: enable spi-3wire mode. * @pullups: enable/disable i2c controller pullup resistors. -- cgit v1.2.3-70-g09d2 From d61881ef7f08aef02d9bfc8c66f4c89c59cdf112 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 14 Apr 2021 22:54:52 +0300 Subject: iio: st_sensors: Make accel, gyro, magn and pressure probe shared Some IMUs may utilize existing library code for STMicro accelerometer, gyroscope, magnetometer and pressure. Let's share them via st_sensors.h. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210414195454.84183-5-andriy.shevchenko@linux.intel.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/st_accel.h | 4 ---- drivers/iio/gyro/st_gyro.h | 4 ---- drivers/iio/magnetometer/st_magn.h | 4 ---- drivers/iio/pressure/st_pressure.h | 4 ---- include/linux/iio/common/st_sensors.h | 20 ++++++++++++++++++++ 5 files changed, 20 insertions(+), 16 deletions(-) (limited to 'include/linux') diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h index 181ebe79c4eb..f5b0b8bbaff7 100644 --- a/drivers/iio/accel/st_accel.h +++ b/drivers/iio/accel/st_accel.h @@ -62,10 +62,6 @@ enum st_accel_type { #define LIS2DE12_ACCEL_DEV_NAME "lis2de12" #define LIS2HH12_ACCEL_DEV_NAME "lis2hh12" -const struct st_sensor_settings *st_accel_get_settings(const char *name); -int st_accel_common_probe(struct iio_dev *indio_dev); -void st_accel_common_remove(struct iio_dev *indio_dev); - #ifdef CONFIG_IIO_BUFFER int st_accel_allocate_ring(struct iio_dev *indio_dev); void st_accel_deallocate_ring(struct iio_dev *indio_dev); diff --git a/drivers/iio/gyro/st_gyro.h b/drivers/iio/gyro/st_gyro.h index b385fe664dcc..6537f5cb8320 100644 --- a/drivers/iio/gyro/st_gyro.h +++ b/drivers/iio/gyro/st_gyro.h @@ -24,10 +24,6 @@ #define LSM330_GYRO_DEV_NAME "lsm330_gyro" #define LSM9DS0_GYRO_DEV_NAME "lsm9ds0_gyro" -const struct st_sensor_settings *st_gyro_get_settings(const char *name); -int st_gyro_common_probe(struct iio_dev *indio_dev); -void st_gyro_common_remove(struct iio_dev *indio_dev); - #ifdef CONFIG_IIO_BUFFER int st_gyro_allocate_ring(struct iio_dev *indio_dev); void st_gyro_deallocate_ring(struct iio_dev *indio_dev); diff --git a/drivers/iio/magnetometer/st_magn.h b/drivers/iio/magnetometer/st_magn.h index 7ba6a6ba5c58..fb6c906c4c0c 100644 --- a/drivers/iio/magnetometer/st_magn.h +++ b/drivers/iio/magnetometer/st_magn.h @@ -23,10 +23,6 @@ #define LSM9DS1_MAGN_DEV_NAME "lsm9ds1_magn" #define IIS2MDC_MAGN_DEV_NAME "iis2mdc" -const struct st_sensor_settings *st_magn_get_settings(const char *name); -int st_magn_common_probe(struct iio_dev *indio_dev); -void st_magn_common_remove(struct iio_dev *indio_dev); - #ifdef CONFIG_IIO_BUFFER int st_magn_allocate_ring(struct iio_dev *indio_dev); void st_magn_deallocate_ring(struct iio_dev *indio_dev); diff --git a/drivers/iio/pressure/st_pressure.h b/drivers/iio/pressure/st_pressure.h index 5c746ff6087e..9417b3bd7513 100644 --- a/drivers/iio/pressure/st_pressure.h +++ b/drivers/iio/pressure/st_pressure.h @@ -41,10 +41,6 @@ static __maybe_unused const struct st_sensors_platform_data default_press_pdata .drdy_int_pin = 1, }; -const struct st_sensor_settings *st_press_get_settings(const char *name); -int st_press_common_probe(struct iio_dev *indio_dev); -void st_press_common_remove(struct iio_dev *indio_dev); - #ifdef CONFIG_IIO_BUFFER int st_press_allocate_ring(struct iio_dev *indio_dev); void st_press_deallocate_ring(struct iio_dev *indio_dev); diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index 33e939977444..aa017b90fb06 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -317,4 +317,24 @@ ssize_t st_sensors_sysfs_scale_avail(struct device *dev, void st_sensors_dev_name_probe(struct device *dev, char *name, int len); +/* Accelerometer */ +const struct st_sensor_settings *st_accel_get_settings(const char *name); +int st_accel_common_probe(struct iio_dev *indio_dev); +void st_accel_common_remove(struct iio_dev *indio_dev); + +/* Gyroscope */ +const struct st_sensor_settings *st_gyro_get_settings(const char *name); +int st_gyro_common_probe(struct iio_dev *indio_dev); +void st_gyro_common_remove(struct iio_dev *indio_dev); + +/* Magnetometer */ +const struct st_sensor_settings *st_magn_get_settings(const char *name); +int st_magn_common_probe(struct iio_dev *indio_dev); +void st_magn_common_remove(struct iio_dev *indio_dev); + +/* Pressure */ +const struct st_sensor_settings *st_press_get_settings(const char *name); +int st_press_common_probe(struct iio_dev *indio_dev); +void st_press_common_remove(struct iio_dev *indio_dev); + #endif /* ST_SENSORS_H */ -- cgit v1.2.3-70-g09d2 From 6731ca3999ffa4c878a661b980759300dfb0237e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 14 Apr 2021 22:54:53 +0300 Subject: iio: st_sensors: Add lsm9ds0 IMU support We can utilize separate drivers for accelerometer and magnetometer, so here is the glue driver to enable LSM9DS0 IMU support. The idea was suggested by Crestez Dan Leonard in [1]. The proposed change was sent as RFC due to race condition concerns, which are indeed possible. In order to amend the initial change, I went further by providing a specific multi-instantiate probe driver that reuses existing accelerometer and magnetometer. [1]: https://lore.kernel.org/patchwork/patch/670353/ Suggested-by: Crestez Dan Leonard Cc: mr.lahorde@laposte.net Cc: Matija Podravec Cc: Sergey Borishchenko Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210414195454.84183-6-andriy.shevchenko@linux.intel.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/st_accel_core.c | 89 ++++++++++++++- drivers/iio/imu/Kconfig | 1 + drivers/iio/imu/Makefile | 1 + drivers/iio/imu/st_lsm9ds0/Kconfig | 28 +++++ drivers/iio/imu/st_lsm9ds0/Makefile | 5 + drivers/iio/imu/st_lsm9ds0/st_lsm9ds0.h | 23 ++++ drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c | 163 +++++++++++++++++++++++++++ drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_i2c.c | 84 ++++++++++++++ drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_spi.c | 83 ++++++++++++++ drivers/iio/magnetometer/st_magn_core.c | 98 ++++++++++++++++ include/linux/iio/common/st_sensors.h | 2 + 11 files changed, 576 insertions(+), 1 deletion(-) create mode 100644 drivers/iio/imu/st_lsm9ds0/Kconfig create mode 100644 drivers/iio/imu/st_lsm9ds0/Makefile create mode 100644 drivers/iio/imu/st_lsm9ds0/st_lsm9ds0.h create mode 100644 drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c create mode 100644 drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_i2c.c create mode 100644 drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_spi.c (limited to 'include/linux') diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index 5c258c1ca62d..dc32ebefe3fc 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -980,7 +980,94 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { .multi_read_bit = true, .bootime = 2, }, - + { + .wai = 0x49, + .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, + .sensors_supported = { + [0] = LSM9DS0_IMU_DEV_NAME, + }, + .ch = (struct iio_chan_spec *)st_accel_16bit_channels, + .odr = { + .addr = 0x20, + .mask = GENMASK(7, 4), + .odr_avl = { + { 3, 0x01, }, + { 6, 0x02, }, + { 12, 0x03, }, + { 25, 0x04, }, + { 50, 0x05, }, + { 100, 0x06, }, + { 200, 0x07, }, + { 400, 0x08, }, + { 800, 0x09, }, + { 1600, 0x0a, }, + }, + }, + .pw = { + .addr = 0x20, + .mask = GENMASK(7, 4), + .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, + }, + .enable_axis = { + .addr = ST_SENSORS_DEFAULT_AXIS_ADDR, + .mask = ST_SENSORS_DEFAULT_AXIS_MASK, + }, + .fs = { + .addr = 0x21, + .mask = GENMASK(5, 3), + .fs_avl = { + [0] = { + .num = ST_ACCEL_FS_AVL_2G, + .value = 0x00, + .gain = IIO_G_TO_M_S_2(61), + }, + [1] = { + .num = ST_ACCEL_FS_AVL_4G, + .value = 0x01, + .gain = IIO_G_TO_M_S_2(122), + }, + [2] = { + .num = ST_ACCEL_FS_AVL_6G, + .value = 0x02, + .gain = IIO_G_TO_M_S_2(183), + }, + [3] = { + .num = ST_ACCEL_FS_AVL_8G, + .value = 0x03, + .gain = IIO_G_TO_M_S_2(244), + }, + [4] = { + .num = ST_ACCEL_FS_AVL_16G, + .value = 0x04, + .gain = IIO_G_TO_M_S_2(732), + }, + }, + }, + .bdu = { + .addr = 0x20, + .mask = BIT(3), + }, + .drdy_irq = { + .int1 = { + .addr = 0x22, + .mask = BIT(2), + }, + .int2 = { + .addr = 0x23, + .mask = BIT(3), + }, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = GENMASK(2, 0), + }, + }, + .sim = { + .addr = 0x21, + .value = BIT(0), + }, + .multi_read_bit = true, + .bootime = 2, + }, }; /* Default accel DRDY is available on INT1 pin */ diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig index f02883b08480..001ca2c3ff95 100644 --- a/drivers/iio/imu/Kconfig +++ b/drivers/iio/imu/Kconfig @@ -94,6 +94,7 @@ config KMX61 source "drivers/iio/imu/inv_icm42600/Kconfig" source "drivers/iio/imu/inv_mpu6050/Kconfig" source "drivers/iio/imu/st_lsm6dsx/Kconfig" +source "drivers/iio/imu/st_lsm9ds0/Kconfig" endmenu diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile index 13e9ff442b11..c82748096c77 100644 --- a/drivers/iio/imu/Makefile +++ b/drivers/iio/imu/Makefile @@ -26,3 +26,4 @@ obj-y += inv_mpu6050/ obj-$(CONFIG_KMX61) += kmx61.o obj-y += st_lsm6dsx/ +obj-y += st_lsm9ds0/ diff --git a/drivers/iio/imu/st_lsm9ds0/Kconfig b/drivers/iio/imu/st_lsm9ds0/Kconfig new file mode 100644 index 000000000000..53b7017014f8 --- /dev/null +++ b/drivers/iio/imu/st_lsm9ds0/Kconfig @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config IIO_ST_LSM9DS0 + tristate "STMicroelectronics LSM9DS0 IMU driver" + depends on (I2C || SPI_MASTER) && SYSFS + depends on !SENSORS_LIS3_I2C + depends on !SENSORS_LIS3_SPI + select IIO_ST_LSM9DS0_I2C if I2C + select IIO_ST_LSM9DS0_SPI if SPI_MASTER + select IIO_ST_ACCEL_3AXIS + select IIO_ST_MAGN_3AXIS + + help + Say yes here to build support for STMicroelectronics LSM9DS0 IMU + sensor. Supported devices: accelerometer/magnetometer of lsm9ds0. + + To compile this driver as a module, choose M here: the module + will be called st_lsm9ds0. + +config IIO_ST_LSM9DS0_I2C + tristate + depends on IIO_ST_LSM9DS0 + select REGMAP_I2C + +config IIO_ST_LSM9DS0_SPI + tristate + depends on IIO_ST_LSM9DS0 + select REGMAP_SPI diff --git a/drivers/iio/imu/st_lsm9ds0/Makefile b/drivers/iio/imu/st_lsm9ds0/Makefile new file mode 100644 index 000000000000..488af523f648 --- /dev/null +++ b/drivers/iio/imu/st_lsm9ds0/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_IIO_ST_LSM9DS0) += st_lsm9ds0.o +st_lsm9ds0-y := st_lsm9ds0_core.o +obj-$(CONFIG_IIO_ST_LSM9DS0_I2C) += st_lsm9ds0_i2c.o +obj-$(CONFIG_IIO_ST_LSM9DS0_SPI) += st_lsm9ds0_spi.o diff --git a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0.h b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0.h new file mode 100644 index 000000000000..146393afd9a7 --- /dev/null +++ b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +// STMicroelectronics LSM9DS0 IMU driver + +#ifndef ST_LSM9DS0_H +#define ST_LSM9DS0_H + +struct iio_dev; +struct regulator; + +struct st_lsm9ds0 { + struct device *dev; + const char *name; + int irq; + struct iio_dev *accel; + struct iio_dev *magn; + struct regulator *vdd; + struct regulator *vdd_io; +}; + +int st_lsm9ds0_probe(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap); +int st_lsm9ds0_remove(struct st_lsm9ds0 *lsm9ds0); + +#endif /* ST_LSM9DS0_H */ diff --git a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c new file mode 100644 index 000000000000..8204f7303fd7 --- /dev/null +++ b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * STMicroelectronics LSM9DS0 IMU driver + * + * Copyright (C) 2021, Intel Corporation + * + * Author: Andy Shevchenko + */ + +#include +#include +#include +#include + +#include +#include + +#include "st_lsm9ds0.h" + +static int st_lsm9ds0_power_enable(struct device *dev, struct st_lsm9ds0 *lsm9ds0) +{ + int ret; + + /* Regulators not mandatory, but if requested we should enable them. */ + lsm9ds0->vdd = devm_regulator_get(dev, "vdd"); + if (IS_ERR(lsm9ds0->vdd)) { + dev_err(dev, "unable to get Vdd supply\n"); + return PTR_ERR(lsm9ds0->vdd); + } + ret = regulator_enable(lsm9ds0->vdd); + if (ret) { + dev_warn(dev, "Failed to enable specified Vdd supply\n"); + return ret; + } + + lsm9ds0->vdd_io = devm_regulator_get(dev, "vddio"); + if (IS_ERR(lsm9ds0->vdd_io)) { + dev_err(dev, "unable to get Vdd_IO supply\n"); + regulator_disable(lsm9ds0->vdd); + return PTR_ERR(lsm9ds0->vdd_io); + } + ret = regulator_enable(lsm9ds0->vdd_io); + if (ret) { + dev_warn(dev, "Failed to enable specified Vdd_IO supply\n"); + regulator_disable(lsm9ds0->vdd); + return ret; + } + + return 0; +} + +static void st_lsm9ds0_power_disable(void *data) +{ + struct st_lsm9ds0 *lsm9ds0 = data; + + regulator_disable(lsm9ds0->vdd_io); + regulator_disable(lsm9ds0->vdd); +} + +static int devm_st_lsm9ds0_power_enable(struct st_lsm9ds0 *lsm9ds0) +{ + struct device *dev = lsm9ds0->dev; + int ret; + + ret = st_lsm9ds0_power_enable(dev, lsm9ds0); + if (ret) + return ret; + + return devm_add_action_or_reset(dev, st_lsm9ds0_power_disable, lsm9ds0); +} + +static int st_lsm9ds0_probe_accel(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap) +{ + const struct st_sensor_settings *settings; + struct device *dev = lsm9ds0->dev; + struct st_sensor_data *data; + + settings = st_accel_get_settings(lsm9ds0->name); + if (!settings) { + dev_err(dev, "device name %s not recognized.\n", lsm9ds0->name); + return -ENODEV; + } + + lsm9ds0->accel = devm_iio_device_alloc(dev, sizeof(*data)); + if (!lsm9ds0->accel) + return -ENOMEM; + + lsm9ds0->accel->name = lsm9ds0->name; + + data = iio_priv(lsm9ds0->accel); + data->sensor_settings = (struct st_sensor_settings *)settings; + data->dev = dev; + data->irq = lsm9ds0->irq; + data->regmap = regmap; + data->vdd = lsm9ds0->vdd; + data->vdd_io = lsm9ds0->vdd_io; + + return st_accel_common_probe(lsm9ds0->accel); +} + +static int st_lsm9ds0_probe_magn(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap) +{ + const struct st_sensor_settings *settings; + struct device *dev = lsm9ds0->dev; + struct st_sensor_data *data; + + settings = st_magn_get_settings(lsm9ds0->name); + if (!settings) { + dev_err(dev, "device name %s not recognized.\n", lsm9ds0->name); + return -ENODEV; + } + + lsm9ds0->magn = devm_iio_device_alloc(dev, sizeof(*data)); + if (!lsm9ds0->magn) + return -ENOMEM; + + lsm9ds0->magn->name = lsm9ds0->name; + + data = iio_priv(lsm9ds0->magn); + data->sensor_settings = (struct st_sensor_settings *)settings; + data->dev = dev; + data->irq = lsm9ds0->irq; + data->regmap = regmap; + data->vdd = lsm9ds0->vdd; + data->vdd_io = lsm9ds0->vdd_io; + + return st_magn_common_probe(lsm9ds0->magn); +} + +int st_lsm9ds0_probe(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap) +{ + int ret; + + ret = devm_st_lsm9ds0_power_enable(lsm9ds0); + if (ret) + return ret; + + /* Setup accelerometer device */ + ret = st_lsm9ds0_probe_accel(lsm9ds0, regmap); + if (ret) + return ret; + + /* Setup magnetometer device */ + ret = st_lsm9ds0_probe_magn(lsm9ds0, regmap); + if (ret) + st_accel_common_remove(lsm9ds0->accel); + + return ret; +} +EXPORT_SYMBOL_GPL(st_lsm9ds0_probe); + +int st_lsm9ds0_remove(struct st_lsm9ds0 *lsm9ds0) +{ + st_magn_common_remove(lsm9ds0->magn); + st_accel_common_remove(lsm9ds0->accel); + + return 0; +} +EXPORT_SYMBOL_GPL(st_lsm9ds0_remove); + +MODULE_AUTHOR("Andy Shevchenko "); +MODULE_DESCRIPTION("STMicroelectronics LSM9DS0 IMU core driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_i2c.c b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_i2c.c new file mode 100644 index 000000000000..50a36ab53bc3 --- /dev/null +++ b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_i2c.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * STMicroelectronics LSM9DS0 IMU driver + * + * Copyright (C) 2021, Intel Corporation + * + * Author: Andy Shevchenko + */ + +#include +#include +#include +#include + +#include + +#include "st_lsm9ds0.h" + +static const struct of_device_id st_lsm9ds0_of_match[] = { + { + .compatible = "st,lsm9ds0-imu", + .data = LSM9DS0_IMU_DEV_NAME, + }, + {} +}; +MODULE_DEVICE_TABLE(of, st_lsm9ds0_of_match); + +static const struct i2c_device_id st_lsm9ds0_id_table[] = { + { LSM9DS0_IMU_DEV_NAME }, + {} +}; +MODULE_DEVICE_TABLE(i2c, st_lsm9ds0_id_table); + +static const struct regmap_config st_lsm9ds0_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .read_flag_mask = 0x80, +}; + +static int st_lsm9ds0_i2c_probe(struct i2c_client *client) +{ + const struct regmap_config *config = &st_lsm9ds0_regmap_config; + struct device *dev = &client->dev; + struct st_lsm9ds0 *lsm9ds0; + struct regmap *regmap; + + st_sensors_dev_name_probe(dev, client->name, sizeof(client->name)); + + lsm9ds0 = devm_kzalloc(dev, sizeof(*lsm9ds0), GFP_KERNEL); + if (!lsm9ds0) + return -ENOMEM; + + lsm9ds0->dev = dev; + lsm9ds0->name = client->name; + lsm9ds0->irq = client->irq; + + regmap = devm_regmap_init_i2c(client, config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + i2c_set_clientdata(client, lsm9ds0); + + return st_lsm9ds0_probe(lsm9ds0, regmap); +} + +static int st_lsm9ds0_i2c_remove(struct i2c_client *client) +{ + return st_lsm9ds0_remove(i2c_get_clientdata(client)); +} + +static struct i2c_driver st_lsm9ds0_driver = { + .driver = { + .name = "st-lsm9ds0-i2c", + .of_match_table = st_lsm9ds0_of_match, + }, + .probe_new = st_lsm9ds0_i2c_probe, + .remove = st_lsm9ds0_i2c_remove, + .id_table = st_lsm9ds0_id_table, +}; +module_i2c_driver(st_lsm9ds0_driver); + +MODULE_AUTHOR("Andy Shevchenko "); +MODULE_DESCRIPTION("STMicroelectronics LSM9DS0 IMU I2C driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_spi.c b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_spi.c new file mode 100644 index 000000000000..272c88990dd0 --- /dev/null +++ b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_spi.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * STMicroelectronics LSM9DS0 IMU driver + * + * Copyright (C) 2021, Intel Corporation + * + * Author: Andy Shevchenko + */ + +#include +#include +#include +#include + +#include + +#include "st_lsm9ds0.h" + +static const struct of_device_id st_lsm9ds0_of_match[] = { + { + .compatible = "st,lsm9ds0-imu", + .data = LSM9DS0_IMU_DEV_NAME, + }, + {} +}; +MODULE_DEVICE_TABLE(of, st_lsm9ds0_of_match); + +static const struct spi_device_id st_lsm9ds0_id_table[] = { + { LSM9DS0_IMU_DEV_NAME }, + {} +}; +MODULE_DEVICE_TABLE(spi, st_lsm9ds0_id_table); + +static const struct regmap_config st_lsm9ds0_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .read_flag_mask = 0xc0, +}; + +static int st_lsm9ds0_spi_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct st_lsm9ds0 *lsm9ds0; + struct regmap *regmap; + + st_sensors_dev_name_probe(dev, spi->modalias, sizeof(spi->modalias)); + + lsm9ds0 = devm_kzalloc(dev, sizeof(*lsm9ds0), GFP_KERNEL); + if (!lsm9ds0) + return -ENOMEM; + + lsm9ds0->dev = dev; + lsm9ds0->name = spi->modalias; + lsm9ds0->irq = spi->irq; + + regmap = devm_regmap_init_spi(spi, &st_lsm9ds0_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + spi_set_drvdata(spi, lsm9ds0); + + return st_lsm9ds0_probe(lsm9ds0, regmap); +} + +static int st_lsm9ds0_spi_remove(struct spi_device *spi) +{ + return st_lsm9ds0_remove(spi_get_drvdata(spi)); +} + +static struct spi_driver st_lsm9ds0_driver = { + .driver = { + .name = "st-lsm9ds0-spi", + .of_match_table = st_lsm9ds0_of_match, + }, + .probe = st_lsm9ds0_spi_probe, + .remove = st_lsm9ds0_spi_remove, + .id_table = st_lsm9ds0_id_table, +}; +module_spi_driver(st_lsm9ds0_driver); + +MODULE_AUTHOR("Andy Shevchenko "); +MODULE_DESCRIPTION("STMicroelectronics LSM9DS0 IMU SPI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index 58da48434a25..1596faa74da9 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c @@ -33,6 +33,7 @@ /* FULLSCALE */ #define ST_MAGN_FS_AVL_1300MG 1300 #define ST_MAGN_FS_AVL_1900MG 1900 +#define ST_MAGN_FS_AVL_2000MG 2000 #define ST_MAGN_FS_AVL_2500MG 2500 #define ST_MAGN_FS_AVL_4000MG 4000 #define ST_MAGN_FS_AVL_4700MG 4700 @@ -53,6 +54,11 @@ #define ST_MAGN_3_OUT_Y_L_ADDR 0x6a #define ST_MAGN_3_OUT_Z_L_ADDR 0x6c +/* Special L addresses for sensor 4 */ +#define ST_MAGN_4_OUT_X_L_ADDR 0x08 +#define ST_MAGN_4_OUT_Y_L_ADDR 0x0a +#define ST_MAGN_4_OUT_Z_L_ADDR 0x0c + static const struct iio_chan_spec st_magn_16bit_channels[] = { ST_SENSORS_LSM_CHANNELS(IIO_MAGN, BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), @@ -101,6 +107,22 @@ static const struct iio_chan_spec st_magn_3_16bit_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(3) }; +static const struct iio_chan_spec st_magn_4_16bit_channels[] = { + ST_SENSORS_LSM_CHANNELS(IIO_MAGN, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16, + ST_MAGN_4_OUT_X_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_MAGN, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16, + ST_MAGN_4_OUT_Y_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_MAGN, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16, + ST_MAGN_4_OUT_Z_L_ADDR), + IIO_CHAN_SOFT_TIMESTAMP(3) +}; + static const struct st_sensor_settings st_magn_sensors_settings[] = { { .wai = 0, /* This sensor has no valid WhoAmI report 0 */ @@ -381,6 +403,82 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = { .multi_read_bit = false, .bootime = 2, }, + { + .wai = 0x49, + .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, + .sensors_supported = { + [0] = LSM9DS0_IMU_DEV_NAME, + }, + .ch = (struct iio_chan_spec *)st_magn_4_16bit_channels, + .odr = { + .addr = 0x24, + .mask = GENMASK(4, 2), + .odr_avl = { + { 3, 0x00, }, + { 6, 0x01, }, + { 12, 0x02, }, + { 25, 0x03, }, + { 50, 0x04, }, + { 100, 0x05, }, + }, + }, + .pw = { + .addr = 0x26, + .mask = GENMASK(1, 0), + .value_on = 0x00, + .value_off = 0x03, + }, + .fs = { + .addr = 0x25, + .mask = GENMASK(6, 5), + .fs_avl = { + [0] = { + .num = ST_MAGN_FS_AVL_2000MG, + .value = 0x00, + .gain = 73, + }, + [1] = { + .num = ST_MAGN_FS_AVL_4000MG, + .value = 0x01, + .gain = 146, + }, + [2] = { + .num = ST_MAGN_FS_AVL_8000MG, + .value = 0x02, + .gain = 292, + }, + [3] = { + .num = ST_MAGN_FS_AVL_12000MG, + .value = 0x03, + .gain = 438, + }, + }, + }, + .bdu = { + .addr = 0x20, + .mask = BIT(3), + }, + .drdy_irq = { + .int1 = { + .addr = 0x22, + .mask = BIT(1), + }, + .int2 = { + .addr = 0x23, + .mask = BIT(2), + }, + .stat_drdy = { + .addr = 0x07, + .mask = GENMASK(2, 0), + }, + }, + .sim = { + .addr = 0x21, + .value = BIT(0), + }, + .multi_read_bit = true, + .bootime = 2, + }, }; /* Default magn DRDY is available on INT2 pin */ diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index aa017b90fb06..0b9aeb479f48 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -20,6 +20,8 @@ #include +#define LSM9DS0_IMU_DEV_NAME "lsm9ds0" + /* * Buffer size max case: 2bytes per channel, 3 channels in total + * 8bytes timestamp channel (s64) -- cgit v1.2.3-70-g09d2 From 8dea228b174ac9637b567e5ef54f4c40db4b3c41 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 1 May 2021 18:13:47 +0100 Subject: iio: cros_ec_sensors: Fix alignment of buffer in iio_push_to_buffers_with_timestamp() The samples buffer is passed to iio_push_to_buffers_with_timestamp() which requires a buffer aligned to 8 bytes as it is assumed that the timestamp will be naturally aligned if present. Fixes tag is inaccurate but prior to that likely manual backporting needed (for anything before 4.18) Earlier than that the include file to fix is drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.h: commit 974e6f02e27 ("iio: cros_ec_sensors_core: Add common functions for the ChromeOS EC Sensor Hub.") present since kernel stable 4.10. (Thanks to Gwendal for tracking this down) Fixes: 5a0b8cb46624c ("iio: cros_ec: Move cros_ec_sensors_core.h in /include") Signed-off-by: Jonathan Cameron Reviewed-by: Gwendal Grignou Date: Tue, 18 May 2021 14:25:46 +0300 Subject: iio: Drop Duplicated "mount-matrix" parameter All of the users of iio_read_mount_matrix() are using the very same property name. Moreover, the property name is hard coded in the API documentation. Make this clear and avoid duplication now and in the future. Signed-off-by: Andy Shevchenko Reviewed-by: Sean Nyekjaer Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20210518112546.44592-1-andriy.shevchenko@linux.intel.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bma180.c | 3 +-- drivers/iio/accel/bma400_core.c | 2 +- drivers/iio/accel/bmc150-accel-core.c | 3 +-- drivers/iio/accel/fxls8962af-core.c | 2 +- drivers/iio/accel/kxcjk-1013.c | 3 +-- drivers/iio/accel/kxsd9.c | 2 +- drivers/iio/gyro/bmg160_core.c | 3 +-- drivers/iio/gyro/itg3200_core.c | 3 +-- drivers/iio/gyro/mpu3050-core.c | 2 +- drivers/iio/imu/bmi160/bmi160_core.c | 3 +-- drivers/iio/imu/inv_icm42600/inv_icm42600_core.c | 2 +- drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 3 +-- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 2 +- drivers/iio/industrialio-core.c | 7 ++----- drivers/iio/magnetometer/ak8974.c | 3 +-- drivers/iio/magnetometer/ak8975.c | 2 +- drivers/iio/magnetometer/bmc150_magn.c | 3 +-- drivers/iio/magnetometer/hmc5843_core.c | 3 +-- drivers/iio/magnetometer/yamaha-yas530.c | 2 +- include/linux/iio/iio.h | 3 +-- 20 files changed, 21 insertions(+), 35 deletions(-) (limited to 'include/linux') diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 71c76bbd81d4..97e991581960 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -1001,8 +1001,7 @@ static int bma180_probe(struct i2c_client *client, chip = id->driver_data; data->part_info = &bma180_part_info[chip]; - ret = iio_read_mount_matrix(dev, "mount-matrix", - &data->orientation); + ret = iio_read_mount_matrix(dev, &data->orientation); if (ret) return ret; diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index 7eeba80e32cb..21520e022a21 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -811,7 +811,7 @@ int bma400_probe(struct device *dev, struct regmap *regmap, const char *name) if (ret) return ret; - ret = iio_read_mount_matrix(dev, "mount-matrix", &data->orientation); + ret = iio_read_mount_matrix(dev, &data->orientation); if (ret) return ret; diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 43cfadf8f6b7..46ab7675186c 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -1685,8 +1685,7 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq, data->regmap = regmap; if (!bmc150_apply_acpi_orientation(dev, &data->orientation)) { - ret = iio_read_mount_matrix(dev, "mount-matrix", - &data->orientation); + ret = iio_read_mount_matrix(dev, &data->orientation); if (ret) return ret; } diff --git a/drivers/iio/accel/fxls8962af-core.c b/drivers/iio/accel/fxls8962af-core.c index 9fe5a18a605c..078d87865fde 100644 --- a/drivers/iio/accel/fxls8962af-core.c +++ b/drivers/iio/accel/fxls8962af-core.c @@ -862,7 +862,7 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq) dev_set_drvdata(dev, indio_dev); data->regmap = regmap; - ret = iio_read_mount_matrix(dev, "mount-matrix", &data->orientation); + ret = iio_read_mount_matrix(dev, &data->orientation); if (ret) return ret; diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index 7cd647315194..a51fdd3c9b5b 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -1455,8 +1455,7 @@ static int kxcjk1013_probe(struct i2c_client *client, } else { data->active_high_intr = true; /* default polarity */ - ret = iio_read_mount_matrix(&client->dev, "mount-matrix", - &data->orientation); + ret = iio_read_mount_matrix(&client->dev, &data->orientation); if (ret) return ret; } diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c index 0e18b92e2099..bf7ed9e7d00f 100644 --- a/drivers/iio/accel/kxsd9.c +++ b/drivers/iio/accel/kxsd9.c @@ -420,7 +420,7 @@ int kxsd9_common_probe(struct device *dev, indio_dev->available_scan_masks = kxsd9_scan_masks; /* Read the mounting matrix, if present */ - ret = iio_read_mount_matrix(dev, "mount-matrix", &st->orientation); + ret = iio_read_mount_matrix(dev, &st->orientation); if (ret) return ret; diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c index a7cc2cad8bbf..17b939a367ad 100644 --- a/drivers/iio/gyro/bmg160_core.c +++ b/drivers/iio/gyro/bmg160_core.c @@ -1106,8 +1106,7 @@ int bmg160_core_probe(struct device *dev, struct regmap *regmap, int irq, if (ret) return ret; - ret = iio_read_mount_matrix(dev, "mount-matrix", - &data->orientation); + ret = iio_read_mount_matrix(dev, &data->orientation); if (ret) return ret; diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c index e9804664db73..a7f1bbb5f289 100644 --- a/drivers/iio/gyro/itg3200_core.c +++ b/drivers/iio/gyro/itg3200_core.c @@ -308,8 +308,7 @@ static int itg3200_probe(struct i2c_client *client, st = iio_priv(indio_dev); - ret = iio_read_mount_matrix(&client->dev, "mount-matrix", - &st->orientation); + ret = iio_read_mount_matrix(&client->dev, &st->orientation); if (ret) return ret; diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c index 2b930c7f4d86..3225de1f023b 100644 --- a/drivers/iio/gyro/mpu3050-core.c +++ b/drivers/iio/gyro/mpu3050-core.c @@ -1164,7 +1164,7 @@ int mpu3050_common_probe(struct device *dev, mpu3050->divisor = 99; /* Read the mounting matrix, if present */ - ret = iio_read_mount_matrix(dev, "mount-matrix", &mpu3050->orientation); + ret = iio_read_mount_matrix(dev, &mpu3050->orientation); if (ret) return ret; diff --git a/drivers/iio/imu/bmi160/bmi160_core.c b/drivers/iio/imu/bmi160/bmi160_core.c index b63bd7e5e5e5..824b5124a5f5 100644 --- a/drivers/iio/imu/bmi160/bmi160_core.c +++ b/drivers/iio/imu/bmi160/bmi160_core.c @@ -852,8 +852,7 @@ int bmi160_core_probe(struct device *dev, struct regmap *regmap, return ret; } - ret = iio_read_mount_matrix(dev, "mount-matrix", - &data->orientation); + ret = iio_read_mount_matrix(dev, &data->orientation); if (ret) return ret; diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c index 8bd77185ccb7..86858da9cc38 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c @@ -592,7 +592,7 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq, st->chip = chip; st->map = regmap; - ret = iio_read_mount_matrix(dev, "mount-matrix", &st->orientation); + ret = iio_read_mount_matrix(dev, &st->orientation); if (ret) { dev_err(dev, "failed to retrieve mounting matrix %d\n", ret); return ret; diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 6244a07048df..64704b55f6eb 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -1455,8 +1455,7 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, pdata = dev_get_platdata(dev); if (!pdata) { - result = iio_read_mount_matrix(dev, "mount-matrix", - &st->orientation); + result = iio_read_mount_matrix(dev, &st->orientation); if (result) { dev_err(dev, "Failed to retrieve mounting matrix %d\n", result); diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index e8d242ee6743..db45f1fc0b81 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -2256,7 +2256,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, return err; } - err = iio_read_mount_matrix(hw->dev, "mount-matrix", &hw->orientation); + err = iio_read_mount_matrix(hw->dev, &hw->orientation); if (err) return err; diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 75e92bac78f3..6d2175eb7af2 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -617,7 +617,6 @@ EXPORT_SYMBOL_GPL(iio_show_mount_matrix); * iio_read_mount_matrix() - retrieve iio device mounting matrix from * device "mount-matrix" property * @dev: device the mounting matrix property is assigned to - * @propname: device specific mounting matrix property name * @matrix: where to store retrieved matrix * * If device is assigned no mounting matrix property, a default 3x3 identity @@ -625,14 +624,12 @@ EXPORT_SYMBOL_GPL(iio_show_mount_matrix); * * Return: 0 if success, or a negative error code on failure. */ -int iio_read_mount_matrix(struct device *dev, const char *propname, - struct iio_mount_matrix *matrix) +int iio_read_mount_matrix(struct device *dev, struct iio_mount_matrix *matrix) { size_t len = ARRAY_SIZE(iio_mount_idmatrix.rotation); int err; - err = device_property_read_string_array(dev, propname, - matrix->rotation, len); + err = device_property_read_string_array(dev, "mount-matrix", matrix->rotation, len); if (err == len) return 0; diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c index 24b2f7b1fe44..e54feacfb980 100644 --- a/drivers/iio/magnetometer/ak8974.c +++ b/drivers/iio/magnetometer/ak8974.c @@ -833,8 +833,7 @@ static int ak8974_probe(struct i2c_client *i2c, ak8974->i2c = i2c; mutex_init(&ak8974->lock); - ret = iio_read_mount_matrix(&i2c->dev, "mount-matrix", - &ak8974->orientation); + ret = iio_read_mount_matrix(&i2c->dev, &ak8974->orientation); if (ret) return ret; diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index d988b6ac3659..42b8a2680e3a 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -890,7 +890,7 @@ static int ak8975_probe(struct i2c_client *client, data->reset_gpiod = reset_gpiod; data->eoc_irq = 0; - err = iio_read_mount_matrix(&client->dev, "mount-matrix", &data->orientation); + err = iio_read_mount_matrix(&client->dev, &data->orientation); if (err) return err; diff --git a/drivers/iio/magnetometer/bmc150_magn.c b/drivers/iio/magnetometer/bmc150_magn.c index 5f28220a7994..f96f53175349 100644 --- a/drivers/iio/magnetometer/bmc150_magn.c +++ b/drivers/iio/magnetometer/bmc150_magn.c @@ -890,8 +890,7 @@ int bmc150_magn_probe(struct device *dev, struct regmap *regmap, if (ret) return dev_err_probe(dev, ret, "failed to get regulators\n"); - ret = iio_read_mount_matrix(dev, "mount-matrix", - &data->orientation); + ret = iio_read_mount_matrix(dev, &data->orientation); if (ret) return ret; diff --git a/drivers/iio/magnetometer/hmc5843_core.c b/drivers/iio/magnetometer/hmc5843_core.c index 221563e0c18f..cf62057480cf 100644 --- a/drivers/iio/magnetometer/hmc5843_core.c +++ b/drivers/iio/magnetometer/hmc5843_core.c @@ -637,8 +637,7 @@ int hmc5843_common_probe(struct device *dev, struct regmap *regmap, data->variant = &hmc5843_chip_info_tbl[id]; mutex_init(&data->lock); - ret = iio_read_mount_matrix(dev, "mount-matrix", - &data->orientation); + ret = iio_read_mount_matrix(dev, &data->orientation); if (ret) return ret; diff --git a/drivers/iio/magnetometer/yamaha-yas530.c b/drivers/iio/magnetometer/yamaha-yas530.c index 2f2f8cb3c26c..9ff7b0e56cf6 100644 --- a/drivers/iio/magnetometer/yamaha-yas530.c +++ b/drivers/iio/magnetometer/yamaha-yas530.c @@ -831,7 +831,7 @@ static int yas5xx_probe(struct i2c_client *i2c, yas5xx->dev = dev; mutex_init(&yas5xx->lock); - ret = iio_read_mount_matrix(dev, "mount-matrix", &yas5xx->orientation); + ret = iio_read_mount_matrix(dev, &yas5xx->orientation); if (ret) return ret; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 5606a3f4c4cb..324561b7a5e8 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -127,8 +127,7 @@ struct iio_mount_matrix { ssize_t iio_show_mount_matrix(struct iio_dev *indio_dev, uintptr_t priv, const struct iio_chan_spec *chan, char *buf); -int iio_read_mount_matrix(struct device *dev, const char *propname, - struct iio_mount_matrix *matrix); +int iio_read_mount_matrix(struct device *dev, struct iio_mount_matrix *matrix); typedef const struct iio_mount_matrix * (iio_get_mount_matrix_t)(const struct iio_dev *indio_dev, -- cgit v1.2.3-70-g09d2 From 42ef8aa2263b19b06e69a318dbd8f1639013ded3 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 19 May 2021 01:07:18 +0200 Subject: iio: st_sensors: Create extended attr macro Extend ST_SENSORS_LSM_CHANNELS() to a version that will accept extended attributes named ST_SENSORS_LSM_CHANNELS_EXT() and wrap the former as a specialized version of the former. Cc: Hans de Goede Cc: Denis Ciocca Cc: Daniel Drake Reviewed-by: Andy Shevchenko Signed-off-by: Stephan Gerhold Signed-off-by: Linus Walleij Reviewed-by: Hans de Goede Link: https://lore.kernel.org/r/20210518230722.522446-1-linus.walleij@linaro.org Signed-off-by: Jonathan Cameron --- include/linux/iio/common/st_sensors.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index 0b9aeb479f48..8e0d76b42db9 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -48,8 +48,8 @@ #define ST_SENSORS_MAX_NAME 17 #define ST_SENSORS_MAX_4WAI 8 -#define ST_SENSORS_LSM_CHANNELS(device_type, mask, index, mod, \ - ch2, s, endian, rbits, sbits, addr) \ +#define ST_SENSORS_LSM_CHANNELS_EXT(device_type, mask, index, mod, \ + ch2, s, endian, rbits, sbits, addr, ext) \ { \ .type = device_type, \ .modified = mod, \ @@ -65,8 +65,14 @@ .storagebits = sbits, \ .endianness = endian, \ }, \ + .ext_info = ext, \ } +#define ST_SENSORS_LSM_CHANNELS(device_type, mask, index, mod, \ + ch2, s, endian, rbits, sbits, addr) \ + ST_SENSORS_LSM_CHANNELS_EXT(device_type, mask, index, mod, \ + ch2, s, endian, rbits, sbits, addr, NULL) + #define ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL() \ IIO_DEV_ATTR_SAMP_FREQ_AVAIL( \ st_sensors_sysfs_sampling_frequency_avail) -- cgit v1.2.3-70-g09d2 From 3d8ad94bb175c2de7200569bb706d67c45903838 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 19 May 2021 01:07:19 +0200 Subject: iio: accel: st_sensors: Support generic mounting matrix The ST accelerators support a special type of quirky mounting matrix found in ACPI systems, but not a generic mounting matrix such as from the device tree. Augment the ACPI hack to be a bit more generic and accept a mounting matrix from device properties. This makes it possible to fix orientation on the Ux500 HREF device. Cc: Hans de Goede Cc: Denis Ciocca Cc: Daniel Drake Reviewed-by: Andy Shevchenko Signed-off-by: Stephan Gerhold Signed-off-by: Linus Walleij Reviewed-by: Hans de Goede Link: https://lore.kernel.org/r/20210518230722.522446-2-linus.walleij@linaro.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/st_accel_core.c | 112 ++++++++++++++++++---------------- include/linux/iio/common/st_sensors.h | 4 +- 2 files changed, 62 insertions(+), 54 deletions(-) (limited to 'include/linux') diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index dc32ebefe3fc..9abcebf767b1 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -41,51 +41,74 @@ #define ST_ACCEL_FS_AVL_200G 200 #define ST_ACCEL_FS_AVL_400G 400 +static const struct iio_mount_matrix * +st_accel_get_mount_matrix(const struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct st_sensor_data *adata = iio_priv(indio_dev); + + return &adata->mount_matrix; +} + +static const struct iio_chan_spec_ext_info st_accel_mount_matrix_ext_info[] = { + IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, st_accel_get_mount_matrix), + { } +}; + static const struct iio_chan_spec st_accel_8bit_channels[] = { - ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, + ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL, BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 8, 8, - ST_ACCEL_DEFAULT_OUT_X_L_ADDR+1), - ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, + ST_ACCEL_DEFAULT_OUT_X_L_ADDR+1, + st_accel_mount_matrix_ext_info), + ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL, BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 8, 8, - ST_ACCEL_DEFAULT_OUT_Y_L_ADDR+1), - ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, + ST_ACCEL_DEFAULT_OUT_Y_L_ADDR+1, + st_accel_mount_matrix_ext_info), + ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL, BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 8, 8, - ST_ACCEL_DEFAULT_OUT_Z_L_ADDR+1), + ST_ACCEL_DEFAULT_OUT_Z_L_ADDR+1, + st_accel_mount_matrix_ext_info), IIO_CHAN_SOFT_TIMESTAMP(3) }; static const struct iio_chan_spec st_accel_12bit_channels[] = { - ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, + ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL, BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 12, 16, - ST_ACCEL_DEFAULT_OUT_X_L_ADDR), - ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, + ST_ACCEL_DEFAULT_OUT_X_L_ADDR, + st_accel_mount_matrix_ext_info), + ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL, BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 12, 16, - ST_ACCEL_DEFAULT_OUT_Y_L_ADDR), - ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, + ST_ACCEL_DEFAULT_OUT_Y_L_ADDR, + st_accel_mount_matrix_ext_info), + ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL, BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 12, 16, - ST_ACCEL_DEFAULT_OUT_Z_L_ADDR), + ST_ACCEL_DEFAULT_OUT_Z_L_ADDR, + st_accel_mount_matrix_ext_info), IIO_CHAN_SOFT_TIMESTAMP(3) }; static const struct iio_chan_spec st_accel_16bit_channels[] = { - ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, + ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL, BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16, - ST_ACCEL_DEFAULT_OUT_X_L_ADDR), - ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, + ST_ACCEL_DEFAULT_OUT_X_L_ADDR, + st_accel_mount_matrix_ext_info), + ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL, BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16, - ST_ACCEL_DEFAULT_OUT_Y_L_ADDR), - ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, + ST_ACCEL_DEFAULT_OUT_Y_L_ADDR, + st_accel_mount_matrix_ext_info), + ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL, BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16, - ST_ACCEL_DEFAULT_OUT_Z_L_ADDR), + ST_ACCEL_DEFAULT_OUT_Z_L_ADDR, + st_accel_mount_matrix_ext_info), IIO_CHAN_SOFT_TIMESTAMP(3) }; @@ -1162,25 +1185,10 @@ static const struct iio_trigger_ops st_accel_trigger_ops = { #endif #ifdef CONFIG_ACPI -static const struct iio_mount_matrix * -get_mount_matrix(const struct iio_dev *indio_dev, - const struct iio_chan_spec *chan) -{ - struct st_sensor_data *adata = iio_priv(indio_dev); - - return adata->mount_matrix; -} - -static const struct iio_chan_spec_ext_info mount_matrix_ext_info[] = { - IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, get_mount_matrix), - { }, -}; - /* Read ST-specific _ONT orientation data from ACPI and generate an * appropriate mount matrix. */ -static int apply_acpi_orientation(struct iio_dev *indio_dev, - struct iio_chan_spec *channels) +static int apply_acpi_orientation(struct iio_dev *indio_dev) { struct st_sensor_data *adata = iio_priv(indio_dev); struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; @@ -1269,14 +1277,6 @@ static int apply_acpi_orientation(struct iio_dev *indio_dev, } /* Convert our integer matrix to a string-based iio_mount_matrix */ - adata->mount_matrix = devm_kmalloc(&indio_dev->dev, - sizeof(*adata->mount_matrix), - GFP_KERNEL); - if (!adata->mount_matrix) { - ret = -ENOMEM; - goto out; - } - for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { int matrix_val = final_ont[i][j]; @@ -1295,26 +1295,25 @@ static int apply_acpi_orientation(struct iio_dev *indio_dev, default: goto out; } - adata->mount_matrix->rotation[i * 3 + j] = str_value; + adata->mount_matrix.rotation[i * 3 + j] = str_value; } } - /* Expose the mount matrix via ext_info */ - for (i = 0; i < indio_dev->num_channels; i++) - channels[i].ext_info = mount_matrix_ext_info; - ret = 0; dev_info(&indio_dev->dev, "computed mount matrix from ACPI\n"); out: kfree(buffer.pointer); + if (ret) + dev_dbg(&indio_dev->dev, + "failed to apply ACPI orientation data: %d\n", ret); + return ret; } #else /* !CONFIG_ACPI */ -static int apply_acpi_orientation(struct iio_dev *indio_dev, - struct iio_chan_spec *channels) +static int apply_acpi_orientation(struct iio_dev *indio_dev) { - return 0; + return -EINVAL; } #endif @@ -1361,9 +1360,16 @@ int st_accel_common_probe(struct iio_dev *indio_dev) if (!channels) return -ENOMEM; - if (apply_acpi_orientation(indio_dev, channels)) - dev_warn(&indio_dev->dev, - "failed to apply ACPI orientation data: %d\n", err); + /* + * First try specific ACPI methods to retrieve orientation then try the + * generic function. + */ + err = apply_acpi_orientation(indio_dev); + if (err) { + err = iio_read_mount_matrix(adata->dev, &adata->mount_matrix); + if (err) + return err; + } indio_dev->channels = channels; adata->current_fullscale = &adata->sensor_settings->fs.fs_avl[0]; diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index 8e0d76b42db9..8bdbaf3f3796 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -221,6 +222,7 @@ struct st_sensor_settings { * struct st_sensor_data - ST sensor device status * @dev: Pointer to instance of struct device (I2C or SPI). * @trig: The trigger in use by the core driver. + * @mount_matrix: The mounting matrix of the sensor. * @sensor_settings: Pointer to the specific sensor settings in use. * @current_fullscale: Maximum range of measure by the sensor. * @vdd: Pointer to sensor's Vdd power supply @@ -240,7 +242,7 @@ struct st_sensor_settings { struct st_sensor_data { struct device *dev; struct iio_trigger *trig; - struct iio_mount_matrix *mount_matrix; + struct iio_mount_matrix mount_matrix; struct st_sensor_settings *sensor_settings; struct st_sensor_fullscale_avl *current_fullscale; struct regulator *vdd; -- cgit v1.2.3-70-g09d2 From aa5c8b25392800bbefa82dd19eeff8ebbf261ace Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Thu, 3 Jun 2021 17:58:35 +0100 Subject: i2c: core: Add stub for i2c_verify_client() if !CONFIG_I2C If I2C is not compiled, there is no way we should see a call to i2c_verify_client() on a device that is an i2c client. As such, provide a stub to return NULL to resolve an associated build failure. The build is failing with this link error ld: fxls8962af-core.o: in function `fxls8962af_fifo_transfer': fxls8962af-core.c: undefined reference to `i2c_verify_client' Reported-by: Tom Rix Signed-off-by: Jonathan Cameron Fixes: af959b7b96b8 ("iio: accel: fxls8962af: fix errata bug E3 - I2C burst reads") Reviewed-by: Sean Nyekjaer Acked-by: Wolfram Sang Link: https://lore.kernel.org/r/20210603165835.3594557-1-jic23@kernel.org --- include/linux/i2c.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index e8f2ac8c9c3d..7d71131c394e 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -343,7 +343,6 @@ struct i2c_client { }; #define to_i2c_client(d) container_of(d, struct i2c_client, dev) -struct i2c_client *i2c_verify_client(struct device *dev); struct i2c_adapter *i2c_verify_adapter(struct device *dev); const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id, const struct i2c_client *client); @@ -477,6 +476,13 @@ i2c_new_ancillary_device(struct i2c_client *client, u16 default_addr); void i2c_unregister_device(struct i2c_client *client); + +struct i2c_client *i2c_verify_client(struct device *dev); +#else +static inline struct i2c_client *i2c_verify_client(struct device *dev) +{ + return NULL; +} #endif /* I2C */ /* Mainboard arch_initcall() code should register all its I2C devices. -- cgit v1.2.3-70-g09d2 From 718fb2bcf1034232599045fc710644d903c2af4b Mon Sep 17 00:00:00 2001 From: Alexandru Ardelean Date: Thu, 13 May 2021 15:07:45 +0300 Subject: iio: adc: ad_sigma_delta: introduct devm_ad_sd_setup_buffer_and_trigger() This is a version of ad_sd_setup_buffer_and_trigger() with all underlying functions (that are used) being replaced with their device-managed variants. One thing to take care here is with {devm_}iio_trigger_alloc(), where both functions take a parent-device object as the first parameter. To make sure nothing quirky is happening, the devm_ad_sd_probe_trigger() function is checking that the provided 'dev' reference is the same as the one stored on the 'struct ad_sigma_delta' driver data. Signed-off-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20210513120752.90074-6-aardelean@deviqon.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad_sigma_delta.c | 60 ++++++++++++++++++++++++++++++++++ include/linux/iio/adc/ad_sigma_delta.h | 3 ++ 2 files changed, 63 insertions(+) (limited to 'include/linux') diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index 69b979331ccd..d5801a47be07 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -513,6 +513,46 @@ error_ret: return ret; } +static int devm_ad_sd_probe_trigger(struct device *dev, struct iio_dev *indio_dev) +{ + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + int ret; + + if (dev != &sigma_delta->spi->dev) { + dev_err(dev, "Trigger parent should be '%s', got '%s'\n", + dev_name(dev), dev_name(&sigma_delta->spi->dev)); + return -EFAULT; + } + + sigma_delta->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, + iio_device_id(indio_dev)); + if (sigma_delta->trig == NULL) + return -ENOMEM; + + sigma_delta->trig->ops = &ad_sd_trigger_ops; + init_completion(&sigma_delta->completion); + + sigma_delta->irq_dis = true; + ret = devm_request_irq(dev, sigma_delta->spi->irq, + ad_sd_data_rdy_trig_poll, + sigma_delta->info->irq_flags | IRQF_NO_AUTOEN, + indio_dev->name, + sigma_delta); + if (ret) + return ret; + + iio_trigger_set_drvdata(sigma_delta->trig, sigma_delta); + + ret = devm_iio_trigger_register(dev, sigma_delta->trig); + if (ret) + return ret; + + /* select default trigger */ + indio_dev->trig = iio_trigger_get(sigma_delta->trig); + + return 0; +} + static void ad_sd_remove_trigger(struct iio_dev *indio_dev) { struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); @@ -556,6 +596,26 @@ void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev) } EXPORT_SYMBOL_GPL(ad_sd_cleanup_buffer_and_trigger); +/** + * devm_ad_sd_setup_buffer_and_trigger() - Device-managed buffer & trigger setup + * @dev: Device object to which to bind the life-time of the resources attached + * @indio_dev: The IIO device + */ +int devm_ad_sd_setup_buffer_and_trigger(struct device *dev, struct iio_dev *indio_dev) +{ + int ret; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, + &iio_pollfunc_store_time, + &ad_sd_trigger_handler, + &ad_sd_buffer_setup_ops); + if (ret) + return ret; + + return devm_ad_sd_probe_trigger(dev, indio_dev); +} +EXPORT_SYMBOL_GPL(devm_ad_sd_setup_buffer_and_trigger); + /** * ad_sd_init() - Initializes a ad_sigma_delta struct * @sigma_delta: The ad_sigma_delta device diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h index 7199280d89ca..be81ad39fb7a 100644 --- a/include/linux/iio/adc/ad_sigma_delta.h +++ b/include/linux/iio/adc/ad_sigma_delta.h @@ -26,6 +26,7 @@ struct ad_sd_calib_data { }; struct ad_sigma_delta; +struct device; struct iio_dev; /** @@ -135,6 +136,8 @@ int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev, int ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev); void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev); +int devm_ad_sd_setup_buffer_and_trigger(struct device *dev, struct iio_dev *indio_dev); + int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig); #endif -- cgit v1.2.3-70-g09d2 From 4b36151d7482654ec50ddc831f19a3e76c8ba4dd Mon Sep 17 00:00:00 2001 From: Alexandru Ardelean Date: Thu, 13 May 2021 15:07:52 +0300 Subject: iio: adc: ad_sigma_delta: remove ad_sd_{setup,cleanup}_buffer_and_trigger() Since all AD Sigma-Delta drivers now use the devm_ad_sd_setup_buffer_and_trigger() function, we can remove the old ad_sd_{setup,cleanup}_buffer_and_trigger() functions. This way we can discourage new drivers that use the ad_sigma_delta lib-driver to use these (older functions). Signed-off-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20210513120752.90074-13-aardelean@deviqon.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad_sigma_delta.c | 86 ---------------------------------- include/linux/iio/adc/ad_sigma_delta.h | 3 -- 2 files changed, 89 deletions(-) (limited to 'include/linux') diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index d5801a47be07..1d652d9b2f5c 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -470,49 +470,6 @@ EXPORT_SYMBOL_GPL(ad_sd_validate_trigger); static const struct iio_trigger_ops ad_sd_trigger_ops = { }; -static int ad_sd_probe_trigger(struct iio_dev *indio_dev) -{ - struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); - int ret; - - sigma_delta->trig = iio_trigger_alloc(&sigma_delta->spi->dev, - "%s-dev%d", indio_dev->name, - iio_device_id(indio_dev)); - if (sigma_delta->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - sigma_delta->trig->ops = &ad_sd_trigger_ops; - init_completion(&sigma_delta->completion); - - sigma_delta->irq_dis = true; - ret = request_irq(sigma_delta->spi->irq, - ad_sd_data_rdy_trig_poll, - sigma_delta->info->irq_flags | IRQF_NO_AUTOEN, - indio_dev->name, - sigma_delta); - if (ret) - goto error_free_trig; - - iio_trigger_set_drvdata(sigma_delta->trig, sigma_delta); - - ret = iio_trigger_register(sigma_delta->trig); - if (ret) - goto error_free_irq; - - /* select default trigger */ - indio_dev->trig = iio_trigger_get(sigma_delta->trig); - - return 0; - -error_free_irq: - free_irq(sigma_delta->spi->irq, sigma_delta); -error_free_trig: - iio_trigger_free(sigma_delta->trig); -error_ret: - return ret; -} - static int devm_ad_sd_probe_trigger(struct device *dev, struct iio_dev *indio_dev) { struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); @@ -553,49 +510,6 @@ static int devm_ad_sd_probe_trigger(struct device *dev, struct iio_dev *indio_de return 0; } -static void ad_sd_remove_trigger(struct iio_dev *indio_dev) -{ - struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); - - iio_trigger_unregister(sigma_delta->trig); - free_irq(sigma_delta->spi->irq, sigma_delta); - iio_trigger_free(sigma_delta->trig); -} - -/** - * ad_sd_setup_buffer_and_trigger() - - * @indio_dev: The IIO device - */ -int ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev) -{ - int ret; - - ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, - &ad_sd_trigger_handler, &ad_sd_buffer_setup_ops); - if (ret) - return ret; - - ret = ad_sd_probe_trigger(indio_dev); - if (ret) { - iio_triggered_buffer_cleanup(indio_dev); - return ret; - } - - return 0; -} -EXPORT_SYMBOL_GPL(ad_sd_setup_buffer_and_trigger); - -/** - * ad_sd_cleanup_buffer_and_trigger() - - * @indio_dev: The IIO device - */ -void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev) -{ - ad_sd_remove_trigger(indio_dev); - iio_triggered_buffer_cleanup(indio_dev); -} -EXPORT_SYMBOL_GPL(ad_sd_cleanup_buffer_and_trigger); - /** * devm_ad_sd_setup_buffer_and_trigger() - Device-managed buffer & trigger setup * @dev: Device object to which to bind the life-time of the resources attached diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h index be81ad39fb7a..c525fd51652f 100644 --- a/include/linux/iio/adc/ad_sigma_delta.h +++ b/include/linux/iio/adc/ad_sigma_delta.h @@ -133,9 +133,6 @@ int ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta, int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev, struct spi_device *spi, const struct ad_sigma_delta_info *info); -int ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev); -void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev); - int devm_ad_sd_setup_buffer_and_trigger(struct device *dev, struct iio_dev *indio_dev); int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig); -- cgit v1.2.3-70-g09d2