Skip to content

Commit

Permalink
Merge tag 'iio-fixes-for-6.13a' of ssh://gitolite.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/jic23/iio into char-misc-linus

Jonathan writes:

IIO: 1st set of fixes for 6.13 cycle.

The usual mixed back of fixes for ancient and recent bugs

A number of these were from an audit by Javier Carrasco of places
we may leak stack data via holes in structures passed to userspace that
were not explicitly zeroed. Very helpful effort after we found a similar
bug in review of new code.

This affected:
- dummy driver
- kionix,kmx61
- murrata,zpa2326
- rockchip,saradc
- rohm,bh1745
- veml,vcnl4035
- ti,ads1119
- ti,ads8688
- ti,tmp0006

Other fixes:

core,inkern
- Underflow fo reference count issue in error path of iio_channel_get_all()
  for devices we haven't yet gotten.
tests
- Kconfig typo fix so it's possible to tell what test is being enabled.
- Check for allocation failures.

adi,ad4695
- Ensure timing requirement wrt to final clock edge vs next conversion
  signal are met by adding an additional SPI transfer.
adi,ad7124
- Ensure channels are disabled at probe to avoid wrong data if channel 0
  is not the first one read.
adi,ad7173
- Fix handing of multiple devices by not editing a single static
  structure and instead making a per instance copy.
adi,ad9467
- Fix handing of multiple devices by not editing a single static
  structure and instead making a per instance copy.
adi,ad9832
- Off by one error on input verification for phase control
adi,ad9834
- Off by one error on input verification for phase control.
atmel,at91
- In an error path don't use a variable that hasn't been initialized yet.
invensense,icm42600
- SPI burst write does not work for some icm426000 chips, disable it.
- Ensure correct handling of timestamps after resume.
st,sensors
- Add back accidentally dropped IIS2MDC compatible in binding doc.
st,stm32-dfsdm:
- label property was accidentally made a required property. Make it optional
  again to fix use of older DT.
ti,ads1119
- Use a fixed size for the channel data rather than an integer, bringing
  the code inline with the advertised 16 bit channel size and avoiding
  userspace misinterpreting the data.
ti,ads124s08
- Use _cansleep gpio calls as no reason to prevent sleeping and it
  was stopping a new board design working (trivial fix).
ti,ads1298
- Add a check on failure of devm_kasprintf()

* tag 'iio-fixes-for-6.13a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (27 commits)
  iio: adc: ti-ads1119: fix sample size in scan struct for triggered buffer
  iio: temperature: tmp006: fix information leak in triggered buffer
  iio: inkern: call iio_device_put() only on mapped devices
  iio: adc: ad9467: Fix the "don't allow reading vref if not available" case
  iio: adc: at91: call input_free_device() on allocated iio_dev
  iio: adc: ad7173: fix using shared static info struct
  iio: adc: ti-ads124s08: Use gpiod_set_value_cansleep()
  iio: adc: ti-ads1119: fix information leak in triggered buffer
  iio: pressure: zpa2326: fix information leak in triggered buffer
  iio: adc: rockchip_saradc: fix information leak in triggered buffer
  iio: imu: kmx61: fix information leak in triggered buffer
  iio: light: vcnl4035: fix information leak in triggered buffer
  iio: light: bh1745: fix information leak in triggered buffer
  iio: adc: ti-ads8688: fix information leak in triggered buffer
  iio: dummy: iio_simply_dummy_buffer: fix information leak in triggered buffer
  iio: test: Fix GTS test config
  dt-bindings: iio: st-sensors: Re-add IIS2MDC magnetometer
  iio: adc: ti-ads1298: Add NULL check in ads1298_init
  iio: adc: stm32-dfsdm: handle label as an optional property
  iio: adc: ad4695: fix buffered read, single sample timings
  ...
  • Loading branch information
Greg Kroah-Hartman committed Dec 16, 2024
2 parents 78d4f34 + 54d3949 commit 6ffc565
Show file tree
Hide file tree
Showing 27 changed files with 159 additions and 58 deletions.
1 change: 1 addition & 0 deletions Documentation/devicetree/bindings/iio/st,st-sensors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ properties:
- st,lsm9ds0-gyro
- description: STMicroelectronics Magnetometers
enum:
- st,iis2mdc
- st,lis2mdl
- st,lis3mdl-magn
- st,lsm303agr-magn
Expand Down
100 changes: 69 additions & 31 deletions drivers/iio/adc/ad4695.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
#define AD4695_T_WAKEUP_SW_MS 3
#define AD4695_T_REFBUF_MS 100
#define AD4695_T_REGCONFIG_NS 20
#define AD4695_T_SCK_CNV_DELAY_NS 80
#define AD4695_REG_ACCESS_SCLK_HZ (10 * MEGA)

/* Max number of voltage input channels. */
Expand Down Expand Up @@ -132,8 +133,13 @@ struct ad4695_state {
unsigned int vref_mv;
/* Common mode input pin voltage. */
unsigned int com_mv;
/* 1 per voltage and temperature chan plus 1 xfer to trigger 1st CNV */
struct spi_transfer buf_read_xfer[AD4695_MAX_CHANNELS + 2];
/*
* 2 per voltage and temperature chan plus 1 xfer to trigger 1st
* CNV. Excluding the trigger xfer, every 2nd xfer only serves
* to control CS and add a delay between the last SCLK and next
* CNV rising edges.
*/
struct spi_transfer buf_read_xfer[AD4695_MAX_CHANNELS * 2 + 3];
struct spi_message buf_read_msg;
/* Raw conversion data received. */
u8 buf[ALIGN((AD4695_MAX_CHANNELS + 2) * AD4695_MAX_CHANNEL_SIZE,
Expand Down Expand Up @@ -423,7 +429,7 @@ static int ad4695_buffer_preenable(struct iio_dev *indio_dev)
u8 temp_chan_bit = st->chip_info->num_voltage_inputs;
u32 bit, num_xfer, num_slots;
u32 temp_en = 0;
int ret;
int ret, rx_buf_offset = 0;

/*
* We are using the advanced sequencer since it is the only way to read
Expand All @@ -449,11 +455,9 @@ static int ad4695_buffer_preenable(struct iio_dev *indio_dev)
iio_for_each_active_channel(indio_dev, bit) {
xfer = &st->buf_read_xfer[num_xfer];
xfer->bits_per_word = 16;
xfer->rx_buf = &st->buf[(num_xfer - 1) * 2];
xfer->rx_buf = &st->buf[rx_buf_offset];
xfer->len = 2;
xfer->cs_change = 1;
xfer->cs_change_delay.value = AD4695_T_CONVERT_NS;
xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
rx_buf_offset += xfer->len;

if (bit == temp_chan_bit) {
temp_en = 1;
Expand All @@ -468,21 +472,44 @@ static int ad4695_buffer_preenable(struct iio_dev *indio_dev)
}

num_xfer++;

/*
* We need to add a blank xfer in data reads, to meet the timing
* requirement of a minimum delay between the last SCLK rising
* edge and the CS deassert.
*/
xfer = &st->buf_read_xfer[num_xfer];
xfer->delay.value = AD4695_T_SCK_CNV_DELAY_NS;
xfer->delay.unit = SPI_DELAY_UNIT_NSECS;
xfer->cs_change = 1;
xfer->cs_change_delay.value = AD4695_T_CONVERT_NS;
xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;

num_xfer++;
}

/*
* The advanced sequencer requires that at least 2 slots are enabled.
* Since slot 0 is always used for other purposes, we need only 1
* enabled voltage channel to meet this requirement. If the temperature
* channel is the only enabled channel, we need to add one more slot
* in the sequence but not read from it.
* enabled voltage channel to meet this requirement. If the temperature
* channel is the only enabled channel, we need to add one more slot in
* the sequence but not read from it. This is because the temperature
* sensor is sampled at the end of the channel sequence in advanced
* sequencer mode (see datasheet page 38).
*
* From the iio_for_each_active_channel() block above, we now have an
* xfer with data followed by a blank xfer to allow us to meet the
* timing spec, so move both of those up before adding an extra to
* handle the temperature-only case.
*/
if (num_slots < 2) {
/* move last xfer so we can insert one more xfer before it */
st->buf_read_xfer[num_xfer] = *xfer;
/* Move last two xfers */
st->buf_read_xfer[num_xfer] = st->buf_read_xfer[num_xfer - 1];
st->buf_read_xfer[num_xfer - 1] = st->buf_read_xfer[num_xfer - 2];
num_xfer++;

/* modify 2nd to last xfer for extra slot */
/* Modify inserted xfer for extra slot. */
xfer = &st->buf_read_xfer[num_xfer - 3];
memset(xfer, 0, sizeof(*xfer));
xfer->cs_change = 1;
xfer->delay.value = st->chip_info->t_acq_ns;
Expand All @@ -499,6 +526,12 @@ static int ad4695_buffer_preenable(struct iio_dev *indio_dev)
return ret;

num_slots++;

/*
* We still want to point at the last xfer when finished, so
* update the pointer.
*/
xfer = &st->buf_read_xfer[num_xfer - 1];
}

/*
Expand Down Expand Up @@ -583,38 +616,43 @@ static irqreturn_t ad4695_trigger_handler(int irq, void *p)
*/
static int ad4695_read_one_sample(struct ad4695_state *st, unsigned int address)
{
struct spi_transfer xfer[2] = { };
int ret, i = 0;
struct spi_transfer xfers[2] = {
{
.speed_hz = AD4695_REG_ACCESS_SCLK_HZ,
.bits_per_word = 16,
.tx_buf = &st->cnv_cmd,
.len = 2,
},
{
/* Required delay between last SCLK and CNV/CS */
.delay.value = AD4695_T_SCK_CNV_DELAY_NS,
.delay.unit = SPI_DELAY_UNIT_NSECS,
}
};
int ret;

ret = ad4695_set_single_cycle_mode(st, address);
if (ret)
return ret;

/*
* Setting the first channel to the temperature channel isn't supported
* in single-cycle mode, so we have to do an extra xfer to read the
* temperature.
* in single-cycle mode, so we have to do an extra conversion to read
* the temperature.
*/
if (address == AD4695_CMD_TEMP_CHAN) {
/* We aren't reading, so we can make this a short xfer. */
st->cnv_cmd2 = AD4695_CMD_TEMP_CHAN << 3;
xfer[0].tx_buf = &st->cnv_cmd2;
xfer[0].len = 1;
xfer[0].cs_change = 1;
xfer[0].cs_change_delay.value = AD4695_T_CONVERT_NS;
xfer[0].cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;

i = 1;
st->cnv_cmd = AD4695_CMD_TEMP_CHAN << 11;

ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
if (ret)
return ret;
}

/* Then read the result and exit conversion mode. */
st->cnv_cmd = AD4695_CMD_EXIT_CNV_MODE << 11;
xfer[i].bits_per_word = 16;
xfer[i].tx_buf = &st->cnv_cmd;
xfer[i].rx_buf = &st->raw_data;
xfer[i].len = 2;
xfers[0].rx_buf = &st->raw_data;

return spi_sync_transfer(st->spi, xfer, i + 1);
return spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
}

static int ad4695_read_raw(struct iio_dev *indio_dev,
Expand Down
3 changes: 3 additions & 0 deletions drivers/iio/adc/ad7124.c
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,9 @@ static int ad7124_setup(struct ad7124_state *st)
* set all channels to this default value.
*/
ad7124_set_channel_odr(st, i, 10);

/* Disable all channels to prevent unintended conversions. */
ad_sd_write_reg(&st->sd, AD7124_CHANNEL(i), 2, 0);
}

ret = ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, st->adc_control);
Expand Down
10 changes: 6 additions & 4 deletions drivers/iio/adc/ad7173.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ struct ad7173_channel {

struct ad7173_state {
struct ad_sigma_delta sd;
struct ad_sigma_delta_info sigma_delta_info;
const struct ad7173_device_info *info;
struct ad7173_channel *channels;
struct regulator_bulk_data regulators[3];
Expand Down Expand Up @@ -753,7 +754,7 @@ static int ad7173_disable_one(struct ad_sigma_delta *sd, unsigned int chan)
return ad_sd_write_reg(sd, AD7173_REG_CH(chan), 2, 0);
}

static struct ad_sigma_delta_info ad7173_sigma_delta_info = {
static const struct ad_sigma_delta_info ad7173_sigma_delta_info = {
.set_channel = ad7173_set_channel,
.append_status = ad7173_append_status,
.disable_all = ad7173_disable_all,
Expand Down Expand Up @@ -1403,7 +1404,7 @@ static int ad7173_fw_parse_device_config(struct iio_dev *indio_dev)
if (ret < 0)
return dev_err_probe(dev, ret, "Interrupt 'rdy' is required\n");

ad7173_sigma_delta_info.irq_line = ret;
st->sigma_delta_info.irq_line = ret;

return ad7173_fw_parse_channel_config(indio_dev);
}
Expand Down Expand Up @@ -1436,8 +1437,9 @@ static int ad7173_probe(struct spi_device *spi)
spi->mode = SPI_MODE_3;
spi_setup(spi);

ad7173_sigma_delta_info.num_slots = st->info->num_configs;
ret = ad_sd_init(&st->sd, indio_dev, spi, &ad7173_sigma_delta_info);
st->sigma_delta_info = ad7173_sigma_delta_info;
st->sigma_delta_info.num_slots = st->info->num_configs;
ret = ad_sd_init(&st->sd, indio_dev, spi, &st->sigma_delta_info);
if (ret)
return ret;

Expand Down
15 changes: 12 additions & 3 deletions drivers/iio/adc/ad9467.c
Original file line number Diff line number Diff line change
Expand Up @@ -895,14 +895,22 @@ static int ad9467_update_scan_mode(struct iio_dev *indio_dev,
return 0;
}

static struct iio_info ad9467_info = {
static const struct iio_info ad9467_info = {
.read_raw = ad9467_read_raw,
.write_raw = ad9467_write_raw,
.update_scan_mode = ad9467_update_scan_mode,
.debugfs_reg_access = ad9467_reg_access,
.read_avail = ad9467_read_avail,
};

/* Same as above, but without .read_avail */
static const struct iio_info ad9467_info_no_read_avail = {
.read_raw = ad9467_read_raw,
.write_raw = ad9467_write_raw,
.update_scan_mode = ad9467_update_scan_mode,
.debugfs_reg_access = ad9467_reg_access,
};

static int ad9467_scale_fill(struct ad9467_state *st)
{
const struct ad9467_chip_info *info = st->info;
Expand Down Expand Up @@ -1214,11 +1222,12 @@ static int ad9467_probe(struct spi_device *spi)
}

if (st->info->num_scales > 1)
ad9467_info.read_avail = ad9467_read_avail;
indio_dev->info = &ad9467_info;
else
indio_dev->info = &ad9467_info_no_read_avail;
indio_dev->name = st->info->name;
indio_dev->channels = st->info->channels;
indio_dev->num_channels = st->info->num_channels;
indio_dev->info = &ad9467_info;

ret = ad9467_iio_backend_get(st);
if (ret)
Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/adc/at91_adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -979,7 +979,7 @@ static int at91_ts_register(struct iio_dev *idev,
return ret;

err:
input_free_device(st->ts_input);
input_free_device(input);
return ret;
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/iio/adc/rockchip_saradc.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,8 @@ static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p)
int ret;
int i, j = 0;

memset(&data, 0, sizeof(data));

mutex_lock(&info->lock);

iio_for_each_active_channel(i_dev, i) {
Expand Down
13 changes: 8 additions & 5 deletions drivers/iio/adc/stm32-dfsdm-adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -691,11 +691,14 @@ static int stm32_dfsdm_generic_channel_parse_of(struct stm32_dfsdm *dfsdm,
return -EINVAL;
}

ret = fwnode_property_read_string(node, "label", &ch->datasheet_name);
if (ret < 0) {
dev_err(&indio_dev->dev,
" Error parsing 'label' for idx %d\n", ch->channel);
return ret;
if (fwnode_property_present(node, "label")) {
/* label is optional */
ret = fwnode_property_read_string(node, "label", &ch->datasheet_name);
if (ret < 0) {
dev_err(&indio_dev->dev,
" Error parsing 'label' for idx %d\n", ch->channel);
return ret;
}
}

df_ch = &dfsdm->ch_list[ch->channel];
Expand Down
4 changes: 3 additions & 1 deletion drivers/iio/adc/ti-ads1119.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,12 +500,14 @@ static irqreturn_t ads1119_trigger_handler(int irq, void *private)
struct iio_dev *indio_dev = pf->indio_dev;
struct ads1119_state *st = iio_priv(indio_dev);
struct {
unsigned int sample;
s16 sample;
s64 timestamp __aligned(8);
} scan;
unsigned int index;
int ret;

memset(&scan, 0, sizeof(scan));

if (!iio_trigger_using_own(indio_dev)) {
index = find_first_bit(indio_dev->active_scan_mask,
iio_get_masklength(indio_dev));
Expand Down
4 changes: 2 additions & 2 deletions drivers/iio/adc/ti-ads124s08.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,9 @@ static int ads124s_reset(struct iio_dev *indio_dev)
struct ads124s_private *priv = iio_priv(indio_dev);

if (priv->reset_gpio) {
gpiod_set_value(priv->reset_gpio, 0);
gpiod_set_value_cansleep(priv->reset_gpio, 0);
udelay(200);
gpiod_set_value(priv->reset_gpio, 1);
gpiod_set_value_cansleep(priv->reset_gpio, 1);
} else {
return ads124s_write_cmd(indio_dev, ADS124S08_CMD_RESET);
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/iio/adc/ti-ads1298.c
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,8 @@ static int ads1298_init(struct iio_dev *indio_dev)
}
indio_dev->name = devm_kasprintf(dev, GFP_KERNEL, "ads129%u%s",
indio_dev->num_channels, suffix);
if (!indio_dev->name)
return -ENOMEM;

/* Enable internal test signal, double amplitude, double frequency */
ret = regmap_write(priv->regmap, ADS1298_REG_CONFIG2,
Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/adc/ti-ads8688.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ static irqreturn_t ads8688_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
/* Ensure naturally aligned timestamp */
u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)] __aligned(8);
u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)] __aligned(8) = { };
int i, j = 0;

iio_for_each_active_channel(indio_dev, i) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/dummy/iio_simple_dummy_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
int i = 0, j;
u16 *data;

data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
data = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);
if (!data)
goto done;

Expand Down
9 changes: 8 additions & 1 deletion drivers/iio/gyro/fxas21002c_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -730,14 +730,21 @@ static irqreturn_t fxas21002c_trigger_handler(int irq, void *p)
int ret;

mutex_lock(&data->lock);
ret = fxas21002c_pm_get(data);
if (ret < 0)
goto out_unlock;

ret = regmap_bulk_read(data->regmap, FXAS21002C_REG_OUT_X_MSB,
data->buffer, CHANNEL_SCAN_MAX * sizeof(s16));
if (ret < 0)
goto out_unlock;
goto out_pm_put;

iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
data->timestamp);

out_pm_put:
fxas21002c_pm_put(data);

out_unlock:
mutex_unlock(&data->lock);

Expand Down
1 change: 1 addition & 0 deletions drivers/iio/imu/inv_icm42600/inv_icm42600.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ struct inv_icm42600_sensor_state {
typedef int (*inv_icm42600_bus_setup)(struct inv_icm42600_state *);

extern const struct regmap_config inv_icm42600_regmap_config;
extern const struct regmap_config inv_icm42600_spi_regmap_config;
extern const struct dev_pm_ops inv_icm42600_pm_ops;

const struct iio_mount_matrix *
Expand Down
Loading

0 comments on commit 6ffc565

Please sign in to comment.