mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-25 05:00:48 -04:00
Merge tag 'iio-fixes-for-7.1b' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-next
IIO: 2nd set of fixes for the 7.1 cycle. Usual mixed bag of ancient issues and the recently introduced. Various drivers - Ensure use of simple_write_to_buffer() in debugfs callbacks doesn't result in reading off the end of intended data by checking the position is always 0. buffer/hw-consumer - Ensure scan_mask is freed on buffer release. acpi-als - Check ACPI_COMPANION() against NULL to close corner case where a driver is overridden. adi,ad4062 - Add GPIOLIB dependency to avoid undefined ref to gpiochip_get_data() adi.ad7768-1 - Add GPIOLIB dependency to avoid several undefined functions. adi,ad2s1210 - Ensure possible recovery path if a read fails in the interrupt handler. bosch,bmg160 - Increase sleep on startup to ensure device is ready. bosch,bmp280 - Ensure buffer pushed to kfifo is zeroed to avoid leaking uninitialized stack data to userspace. dyna-image,al3010 - Fix refactor that stopped reading one of the two measurement registers. dyna-image,al3320a - Fix refactor that stopped reading one of the two measurement registers. qcom,spmi-iadc - Ensure disable_irq_wake() is called on remove path. sensiron,scd30 - Fix a sign extension bug. st,vl5310x - Ensure possible recovery path if a read fails in the interrupt handler. ti,adc1298 - Bounds check for pga_settings index. Hardening against device returning unexpected values. ti,tmp006 - Ensure trigger correctly released on remove path. vishay,veml6030 - Fix incorrect channel type in events. vishay,veml6074 - Bounds check for veml6075_it_ms. Hardening against device returning unexpected values. * tag 'iio-fixes-for-7.1b' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (23 commits) iio: adc: ad_sigma_delta: fix clear_pending_event for registerless devices iio: adc: ad_sigma_delta: fix CS held asserted and state leaks iio: light: opt3001: fix missing state reset on timeout iio: chemical: scd30: Cleanup initializations and fix sign-extension bug iio: core: fix uninitialized data in debugfs iio: backend: fix uninitialized data in debugfs iio: dac: ad3552r-hs: fix uninitialized data ni ad3552r_hs_write_data_source() iio: adc: qcom-spmi-iadc: balance enable_irq_wake() on driver unbind iio: light: al3320a: read both ALS ADC registers again iio: light: al3010: read both ALS ADC registers again iio: temperature: tmp006: use devm_iio_trigger_register iio: buffer: hw-consumer: free scan_mask on buffer release iio: adc: ad7768-1: Select GPIOLIB iio: light: veml6030: fix channel type when pushing events iio: light: acpi-als: Check ACPI_COMPANION() against NULL iio: resolver: ad2s1210: notify trigger and clear state on fault read error iio: proximity: vl53l0x: notify trigger and clear IRQ on error paths iio: gyro: bmg160: wait full startup time after mode change at probe iio: gyro: bmg160: bail out when bandwidth/filter is not in table iio: pressure: bmp280: zero-init bmp580 trigger handler buffer ...
This commit is contained in:
@@ -78,6 +78,7 @@ config AD4030
|
||||
config AD4062
|
||||
tristate "Analog Devices AD4062 Driver"
|
||||
depends on I3C
|
||||
depends on GPIOLIB
|
||||
select REGMAP_I3C
|
||||
select IIO_BUFFER
|
||||
select IIO_TRIGGERED_BUFFER
|
||||
@@ -430,6 +431,7 @@ config AD7766
|
||||
config AD7768_1
|
||||
tristate "Analog Devices AD7768-1 ADC driver"
|
||||
depends on SPI
|
||||
select GPIOLIB
|
||||
select REGULATOR
|
||||
select REGMAP_SPI
|
||||
select RATIONAL
|
||||
|
||||
@@ -262,11 +262,25 @@ static int ad_sigma_delta_clear_pending_event(struct ad_sigma_delta *sigma_delta
|
||||
|
||||
/*
|
||||
* Read R̅D̅Y̅ pin (if possible) or status register to check if there is an
|
||||
* old event.
|
||||
* old event. For devices with neither an RDY GPIO nor registers,
|
||||
* ad_sd_read_reg() transmits no address byte and clocks raw MISO bytes,
|
||||
* which is indistinguishable from reading conversion data and would
|
||||
* partially consume a pending result. Skip the check for such devices.
|
||||
*
|
||||
* This is safe for all current registerless devices: ad7191 and ad7780
|
||||
* (with powerdown GPIO) are reset between conversions by CS deassertion,
|
||||
* so there is no stale result to drain; ad7780 (without powerdown GPIO)
|
||||
* and max11205 are continuously-converting and cycle ~DRDY at the output
|
||||
* data rate regardless of whether the previous result was read, so the
|
||||
* next falling edge fires naturally.
|
||||
*
|
||||
* A future registerless device that holds ~DRDY asserted until data is
|
||||
* read would be broken by this early return and would need either
|
||||
* num_resetclks set or a rdy-gpio.
|
||||
*/
|
||||
if (sigma_delta->rdy_gpiod) {
|
||||
pending_event = gpiod_get_value(sigma_delta->rdy_gpiod);
|
||||
} else {
|
||||
} else if (sigma_delta->info->has_registers) {
|
||||
unsigned int status_reg;
|
||||
|
||||
ret = ad_sd_read_reg(sigma_delta, AD_SD_REG_STATUS, 1, &status_reg);
|
||||
@@ -274,11 +288,24 @@ static int ad_sigma_delta_clear_pending_event(struct ad_sigma_delta *sigma_delta
|
||||
return ret;
|
||||
|
||||
pending_event = !(status_reg & AD_SD_REG_STATUS_RDY);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pending_event)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* With num_resetclks = 0, data_read_len is 0 and the drain sequence
|
||||
* below would compute memset(data + 2, 0xff, 0 - 1), underflowing to
|
||||
* SIZE_MAX and corrupting the heap. There is no safe way to drain the
|
||||
* stale result without knowing the data register size; it will be
|
||||
* consumed by the first ad_sd_read_reg() call in
|
||||
* ad_sigma_delta_single_conversion().
|
||||
*/
|
||||
if (!data_read_len)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* In general the size of the data register is unknown. It varies from
|
||||
* device to device, might be one byte longer if CONTROL.DATA_STATUS is
|
||||
@@ -441,11 +468,10 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
|
||||
out:
|
||||
ad_sd_disable_irq(sigma_delta);
|
||||
|
||||
ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
|
||||
ad_sigma_delta_disable_one(sigma_delta, chan->address);
|
||||
|
||||
out_unlock:
|
||||
sigma_delta->keep_cs_asserted = false;
|
||||
ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
|
||||
ad_sigma_delta_disable_one(sigma_delta, chan->address);
|
||||
sigma_delta->bus_locked = false;
|
||||
spi_bus_unlock(sigma_delta->spi->controller);
|
||||
out_release:
|
||||
@@ -578,6 +604,9 @@ static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
|
||||
return 0;
|
||||
|
||||
err_unlock:
|
||||
sigma_delta->keep_cs_asserted = false;
|
||||
ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
|
||||
sigma_delta->bus_locked = false;
|
||||
spi_bus_unlock(sigma_delta->spi->controller);
|
||||
spi_unoptimize_message(&sigma_delta->sample_msg);
|
||||
|
||||
|
||||
@@ -481,6 +481,11 @@ static const struct iio_chan_spec iadc_channels[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static void iadc_disable_irq_wake(void *data)
|
||||
{
|
||||
disable_irq_wake((unsigned long)data);
|
||||
}
|
||||
|
||||
static int iadc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
@@ -538,9 +543,16 @@ static int iadc_probe(struct platform_device *pdev)
|
||||
if (!iadc->poll_eoc) {
|
||||
ret = devm_request_irq(dev, irq_eoc, iadc_isr, 0,
|
||||
"spmi-iadc", iadc);
|
||||
if (!ret)
|
||||
enable_irq_wake(irq_eoc);
|
||||
else
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = enable_irq_wake(irq_eoc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, iadc_disable_irq_wake,
|
||||
(void *)(unsigned long)irq_eoc);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
ret = devm_device_init_wakeup(iadc->dev);
|
||||
|
||||
@@ -281,6 +281,7 @@ static const u8 ads1298_pga_settings[] = { 6, 1, 2, 3, 4, 8, 12 };
|
||||
static int ads1298_get_scale(struct ads1298_private *priv,
|
||||
int channel, int *val, int *val2)
|
||||
{
|
||||
unsigned int pga_idx;
|
||||
int ret;
|
||||
unsigned int regval;
|
||||
u8 gain;
|
||||
@@ -304,7 +305,11 @@ static int ads1298_get_scale(struct ads1298_private *priv,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
gain = ads1298_pga_settings[FIELD_GET(ADS1298_MASK_CH_PGA, regval)];
|
||||
pga_idx = FIELD_GET(ADS1298_MASK_CH_PGA, regval);
|
||||
if (pga_idx >= ARRAY_SIZE(ads1298_pga_settings))
|
||||
return -EINVAL;
|
||||
|
||||
gain = ads1298_pga_settings[pga_idx];
|
||||
*val /= gain; /* Full scale is VREF / gain */
|
||||
|
||||
*val2 = ADS1298_BITS_PER_SAMPLE - 1; /* Signed, hence the -1 */
|
||||
|
||||
@@ -40,6 +40,8 @@ static void iio_hw_buf_release(struct iio_buffer *buffer)
|
||||
{
|
||||
struct hw_consumer_buffer *hw_buf =
|
||||
iio_buffer_to_hw_consumer_buffer(buffer);
|
||||
|
||||
bitmap_free(buffer->scan_mask);
|
||||
kfree(hw_buf);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
*
|
||||
* Copyright (c) 2020 Tomasz Duszynski <tomasz.duszynski@octakon.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/completion.h>
|
||||
@@ -43,6 +45,11 @@
|
||||
#define SCD30_TEMP_OFFSET_MAX 655360
|
||||
#define SCD30_EXTRA_TIMEOUT_PER_S 250
|
||||
|
||||
/* Floating point arithmetic macros */
|
||||
#define SCD30_FLOAT_MANTISSA_MSK GENMASK(22, 0)
|
||||
#define SCD30_FLOAT_EXP_MSK GENMASK(30, 23)
|
||||
#define SCD30_FLOAT_SIGN_MSK BIT(31)
|
||||
|
||||
enum {
|
||||
SCD30_CONC,
|
||||
SCD30_TEMP,
|
||||
@@ -89,10 +96,14 @@ static int scd30_reset(struct scd30_state *state)
|
||||
/* simplified float to fixed point conversion with a scaling factor of 0.01 */
|
||||
static int scd30_float_to_fp(int float32)
|
||||
{
|
||||
int fraction, shift,
|
||||
mantissa = float32 & GENMASK(22, 0),
|
||||
sign = (float32 & BIT(31)) ? -1 : 1,
|
||||
exp = (float32 & ~BIT(31)) >> 23;
|
||||
int fraction, shift, sign;
|
||||
int mantissa = FIELD_GET(SCD30_FLOAT_MANTISSA_MSK, float32);
|
||||
int exp = FIELD_GET(SCD30_FLOAT_EXP_MSK, float32);
|
||||
|
||||
if (float32 & SCD30_FLOAT_SIGN_MSK)
|
||||
sign = -1;
|
||||
else
|
||||
sign = 1;
|
||||
|
||||
/* special case 0 */
|
||||
if (!exp && !mantissa)
|
||||
|
||||
@@ -549,7 +549,7 @@ static ssize_t ad3552r_hs_write_data_source(struct file *f,
|
||||
|
||||
guard(mutex)(&st->lock);
|
||||
|
||||
if (count >= sizeof(buf))
|
||||
if (*ppos != 0 || count >= sizeof(buf))
|
||||
return -ENOSPC;
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, userbuf,
|
||||
|
||||
@@ -201,6 +201,9 @@ static int bmg160_get_filter(struct bmg160_data *data, int *val)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(bmg160_samp_freq_table))
|
||||
return -EINVAL;
|
||||
|
||||
*val = bmg160_samp_freq_table[i].filter;
|
||||
|
||||
return ret ? ret : IIO_VAL_INT;
|
||||
@@ -218,6 +221,9 @@ static int bmg160_set_filter(struct bmg160_data *data, int val)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(bmg160_samp_freq_table))
|
||||
return -EINVAL;
|
||||
|
||||
ret = regmap_write(data->regmap, BMG160_REG_PMU_BW,
|
||||
bmg160_samp_freq_table[i].bw_bits);
|
||||
if (ret < 0) {
|
||||
@@ -258,8 +264,14 @@ static int bmg160_chip_init(struct bmg160_data *data)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Wait upto 500 ms to be ready after changing mode */
|
||||
usleep_range(500, 1000);
|
||||
/*
|
||||
* Wait for the chip to be ready after switching to normal mode.
|
||||
* The BMG160 datasheet (BST-BMG160-DS000-07 Rev. 1.0, May 2013)
|
||||
* specifies a start-up / wake-up time (tsu, twusm) of 30 ms; use
|
||||
* BMG160_MAX_STARTUP_TIME_MS (80 ms) as a safety margin, matching
|
||||
* what bmg160_runtime_resume() already does.
|
||||
*/
|
||||
msleep(BMG160_MAX_STARTUP_TIME_MS);
|
||||
|
||||
/* Set Bandwidth */
|
||||
ret = bmg160_set_bw(data, BMG160_DEF_BW);
|
||||
|
||||
@@ -156,7 +156,7 @@ static ssize_t iio_backend_debugfs_write_reg(struct file *file,
|
||||
ssize_t rc;
|
||||
int ret;
|
||||
|
||||
if (count >= sizeof(buf))
|
||||
if (*ppos != 0 || count >= sizeof(buf))
|
||||
return -ENOSPC;
|
||||
|
||||
rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, userbuf, count);
|
||||
|
||||
@@ -420,7 +420,7 @@ static ssize_t iio_debugfs_write_reg(struct file *file,
|
||||
char buf[80];
|
||||
int ret;
|
||||
|
||||
if (count >= sizeof(buf))
|
||||
if (*ppos != 0 || count >= sizeof(buf))
|
||||
return -EINVAL;
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, userbuf,
|
||||
|
||||
@@ -179,11 +179,15 @@ static irqreturn_t acpi_als_trigger_handler(int irq, void *p)
|
||||
static int acpi_als_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct acpi_device *device = ACPI_COMPANION(dev);
|
||||
struct acpi_device *device;
|
||||
struct iio_dev *indio_dev;
|
||||
struct acpi_als *als;
|
||||
int ret;
|
||||
|
||||
device = ACPI_COMPANION(dev);
|
||||
if (!device)
|
||||
return -ENODEV;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(dev, sizeof(*als));
|
||||
if (!indio_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -111,7 +111,8 @@ static int al3010_read_raw(struct iio_dev *indio_dev,
|
||||
int *val2, long mask)
|
||||
{
|
||||
struct al3010_data *data = iio_priv(indio_dev);
|
||||
int ret, gain, raw;
|
||||
int ret, gain;
|
||||
__le16 raw;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
@@ -120,11 +121,12 @@ static int al3010_read_raw(struct iio_dev *indio_dev,
|
||||
* - low byte of output is stored at AL3010_REG_DATA_LOW
|
||||
* - high byte of output is stored at AL3010_REG_DATA_LOW + 1
|
||||
*/
|
||||
ret = regmap_read(data->regmap, AL3010_REG_DATA_LOW, &raw);
|
||||
ret = regmap_bulk_read(data->regmap, AL3010_REG_DATA_LOW,
|
||||
&raw, sizeof(raw));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*val = raw;
|
||||
*val = le16_to_cpu(raw);
|
||||
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
|
||||
@@ -135,7 +135,8 @@ static int al3320a_read_raw(struct iio_dev *indio_dev,
|
||||
int *val2, long mask)
|
||||
{
|
||||
struct al3320a_data *data = iio_priv(indio_dev);
|
||||
int ret, gain, raw;
|
||||
int ret, gain;
|
||||
__le16 raw;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
@@ -144,11 +145,12 @@ static int al3320a_read_raw(struct iio_dev *indio_dev,
|
||||
* - low byte of output is stored at AL3320A_REG_DATA_LOW
|
||||
* - high byte of output is stored at AL3320A_REG_DATA_LOW + 1
|
||||
*/
|
||||
ret = regmap_read(data->regmap, AL3320A_REG_DATA_LOW, &raw);
|
||||
ret = regmap_bulk_read(data->regmap, AL3320A_REG_DATA_LOW,
|
||||
&raw, sizeof(raw));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*val = raw;
|
||||
*val = le16_to_cpu(raw);
|
||||
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
|
||||
@@ -366,8 +366,10 @@ static int opt3001_get_processed(struct opt3001 *opt, int *val, int *val2)
|
||||
ret = wait_event_timeout(opt->result_ready_queue,
|
||||
opt->result_ready,
|
||||
msecs_to_jiffies(OPT3001_RESULT_READY_LONG));
|
||||
if (ret == 0)
|
||||
return -ETIMEDOUT;
|
||||
if (ret == 0) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
/* Sleep for result ready time */
|
||||
timeout = (opt->int_time == OPT3001_INT_TIME_SHORT) ?
|
||||
|
||||
@@ -871,9 +871,11 @@ static irqreturn_t veml6030_event_handler(int irq, void *private)
|
||||
else
|
||||
evtdir = IIO_EV_DIR_FALLING;
|
||||
|
||||
iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_INTENSITY,
|
||||
0, IIO_EV_TYPE_THRESH, evtdir),
|
||||
iio_get_time_ns(indio_dev));
|
||||
iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
|
||||
0,
|
||||
IIO_EV_TYPE_THRESH,
|
||||
evtdir),
|
||||
iio_get_time_ns(indio_dev));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ static const struct iio_chan_spec veml6075_channels[] = {
|
||||
|
||||
static int veml6075_request_measurement(struct veml6075_data *data)
|
||||
{
|
||||
int ret, conf, int_time;
|
||||
int ret, conf, int_time, int_index;
|
||||
|
||||
ret = regmap_read(data->regmap, VEML6075_CMD_CONF, &conf);
|
||||
if (ret < 0)
|
||||
@@ -117,7 +117,11 @@ static int veml6075_request_measurement(struct veml6075_data *data)
|
||||
* time for all possible configurations. Using a 1.50 factor simplifies
|
||||
* operations and ensures reliability under all circumstances.
|
||||
*/
|
||||
int_time = veml6075_it_ms[FIELD_GET(VEML6075_CONF_IT, conf)];
|
||||
int_index = FIELD_GET(VEML6075_CONF_IT, conf);
|
||||
if (int_index >= ARRAY_SIZE(veml6075_it_ms))
|
||||
return -EINVAL;
|
||||
|
||||
int_time = veml6075_it_ms[int_index];
|
||||
msleep(int_time + (int_time / 2));
|
||||
|
||||
/* shutdown again, data registers are still accessible */
|
||||
|
||||
@@ -1910,7 +1910,7 @@ static irqreturn_t bmp380_trigger_handler(int irq, void *p)
|
||||
u32 comp_press;
|
||||
s32 comp_temp;
|
||||
aligned_s64 timestamp;
|
||||
} buffer;
|
||||
} buffer = { };
|
||||
int ret;
|
||||
|
||||
guard(mutex)(&data->lock);
|
||||
|
||||
@@ -87,15 +87,14 @@ static irqreturn_t vl53l0x_trigger_handler(int irq, void *priv)
|
||||
ret = i2c_smbus_read_i2c_block_data(data->client,
|
||||
VL_REG_RESULT_RANGE_STATUS,
|
||||
sizeof(buffer), buffer);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
else if (ret != 12)
|
||||
return -EREMOTEIO;
|
||||
if (ret != 12)
|
||||
goto done;
|
||||
|
||||
scan.chan = get_unaligned_be16(&buffer[10]);
|
||||
iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan),
|
||||
iio_get_time_ns(indio_dev));
|
||||
|
||||
done:
|
||||
iio_trigger_notify_done(indio_dev->trig);
|
||||
vl53l0x_clear_irq(data);
|
||||
|
||||
|
||||
@@ -1334,7 +1334,7 @@ static irqreturn_t ad2s1210_trigger_handler(int irq, void *p)
|
||||
|
||||
ret = regmap_read(st->regmap, AD2S1210_REG_FAULT, ®_val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto error_ret;
|
||||
|
||||
st->sample.fault = reg_val;
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ static int tmp006_probe(struct i2c_client *client)
|
||||
|
||||
data->drdy_trig->ops = &tmp006_trigger_ops;
|
||||
iio_trigger_set_drvdata(data->drdy_trig, indio_dev);
|
||||
ret = iio_trigger_register(data->drdy_trig);
|
||||
ret = devm_iio_trigger_register(&client->dev, data->drdy_trig);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user