Skip to content

Commit

Permalink
Merge tag 'iio-fixes-for-5.16b' of https://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/jic23/iio into char-misc-next

Jonathan writes:

2nd set of IIO fixes for 5.16

Note 1st set were before the merge window.

Biggest set in here fix what happens when things go wrong in
the interrupt handlers for an IIO trigger.

Otherwise normal mix of recent and ancient bugs.

trigger core
 - Fix reference counting bug that was preventing the iio_trig
   structures from being released.
adxrs290
 - Correctly sign extend the rate and temperature data.
at91-sama5d2
 - Fix sign extension from the wrong bit and use the scan_type
   values to avoid it being open coded in two places (which were
   out of sync)
axp20x_adc
 - Fix current reporting bit depth.
dln2-adc
 - Fix a lock ordering issue and lockdep complaint that results.
 - Add error handling for failure to register the trigger.
imx8qxp
 - Wrong config dependency
kxcjk-1013
 - Potential leak due to wrong guard on cleanup.
ltr501, kxsd9, stk3310, itg3200, ad7768
 - Don't return error codes from interrupt handler and call
   iio_trigger_notify_done() on all paths to avoid leaving
   trigger disabled on an intermittent fault.
mma8452
 - Fix missing iio_trigger_get() that could lead to use after free.
stm32
 - Fix a current leak.
 - Avoid null pointer derefence on defer_probe error due to wrong
   struct device being passed.
stm32-timer
 - Drop space in MODULE_ALIAS.

* tag 'iio-fixes-for-5.16b' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio:
  iio: trigger: stm32-timer: fix MODULE_ALIAS
  iio: adc: stm32: fix null pointer on defer_probe error
  iio: at91-sama5d2: Fix incorrect sign extension
  iio: adc: axp20x_adc: fix charging current reporting on AXP22x
  iio: gyro: adxrs290: fix data signedness
  iio: ad7768-1: Call iio_trigger_notify_done() on error
  iio: itg3200: Call iio_trigger_notify_done() on error
  iio: imx8qxp-adc: fix dependency to the intended ARCH_MXC config
  iio: dln2: Check return value of devm_iio_trigger_register()
  iio: trigger: Fix reference counting
  iio: dln2-adc: Fix lockdep complaint
  iio: adc: stm32: fix a current leak by resetting pcsel before disabling vdda
  iio: mma8452: Fix trigger reference couting
  iio: stk3310: Don't return error code in interrupt handler
  iio: kxsd9: Don't return error code in trigger handler
  iio: ltr501: Don't return error code in trigger handler
  iio: accel: kxcjk-1013: Fix possible memory leak in probe and remove
  • Loading branch information
Greg Kroah-Hartman committed Dec 8, 2021
2 parents 0edeb89 + 893621e commit 7c602f5
Show file tree
Hide file tree
Showing 15 changed files with 36 additions and 44 deletions.
5 changes: 2 additions & 3 deletions drivers/iio/accel/kxcjk-1013.c
Original file line number Diff line number Diff line change
Expand Up @@ -1595,8 +1595,7 @@ static int kxcjk1013_probe(struct i2c_client *client,
return 0;

err_buffer_cleanup:
if (data->dready_trig)
iio_triggered_buffer_cleanup(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
err_trigger_unregister:
if (data->dready_trig)
iio_trigger_unregister(data->dready_trig);
Expand All @@ -1618,8 +1617,8 @@ static int kxcjk1013_remove(struct i2c_client *client)
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);

iio_triggered_buffer_cleanup(indio_dev);
if (data->dready_trig) {
iio_triggered_buffer_cleanup(indio_dev);
iio_trigger_unregister(data->dready_trig);
iio_trigger_unregister(data->motion_trig);
}
Expand Down
6 changes: 3 additions & 3 deletions drivers/iio/accel/kxsd9.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,14 +224,14 @@ static irqreturn_t kxsd9_trigger_handler(int irq, void *p)
hw_values.chan,
sizeof(hw_values.chan));
if (ret) {
dev_err(st->dev,
"error reading data\n");
return ret;
dev_err(st->dev, "error reading data: %d\n", ret);
goto out;
}

iio_push_to_buffers_with_timestamp(indio_dev,
&hw_values,
iio_get_time_ns(indio_dev));
out:
iio_trigger_notify_done(indio_dev->trig);

return IRQ_HANDLED;
Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/accel/mma8452.c
Original file line number Diff line number Diff line change
Expand Up @@ -1470,7 +1470,7 @@ static int mma8452_trigger_setup(struct iio_dev *indio_dev)
if (ret)
return ret;

indio_dev->trig = trig;
indio_dev->trig = iio_trigger_get(trig);

return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/adc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ config IMX7D_ADC

config IMX8QXP_ADC
tristate "NXP IMX8QXP ADC driver"
depends on ARCH_MXC_ARM64 || COMPILE_TEST
depends on ARCH_MXC || COMPILE_TEST
depends on HAS_IOMEM
help
Say yes here to build support for IMX8QXP ADC.
Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/adc/ad7768-1.c
Original file line number Diff line number Diff line change
Expand Up @@ -480,8 +480,8 @@ static irqreturn_t ad7768_trigger_handler(int irq, void *p)
iio_push_to_buffers_with_timestamp(indio_dev, &st->data.scan,
iio_get_time_ns(indio_dev));

iio_trigger_notify_done(indio_dev->trig);
err_unlock:
iio_trigger_notify_done(indio_dev->trig);
mutex_unlock(&st->lock);

return IRQ_HANDLED;
Expand Down
3 changes: 2 additions & 1 deletion drivers/iio/adc/at91-sama5d2_adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1586,7 +1586,8 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
*val = st->conversion_value;
ret = at91_adc_adjust_val_osr(st, val);
if (chan->scan_type.sign == 's')
*val = sign_extend32(*val, 11);
*val = sign_extend32(*val,
chan->scan_type.realbits - 1);
st->conversion_done = false;
}

Expand Down
18 changes: 3 additions & 15 deletions drivers/iio/adc/axp20x_adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,19 +251,8 @@ static int axp22x_adc_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val)
{
struct axp20x_adc_iio *info = iio_priv(indio_dev);
int size;

/*
* N.B.: Unlike the Chinese datasheets tell, the charging current is
* stored on 12 bits, not 13 bits. Only discharging current is on 13
* bits.
*/
if (chan->type == IIO_CURRENT && chan->channel == AXP22X_BATT_DISCHRG_I)
size = 13;
else
size = 12;

*val = axp20x_read_variable_width(info->regmap, chan->address, size);
*val = axp20x_read_variable_width(info->regmap, chan->address, 12);
if (*val < 0)
return *val;

Expand Down Expand Up @@ -386,9 +375,8 @@ static int axp22x_adc_scale(struct iio_chan_spec const *chan, int *val,
return IIO_VAL_INT_PLUS_MICRO;

case IIO_CURRENT:
*val = 0;
*val2 = 500000;
return IIO_VAL_INT_PLUS_MICRO;
*val = 1;
return IIO_VAL_INT;

case IIO_TEMP:
*val = 100;
Expand Down
21 changes: 12 additions & 9 deletions drivers/iio/adc/dln2-adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,6 @@ static int dln2_adc_set_chan_period(struct dln2_adc *dln2,
static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel)
{
int ret, i;
struct iio_dev *indio_dev = platform_get_drvdata(dln2->pdev);
u16 conflict;
__le16 value;
int olen = sizeof(value);
Expand All @@ -257,13 +256,9 @@ static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel)
.chan = channel,
};

ret = iio_device_claim_direct_mode(indio_dev);
if (ret < 0)
return ret;

ret = dln2_adc_set_chan_enabled(dln2, channel, true);
if (ret < 0)
goto release_direct;
return ret;

ret = dln2_adc_set_port_enabled(dln2, true, &conflict);
if (ret < 0) {
Expand Down Expand Up @@ -300,8 +295,6 @@ static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel)
dln2_adc_set_port_enabled(dln2, false, NULL);
disable_chan:
dln2_adc_set_chan_enabled(dln2, channel, false);
release_direct:
iio_device_release_direct_mode(indio_dev);

return ret;
}
Expand Down Expand Up @@ -337,10 +330,16 @@ static int dln2_adc_read_raw(struct iio_dev *indio_dev,

switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = iio_device_claim_direct_mode(indio_dev);
if (ret < 0)
return ret;

mutex_lock(&dln2->mutex);
ret = dln2_adc_read(dln2, chan->channel);
mutex_unlock(&dln2->mutex);

iio_device_release_direct_mode(indio_dev);

if (ret < 0)
return ret;

Expand Down Expand Up @@ -656,7 +655,11 @@ static int dln2_adc_probe(struct platform_device *pdev)
return -ENOMEM;
}
iio_trigger_set_drvdata(dln2->trig, dln2);
devm_iio_trigger_register(dev, dln2->trig);
ret = devm_iio_trigger_register(dev, dln2->trig);
if (ret) {
dev_err(dev, "failed to register trigger: %d\n", ret);
return ret;
}
iio_trigger_set_immutable(indio_dev, dln2->trig);

ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
Expand Down
3 changes: 2 additions & 1 deletion drivers/iio/adc/stm32-adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,7 @@ static void stm32h7_adc_unprepare(struct iio_dev *indio_dev)
{
struct stm32_adc *adc = iio_priv(indio_dev);

stm32_adc_writel(adc, STM32H7_ADC_PCSEL, 0);
stm32h7_adc_disable(indio_dev);
stm32_adc_int_ch_disable(adc);
stm32h7_adc_enter_pwr_down(adc);
Expand Down Expand Up @@ -1986,7 +1987,7 @@ static int stm32_adc_populate_int_ch(struct iio_dev *indio_dev, const char *ch_n
/* Get calibration data for vrefint channel */
ret = nvmem_cell_read_u16(&indio_dev->dev, "vrefint", &vrefint);
if (ret && ret != -ENOENT) {
return dev_err_probe(&indio_dev->dev, ret,
return dev_err_probe(indio_dev->dev.parent, ret,
"nvmem access error\n");
}
if (ret == -ENOENT)
Expand Down
5 changes: 3 additions & 2 deletions drivers/iio/gyro/adxrs290.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/kernel.h>
Expand Down Expand Up @@ -124,7 +125,7 @@ static int adxrs290_get_rate_data(struct iio_dev *indio_dev, const u8 cmd, int *
goto err_unlock;
}

*val = temp;
*val = sign_extend32(temp, 15);

err_unlock:
mutex_unlock(&st->lock);
Expand All @@ -146,7 +147,7 @@ static int adxrs290_get_temp_data(struct iio_dev *indio_dev, int *val)
}

/* extract lower 12 bits temperature reading */
*val = temp & 0x0FFF;
*val = sign_extend32(temp, 11);

err_unlock:
mutex_unlock(&st->lock);
Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/gyro/itg3200_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p)

iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp);

error_ret:
iio_trigger_notify_done(indio_dev->trig);

error_ret:
return IRQ_HANDLED;
}

Expand Down
1 change: 0 additions & 1 deletion drivers/iio/industrialio-trigger.c
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,6 @@ struct iio_trigger *viio_trigger_alloc(struct device *parent,
irq_modify_status(trig->subirq_base + i,
IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
}
get_device(&trig->dev);

return trig;

Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/light/ltr501.c
Original file line number Diff line number Diff line change
Expand Up @@ -1275,7 +1275,7 @@ static irqreturn_t ltr501_trigger_handler(int irq, void *p)
ret = regmap_bulk_read(data->regmap, LTR501_ALS_DATA1,
als_buf, sizeof(als_buf));
if (ret < 0)
return ret;
goto done;
if (test_bit(0, indio_dev->active_scan_mask))
scan.channels[j++] = le16_to_cpu(als_buf[1]);
if (test_bit(1, indio_dev->active_scan_mask))
Expand Down
6 changes: 3 additions & 3 deletions drivers/iio/light/stk3310.c
Original file line number Diff line number Diff line change
Expand Up @@ -546,9 +546,8 @@ static irqreturn_t stk3310_irq_event_handler(int irq, void *private)
mutex_lock(&data->lock);
ret = regmap_field_read(data->reg_flag_nf, &dir);
if (ret < 0) {
dev_err(&data->client->dev, "register read failed\n");
mutex_unlock(&data->lock);
return ret;
dev_err(&data->client->dev, "register read failed: %d\n", ret);
goto out;
}
event = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1,
IIO_EV_TYPE_THRESH,
Expand All @@ -560,6 +559,7 @@ static irqreturn_t stk3310_irq_event_handler(int irq, void *private)
ret = regmap_field_write(data->reg_flag_psint, 0);
if (ret < 0)
dev_err(&data->client->dev, "failed to reset interrupts\n");
out:
mutex_unlock(&data->lock);

return IRQ_HANDLED;
Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/trigger/stm32-timer-trigger.c
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,6 @@ static struct platform_driver stm32_timer_trigger_driver = {
};
module_platform_driver(stm32_timer_trigger_driver);

MODULE_ALIAS("platform: stm32-timer-trigger");
MODULE_ALIAS("platform:stm32-timer-trigger");
MODULE_DESCRIPTION("STMicroelectronics STM32 Timer Trigger driver");
MODULE_LICENSE("GPL v2");

0 comments on commit 7c602f5

Please sign in to comment.