Merge tag 'iio-fixes-for-7.0b' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-linux

Jonathan writes:

IIO: 2nd set of fixes for the 7.0 cycle

Usual mixed bag of fixes for recent code and much older issues that have
surfaced. Biggest group are continued resolution of IRQF_ONE_SHOT
being used incorrectly (which now triggers a warning)

adi,ad4062
- Replace IRQF_ONESHOT (as no threaded handler) with IRQF_NO_THREAD as
  the caller makes use of iio_trigger_poll() which cannot run from a
  thread.
adi,ade9000
- Move mutex_init() earlier to ensure it is available if spurious IRQ
  occurs.
adi,adis16550
- Fix swapped gyro and accel filter functions.
adi,adxl3380
- Fix some bit manipulation that was always resulting in 0.
- Fix incorrect register map for calibbias on the active power channel.
- Fix returning IRQF_HANDLED from a function that should return 0 or
  -ERRNO.
aspeed,adc
- Clear a reference voltage bit that might be set prior to driver load.
bosch,bno055
- Off by one channel buffer sizing. Benine due to padding prior to the
  subsequent timestamp.
hid-sensors
- A more complex fix to IRQF_ONESHOT warning as this driver had a trigger
  that was never actually used but the ABI that exposed had to be
  maintained to avoid regressions.
hid-sensors-rotation
- An obscure buffer alignment case that applies to quaternions only was
  recently broken resulting in writes beyond the end of the channel buffer.
  Add a new core macro and apply it in this driver to make it very clear
  what was going on.
honeywell,abp2030pa
- Remove meaningless IRQF_ONESHOT from a non threaded IRQ handler.
  Warning fix only.
invense,mpu3050
- Fix token passed to free_irq() to match the one used at setup.
- Fix an irq resource leak in error path.
- Reorder probe so that userspace interfaces are exposed only after
  everything else has finished.
- Reorder remove slightly to cleanup the buffer only after irq removed
  ensuring reverse of probe sequence.
microchip,mcp47feb02
- Fix use of mutex before it was initialized by not performing unnecessary
  lock that was early enough in probe that all code was serial.
st,lsm6dsx
- Ensure that FIFO ODR is only controllable for accel and gyro channels
  avoiding incorrect register accesses.
- Restrict separation of buffer sampling from main sampling rate to
  accelerometer. It is only useful for running event detection faster
  than the fifo and the only events are on the accelerometer.
ti,ads1018
- Fix overflow of u8 which wasn't big enough to store max data rate value.
ti,ads1119:
- Fix unbalanced pm in an error path.
- IRQF_ONESHOT (as no threaded handler) replaced with IRQF_NO_THREAD
  (needed for iio_trigger_poll()).
- Ensure complete reinitialized before reuse. Previously it would have
  completed immediate after the first time.
ti,ads7950
- Fix return value of gpio_get() to be 0 or 1.
- Avoid accidental overwrite of state resulting in gpio_get() only
  returning 0 or -ERRNO but never 1.

* tag 'iio-fixes-for-7.0b' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (25 commits)
  iio: imu: adis16550: fix swapped gyro/accel filter functions
  iio: adc: aspeed: clear reference voltage bits before configuring vref
  iio: adc: ti-ads1119: Reinit completion before wait_for_completion_timeout()
  iio: adc: ti-ads1018: fix type overflow for data rate
  iio: adc: ti-ads7950: do not clobber gpio state in ti_ads7950_get()
  iio: adc: ti-ads7950: normalize return value of gpio_get
  iio: orientation: hid-sensor-rotation: fix quaternion alignment
  iio: add IIO_DECLARE_QUATERNION() macro
  iio: adc: ti-ads1119: Replace IRQF_ONESHOT with IRQF_NO_THREAD
  iio: imu: bno055: fix BNO055_SCAN_CH_COUNT off by one
  iio: hid-sensors: Use software trigger
  iio: adc: ad4062: Replace IRQF_ONESHOT with IRQF_NO_THREAD
  iio: gyro: mpu3050: Fix out-of-sequence free_irq()
  iio: gyro: mpu3050: Move iio_device_register() to correct location
  iio: gyro: mpu3050: Fix irq resource leak
  iio: gyro: mpu3050: Fix incorrect free_irq() variable
  iio: imu: st_lsm6dsx: Set buffer sampling frequency for accelerometer only
  iio: imu: st_lsm6dsx: Set FIFO ODR for accelerometer and gyroscope only
  iio: dac: mcp47feb02: Fix mutex used before initialization
  iio: adc: ade9000: fix wrong return type in streaming push
  ...
This commit is contained in:
Greg Kroah-Hartman
2026-03-29 14:49:21 +02:00
16 changed files with 107 additions and 60 deletions

View File

@@ -877,7 +877,7 @@ static int adxl380_set_fifo_samples(struct adxl380_state *st)
ret = regmap_update_bits(st->regmap, ADXL380_FIFO_CONFIG_0_REG,
ADXL380_FIFO_SAMPLES_8_MSK,
FIELD_PREP(ADXL380_FIFO_SAMPLES_8_MSK,
(fifo_samples & BIT(8))));
!!(fifo_samples & BIT(8))));
if (ret)
return ret;

View File

@@ -719,10 +719,8 @@ static int ad4062_request_irq(struct iio_dev *indio_dev)
}
st->gpo_irq[1] = true;
return devm_request_threaded_irq(dev, ret,
ad4062_irq_handler_drdy,
NULL, IRQF_ONESHOT, indio_dev->name,
indio_dev);
return devm_request_irq(dev, ret, ad4062_irq_handler_drdy,
IRQF_NO_THREAD, indio_dev->name, indio_dev);
}
static const struct iio_trigger_ops ad4062_trigger_ops = {
@@ -955,7 +953,7 @@ static int ad4062_write_raw_dispatch(struct ad4062_state *st, int val, int val2,
default:
return -EINVAL;
}
};
}
static int ad4062_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int val,

View File

@@ -787,7 +787,7 @@ static int ade9000_iio_push_streaming(struct iio_dev *indio_dev)
ADE9000_MIDDLE_PAGE_BIT);
if (ret) {
dev_err_ratelimited(dev, "IRQ0 WFB write fail");
return IRQ_HANDLED;
return ret;
}
ade9000_configure_scan(indio_dev, ADE9000_REG_WF_BUFF);
@@ -1123,7 +1123,7 @@ static int ade9000_write_raw(struct iio_dev *indio_dev,
tmp &= ~ADE9000_PHASE_C_POS_BIT;
switch (tmp) {
case ADE9000_REG_AWATTOS:
case ADE9000_REG_AWATT:
return regmap_write(st->regmap,
ADE9000_ADDR_ADJUST(ADE9000_REG_AWATTOS,
chan->channel), val);
@@ -1706,6 +1706,10 @@ static int ade9000_probe(struct spi_device *spi)
init_completion(&st->reset_completion);
ret = devm_mutex_init(dev, &st->lock);
if (ret)
return ret;
ret = ade9000_request_irq(dev, "irq0", ade9000_irq0_thread, indio_dev);
if (ret)
return ret;
@@ -1718,10 +1722,6 @@ static int ade9000_probe(struct spi_device *spi)
if (ret)
return ret;
ret = devm_mutex_init(dev, &st->lock);
if (ret)
return ret;
/* External CMOS clock input (optional - crystal can be used instead) */
st->clkin = devm_clk_get_optional_enabled(dev, NULL);
if (IS_ERR(st->clkin))

View File

@@ -415,6 +415,7 @@ static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
}
adc_engine_control_reg_val =
readl(data->base + ASPEED_REG_ENGINE_CONTROL);
adc_engine_control_reg_val &= ~ASPEED_ADC_REF_VOLTAGE;
ret = devm_regulator_get_enable_read_voltage(data->dev, "vref");
if (ret < 0 && ret != -ENODEV)

View File

@@ -249,7 +249,7 @@ static int ads1018_single_shot(struct ads1018 *ads1018,
struct iio_chan_spec const *chan, u16 *cnv)
{
u8 max_drate_mode = ads1018->chip_info->num_data_rate_mode_to_hz - 1;
u8 drate = ads1018->chip_info->data_rate_mode_to_hz[max_drate_mode];
u32 drate = ads1018->chip_info->data_rate_mode_to_hz[max_drate_mode];
u8 pga_mode = ads1018->chan_data[chan->scan_index].pga_mode;
struct spi_transfer xfer[2] = {
{

View File

@@ -274,12 +274,15 @@ static int ads1119_single_conversion(struct ads1119_state *st,
ret = pm_runtime_resume_and_get(dev);
if (ret)
goto pdown;
return ret;
ret = ads1119_configure_channel(st, mux, gain, datarate);
if (ret)
goto pdown;
if (st->client->irq)
reinit_completion(&st->completion);
ret = i2c_smbus_write_byte(st->client, ADS1119_CMD_START_SYNC);
if (ret)
goto pdown;
@@ -735,10 +738,8 @@ static int ads1119_probe(struct i2c_client *client)
return dev_err_probe(dev, ret, "Failed to setup IIO buffer\n");
if (client->irq > 0) {
ret = devm_request_threaded_irq(dev, client->irq,
ads1119_irq_handler,
NULL, IRQF_ONESHOT,
"ads1119", indio_dev);
ret = devm_request_irq(dev, client->irq, ads1119_irq_handler,
IRQF_NO_THREAD, "ads1119", indio_dev);
if (ret)
return dev_err_probe(dev, ret,
"Failed to allocate irq\n");

View File

@@ -427,13 +427,15 @@ static int ti_ads7950_set(struct gpio_chip *chip, unsigned int offset,
static int ti_ads7950_get(struct gpio_chip *chip, unsigned int offset)
{
struct ti_ads7950_state *st = gpiochip_get_data(chip);
bool state;
int ret;
mutex_lock(&st->slock);
/* If set as output, return the output */
if (st->gpio_cmd_settings_bitmask & BIT(offset)) {
ret = st->cmd_settings_bitmask & BIT(offset);
state = st->cmd_settings_bitmask & BIT(offset);
ret = 0;
goto out;
}
@@ -444,7 +446,7 @@ static int ti_ads7950_get(struct gpio_chip *chip, unsigned int offset)
if (ret)
goto out;
ret = ((st->single_rx >> 12) & BIT(offset)) ? 1 : 0;
state = (st->single_rx >> 12) & BIT(offset);
/* Revert back to original settings */
st->cmd_settings_bitmask &= ~TI_ADS7950_CR_GPIO_DATA;
@@ -456,7 +458,7 @@ static int ti_ads7950_get(struct gpio_chip *chip, unsigned int offset)
out:
mutex_unlock(&st->slock);
return ret;
return ret ?: state;
}
static int ti_ads7950_get_direction(struct gpio_chip *chip,

View File

@@ -14,6 +14,7 @@
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/kfifo_buf.h>
#include "hid-sensor-trigger.h"
static ssize_t _hid_sensor_set_report_latency(struct device *dev,
@@ -202,12 +203,21 @@ static void hid_sensor_set_power_work(struct work_struct *work)
_hid_sensor_power_state(attrb, true);
}
static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
bool state)
static int buffer_postenable(struct iio_dev *indio_dev)
{
return hid_sensor_power_state(iio_trigger_get_drvdata(trig), state);
return hid_sensor_power_state(iio_device_get_drvdata(indio_dev), 1);
}
static int buffer_predisable(struct iio_dev *indio_dev)
{
return hid_sensor_power_state(iio_device_get_drvdata(indio_dev), 0);
}
static const struct iio_buffer_setup_ops hid_sensor_buffer_ops = {
.postenable = buffer_postenable,
.predisable = buffer_predisable,
};
void hid_sensor_remove_trigger(struct iio_dev *indio_dev,
struct hid_sensor_common *attrb)
{
@@ -219,14 +229,9 @@ void hid_sensor_remove_trigger(struct iio_dev *indio_dev,
cancel_work_sync(&attrb->work);
iio_trigger_unregister(attrb->trigger);
iio_trigger_free(attrb->trigger);
iio_triggered_buffer_cleanup(indio_dev);
}
EXPORT_SYMBOL_NS(hid_sensor_remove_trigger, "IIO_HID");
static const struct iio_trigger_ops hid_sensor_trigger_ops = {
.set_trigger_state = &hid_sensor_data_rdy_trigger_set_state,
};
int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
struct hid_sensor_common *attrb)
{
@@ -239,25 +244,34 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
else
fifo_attrs = NULL;
ret = iio_triggered_buffer_setup_ext(indio_dev,
&iio_pollfunc_store_time, NULL,
IIO_BUFFER_DIRECTION_IN,
NULL, fifo_attrs);
indio_dev->modes = INDIO_DIRECT_MODE | INDIO_HARDWARE_TRIGGERED;
ret = devm_iio_kfifo_buffer_setup_ext(&indio_dev->dev, indio_dev,
&hid_sensor_buffer_ops,
fifo_attrs);
if (ret) {
dev_err(&indio_dev->dev, "Triggered Buffer Setup Failed\n");
dev_err(&indio_dev->dev, "Kfifo Buffer Setup Failed\n");
return ret;
}
/*
* The current user space in distro "iio-sensor-proxy" is not working in
* trigerless mode and it expects
* /sys/bus/iio/devices/iio:device0/trigger/current_trigger.
* The change replacing iio_triggered_buffer_setup_ext() with
* devm_iio_kfifo_buffer_setup_ext() will not create attribute without
* registering a trigger with INDIO_HARDWARE_TRIGGERED.
* So the below code fragment is still required.
*/
trig = iio_trigger_alloc(indio_dev->dev.parent,
"%s-dev%d", name, iio_device_id(indio_dev));
if (trig == NULL) {
dev_err(&indio_dev->dev, "Trigger Allocate Failed\n");
ret = -ENOMEM;
goto error_triggered_buffer_cleanup;
return -ENOMEM;
}
iio_trigger_set_drvdata(trig, attrb);
trig->ops = &hid_sensor_trigger_ops;
ret = iio_trigger_register(trig);
if (ret) {
@@ -284,8 +298,6 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
iio_trigger_unregister(trig);
error_free_trig:
iio_trigger_free(trig);
error_triggered_buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
return ret;
}
EXPORT_SYMBOL_NS(hid_sensor_setup_trigger, "IIO_HID");

View File

@@ -955,8 +955,6 @@ static int mcp47feb02_parse_fw(struct iio_dev *indio_dev,
u32 num_channels;
u8 chan_idx = 0;
guard(mutex)(&data->lock);
num_channels = device_get_child_node_count(dev);
if (num_channels > chip_features->phys_channels)
return dev_err_probe(dev, -EINVAL, "More channels than the chip supports\n");

View File

@@ -1129,11 +1129,16 @@ static int mpu3050_trigger_probe(struct iio_dev *indio_dev, int irq)
ret = iio_trigger_register(mpu3050->trig);
if (ret)
return ret;
goto err_iio_trigger;
indio_dev->trig = iio_trigger_get(mpu3050->trig);
return 0;
err_iio_trigger:
free_irq(mpu3050->irq, mpu3050->trig);
return ret;
}
int mpu3050_common_probe(struct device *dev,
@@ -1221,12 +1226,6 @@ int mpu3050_common_probe(struct device *dev,
goto err_power_down;
}
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(dev, "device register failed\n");
goto err_cleanup_buffer;
}
dev_set_drvdata(dev, indio_dev);
/* Check if we have an assigned IRQ to use as trigger */
@@ -1249,9 +1248,20 @@ int mpu3050_common_probe(struct device *dev,
pm_runtime_use_autosuspend(dev);
pm_runtime_put(dev);
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(dev, "device register failed\n");
goto err_iio_device_register;
}
return 0;
err_cleanup_buffer:
err_iio_device_register:
pm_runtime_get_sync(dev);
pm_runtime_put_noidle(dev);
pm_runtime_disable(dev);
if (irq)
free_irq(mpu3050->irq, mpu3050->trig);
iio_triggered_buffer_cleanup(indio_dev);
err_power_down:
mpu3050_power_down(mpu3050);
@@ -1264,13 +1274,13 @@ void mpu3050_common_remove(struct device *dev)
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct mpu3050 *mpu3050 = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
pm_runtime_get_sync(dev);
pm_runtime_put_noidle(dev);
pm_runtime_disable(dev);
iio_triggered_buffer_cleanup(indio_dev);
if (mpu3050->irq)
free_irq(mpu3050->irq, mpu3050);
iio_device_unregister(indio_dev);
free_irq(mpu3050->irq, mpu3050->trig);
iio_triggered_buffer_cleanup(indio_dev);
mpu3050_power_down(mpu3050);
}

View File

@@ -643,12 +643,12 @@ static int adis16550_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
switch (chan->type) {
case IIO_ANGL_VEL:
ret = adis16550_get_accl_filter_freq(st, val);
ret = adis16550_get_gyro_filter_freq(st, val);
if (ret)
return ret;
return IIO_VAL_INT;
case IIO_ACCEL:
ret = adis16550_get_gyro_filter_freq(st, val);
ret = adis16550_get_accl_filter_freq(st, val);
if (ret)
return ret;
return IIO_VAL_INT;
@@ -681,9 +681,9 @@ static int adis16550_write_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
switch (chan->type) {
case IIO_ANGL_VEL:
return adis16550_set_accl_filter_freq(st, val);
case IIO_ACCEL:
return adis16550_set_gyro_filter_freq(st, val);
case IIO_ACCEL:
return adis16550_set_accl_filter_freq(st, val);
default:
return -EINVAL;
}

View File

@@ -64,7 +64,7 @@
#define BNO055_GRAVITY_DATA_X_LSB_REG 0x2E
#define BNO055_GRAVITY_DATA_Y_LSB_REG 0x30
#define BNO055_GRAVITY_DATA_Z_LSB_REG 0x32
#define BNO055_SCAN_CH_COUNT ((BNO055_GRAVITY_DATA_Z_LSB_REG - BNO055_ACC_DATA_X_LSB_REG) / 2)
#define BNO055_SCAN_CH_COUNT ((BNO055_GRAVITY_DATA_Z_LSB_REG - BNO055_ACC_DATA_X_LSB_REG) / 2 + 1)
#define BNO055_TEMP_REG 0x34
#define BNO055_CALIB_STAT_REG 0x35
#define BNO055_CALIB_STAT_MAGN_SHIFT 0

View File

@@ -225,6 +225,10 @@ static int st_lsm6dsx_set_fifo_odr(struct st_lsm6dsx_sensor *sensor,
const struct st_lsm6dsx_reg *batch_reg;
u8 data;
/* Only internal sensors have a FIFO ODR configuration register. */
if (sensor->id >= ARRAY_SIZE(hw->settings->batch))
return 0;
batch_reg = &hw->settings->batch[sensor->id];
if (batch_reg->addr) {
int val;
@@ -858,12 +862,21 @@ int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw)
int i, ret;
for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
const struct iio_dev_attr **attrs;
if (!hw->iio_devs[i])
continue;
/*
* For the accelerometer, allow setting FIFO sampling frequency
* values different from the sensor sampling frequency, which
* may be needed to keep FIFO data rate low while sampling
* acceleration data at high rates for accurate event detection.
*/
attrs = i == ST_LSM6DSX_ID_ACC ? st_lsm6dsx_buffer_attrs : NULL;
ret = devm_iio_kfifo_buffer_setup_ext(hw->dev, hw->iio_devs[i],
&st_lsm6dsx_buffer_ops,
st_lsm6dsx_buffer_attrs);
attrs);
if (ret)
return ret;
}

View File

@@ -19,7 +19,7 @@ struct dev_rot_state {
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info quaternion;
struct {
s32 sampled_vals[4];
IIO_DECLARE_QUATERNION(s32, sampled_vals);
aligned_s64 timestamp;
} scan;
int scale_pre_decml;

View File

@@ -520,7 +520,7 @@ int abp2_common_probe(struct device *dev, const struct abp2_ops *ops, int irq)
data->p_offset = div_s64(odelta * data->pmin, pdelta) - data->outmin;
if (data->irq > 0) {
ret = devm_request_irq(dev, irq, abp2_eoc_handler, IRQF_ONESHOT,
ret = devm_request_irq(dev, irq, abp2_eoc_handler, 0,
dev_name(dev), data);
if (ret)
return ret;

View File

@@ -931,6 +931,18 @@ static inline void *iio_device_get_drvdata(const struct iio_dev *indio_dev)
#define IIO_DECLARE_DMA_BUFFER_WITH_TS(type, name, count) \
__IIO_DECLARE_BUFFER_WITH_TS(type, name, count) __aligned(IIO_DMA_MINALIGN)
/**
* IIO_DECLARE_QUATERNION() - Declare a quaternion element
* @type: element type of the individual vectors
* @name: identifier name
*
* Quaternions are a vector composed of 4 elements (W, X, Y, Z). Use this macro
* to declare a quaternion element in a struct to ensure proper alignment in
* an IIO buffer.
*/
#define IIO_DECLARE_QUATERNION(type, name) \
type name[4] __aligned(sizeof(type) * 4)
struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv);
/* The information at the returned address is guaranteed to be cacheline aligned */