IIO: 2nd set of fixes for the 7.2 cycle.

Given timing these are probably now merge window material.
 
 Usual mixed bunch of ancient issues and newer ones.
 
 core,buffer
 - Fix a potential UAF in release on anonymous buffers.
 - Make sure DMA fence lock lifetime matches that of the DMA fence.
 - Make IIO DMA fence release RCU safe.
 various
 - Kconfig missing REGMAP* related selects.
 - Unbalance of runtime pm or regulators in error paths.
 
 adi,ad3552r-hs
 - Fixing wrong buffers size for string printing.
 adi,ad4080
 - Fix 16-bit part support by adding path to tell the backend what
   the data size is - avoiding corrupted data capture.
 adi,ad5446
 - Wrong MODULE_DEVICE_TABLE() type due to case error.
 atlas,sensor
 - Drop use of irq_work() in favour of iio_trigger_poll_nested() avoiding
   a possible UAF.
 hid-temperature
 - Potential release ordering issue due to mixed devm and not that
   can lead to long timeouts.
 infineon,dps310
 - Fix NULL dereference on ACPI platforms.
 invense,mpu3050
 - Fix sign of raw angular velocity readings.
 mitsubishi,m62332
 - Fix a regulator reference counting issue when switching channels.
 sharp,gp2ap002
 - Unbalanced runtime PM on repeated event writes.
 - Reenable irq if runtime suspend fails.
 ti,ads7138
 - Disable statistics gathering whilst reading conversions results
   to avoid data corruption.
 ti,opt4001
 - Ensure integration times with integer part are rejected rather than
   ignoring the integer part of the value.
 - Fix use of wrong register.
 - Pointer type mismatch to div_u64_rem()
 - Fix reversed GENMASK() arguements.
 ti,opt4060
 - Ensure integration times with integer part are rejected rather than
   ignoring the integer part of the value.
 - Pointer type mismatch to div_u64_rem()
 - Wrong register name in an error print.
 ti,pac1921
 - Fix wrong channel used in the trigger handler for some combinations
   of enabled channels.
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCgAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAmp2YZMRHGppYzIzQGtl
 cm5lbC5vcmcACgkQVIU0mcT0FohoXg//bpUQOCkNkpSK1ZZsB37N6bE8vru1UenU
 a2W8A6KW22BWQ3ibrmt/rm/5kwlx9BM8v+CuU11pbtFpsa5whF3errsRYf1KiQCC
 axbQhPgXlt09YYeDFgOXCkcrfVzW/PAqUmWsaKRPXkCQ5DKT6JNxKa4tIvwdDceL
 5+bq7AeU5w2k5kw91Ro/XCCdy0eRO1yWOJz1rDsDD68s4a+yMyhPzljyz5z/0ngT
 sX/AMEf0Ykcs8rdr7hi6GTPI5+x0bMlWWI1RLLDpvsgNU575CRFrktYwtz6HVD5b
 2p8fdHWJRLZOhMZV+VEqhEpkwXsEF7YBIj6/jgyOHo1tYGwKPeWNz9KJ5n13mLbx
 kqI/lyK/DMX8llMPkoFtjqqT0meY6KOApiySCzGd3+r00D9OWvX4NWvC/kuwezyI
 7xt9mjJpco5vj2GL4mPjSEOXbgylidCErSz4QaM9URZopp1xa7ID5ELEiH0bjvr0
 4v551XYEubeKxHWsvrk5uDQfrbeW0OFGYxe6Y7nNkWTVItIkbO9cLvqgqh2aeeID
 Vhdpr9Z4cHS6kXX7LzXYeWV6DMgSRJRgidKHWwXSIZtw3afc3VOai0LYho+9aLTq
 L4RB6BZ7yUPvNkZlloX7/wWc7CpVX6VF9J9s7speyB5UXL4kKvPzcETrQnqruq8O
 BCAFbiMn7Tg=
 =N4R+
 -----END PGP SIGNATURE-----

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

Jonathan writes:

IIO: 2nd set of fixes for the 7.2 cycle.

Given timing these are probably now merge window material.

Usual mixed bunch of ancient issues and newer ones.

core,buffer
- Fix a potential UAF in release on anonymous buffers.
- Make sure DMA fence lock lifetime matches that of the DMA fence.
- Make IIO DMA fence release RCU safe.
various
- Kconfig missing REGMAP* related selects.
- Unbalance of runtime pm or regulators in error paths.

adi,ad3552r-hs
- Fixing wrong buffers size for string printing.
adi,ad4080
- Fix 16-bit part support by adding path to tell the backend what
  the data size is - avoiding corrupted data capture.
adi,ad5446
- Wrong MODULE_DEVICE_TABLE() type due to case error.
atlas,sensor
- Drop use of irq_work() in favour of iio_trigger_poll_nested() avoiding
  a possible UAF.
hid-temperature
- Potential release ordering issue due to mixed devm and not that
  can lead to long timeouts.
infineon,dps310
- Fix NULL dereference on ACPI platforms.
invense,mpu3050
- Fix sign of raw angular velocity readings.
mitsubishi,m62332
- Fix a regulator reference counting issue when switching channels.
sharp,gp2ap002
- Unbalanced runtime PM on repeated event writes.
- Reenable irq if runtime suspend fails.
ti,ads7138
- Disable statistics gathering whilst reading conversions results
  to avoid data corruption.
ti,opt4001
- Ensure integration times with integer part are rejected rather than
  ignoring the integer part of the value.
- Fix use of wrong register.
- Pointer type mismatch to div_u64_rem()
- Fix reversed GENMASK() arguements.
ti,opt4060
- Ensure integration times with integer part are rejected rather than
  ignoring the integer part of the value.
- Pointer type mismatch to div_u64_rem()
- Wrong register name in an error print.
ti,pac1921
- Fix wrong channel used in the trigger handler for some combinations
  of enabled channels.

* tag 'iio-fixes-for-7.2b-take2' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (31 commits)
  iio: chemical: atlas-sensor: use iio_trigger_poll_nested() to fix remove UAF
  iio: adc: pac1921: fix wrong channel used in trigger handler read
  iio: light: gp2ap002: re-enable irq if runtime suspend fails
  iio: light: gp2ap002: Fix unbalanced runtime PM on repeated event writes
  iio: light: apds9306: fix PM reference leak in apds9306_read_data()
  iio: gyro: mpu3050: fix sign of raw angular velocity readings
  iio: srf04: fix pm_runtime handling on probe error path
  iio: adc: ad4080: configure backend data size
  iio: adc: adi-axi-adc: add data size support for AD408X backend
  iio: chemical: atlas-sensor: fix PM reference leak in buffer postenable
  iio: dac: ad5446: fix OF module device table
  iio: light: opt4001: Fix reversed GENMASK() arguments in fault count mask
  iio: light: opt4001: Reject integration times with a non-zero seconds part
  iio: light: opt4001: Fix incompatible pointer type passed to div_u64_rem()
  iio: light: opt4001: Fix power down clearing bits of the wrong register
  iio: light: opt4060: Fix incorrect register name in threshold read error message
  iio: light: opt4060: Fix pointer type passed to div_u64_rem()
  iio: light: opt4060: Reject integration times with a non-zero seconds part
  iio: light: ltrf216a: fix runtime PM reference leak in error path
  iio: pressure: dps310: fix NULL pointer dereference on ACPI probe
  ...
This commit is contained in:
Greg Kroah-Hartman 2026-08-19 09:43:39 +02:00
commit 05fa77078b
20 changed files with 156 additions and 94 deletions

View File

@ -1076,6 +1076,7 @@ config MAX1363
config MAX14001
tristate "Analog Devices MAX14001/MAX14002 ADC driver"
depends on SPI
select REGMAP
help
Say yes here to build support for Analog Devices MAX14001/MAX14002
Configurable, Isolated 10-bit ADCs for Multi-Range Binary Inputs.
@ -1086,6 +1087,7 @@ config MAX14001
config MAX34408
tristate "Maxim max34408/max344089 ADC driver"
depends on I2C
select REGMAP_I2C
help
Say yes here to build support for Maxim max34408/max34409 current sense
monitor with 8-bits ADC interface with overcurrent delay/threshold and

View File

@ -697,6 +697,11 @@ static int ad4080_setup_channel(struct ad4080_state *st, unsigned int ch)
if (ret)
return ret;
ret = iio_backend_data_size_set(st->back[ch],
st->info->channels[0].scan_type.realbits);
if (ret)
return ret;
if (!st->lvds_cnv_en)
return 0;

View File

@ -53,6 +53,10 @@
#define AXI_AD485X_PACKET_FORMAT_24BIT 0x1
#define AXI_AD485X_PACKET_FORMAT_32BIT 0x2
#define AXI_AD408X_CNTRL_3_FILTER_EN_MSK BIT(0)
#define AXI_AD408X_CNTRL_3_PACKET_FORMAT_MSK GENMASK(3, 2)
#define AXI_AD408X_PACKET_FORMAT_20BIT 0x0
#define AXI_AD408X_PACKET_FORMAT_16BIT 0x1
#define AXI_AD408X_PACKET_FORMAT_14BIT 0x2
#define ADI_AXI_ADC_REG_SYNC_STATUS 0x0068
#define ADI_AXI_ADC_SYNC_STATUS_ADC_SYNC_MSK BIT(0)
@ -436,6 +440,31 @@ static int axi_adc_ad408x_filter_type_set(struct iio_backend *back,
AXI_AD408X_CNTRL_3_FILTER_EN_MSK);
}
static int axi_adc_ad408x_data_size_set(struct iio_backend *back,
unsigned int size)
{
struct adi_axi_adc_state *st = iio_backend_get_priv(back);
unsigned int val;
switch (size) {
case 20:
val = AXI_AD408X_PACKET_FORMAT_20BIT;
break;
case 16:
val = AXI_AD408X_PACKET_FORMAT_16BIT;
break;
case 14:
val = AXI_AD408X_PACKET_FORMAT_14BIT;
break;
default:
return -EINVAL;
}
return regmap_update_bits(st->regmap, ADI_AXI_ADC_REG_CNTRL_3,
AXI_AD408X_CNTRL_3_PACKET_FORMAT_MSK,
FIELD_PREP(AXI_AD408X_CNTRL_3_PACKET_FORMAT_MSK, val));
}
static int axi_adc_ad408x_interface_data_align(struct iio_backend *back,
u32 timeout_us)
{
@ -659,6 +688,7 @@ static const struct iio_backend_ops adi_ad408x_ops = {
.free_buffer = axi_adc_free_buffer,
.data_sample_trigger = axi_adc_data_sample_trigger,
.filter_type_set = axi_adc_ad408x_filter_type_set,
.data_size_set = axi_adc_ad408x_data_size_set,
.interface_data_align = axi_adc_ad408x_interface_data_align,
.num_lanes_set = axi_adc_num_lanes_set,
.debugfs_reg_access = iio_backend_debugfs_ptr(axi_adc_reg_access),

View File

@ -1037,7 +1037,7 @@ static irqreturn_t pac1921_trigger_handler(int irq, void *p)
iio_for_each_active_channel(idev, bit) {
u16 val;
ret = pac1921_read_res(priv, idev->channels[ch].address, &val);
ret = pac1921_read_res(priv, idev->channels[bit].address, &val);
if (ret)
goto done;

View File

@ -227,6 +227,26 @@ static int ads7138_osr_to_bits(int osr)
return -EINVAL;
}
static int ads7138_read_statistics(const struct i2c_client *client, u8 reg,
u8 *out_values, u8 length)
{
int ret;
/* Disable statistics update so the value is not updated mid read */
ret = ads7138_i2c_clear_bit(client, ADS7138_REG_GENERAL_CFG,
ADS7138_GENERAL_CFG_STATS_EN);
if (ret)
return ret;
ret = ads7138_i2c_read_block(client, reg, out_values, length);
if (ret)
return ret;
/* Enable statistics update after read */
return ads7138_i2c_set_bit(client, ADS7138_REG_GENERAL_CFG,
ADS7138_GENERAL_CFG_STATS_EN);
}
static int ads7138_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val,
int *val2, long mask)
@ -236,28 +256,32 @@ static int ads7138_read_raw(struct iio_dev *indio_dev,
u8 values[2];
switch (mask) {
/*
* Reading the statistics registers reinitializes them. This is
* unfortunate but necessary to prevent data races.
*/
case IIO_CHAN_INFO_RAW:
ret = ads7138_i2c_read_block(data->client,
ADS7138_REG_RECENT_LSB_CH(chan->channel),
values, ARRAY_SIZE(values));
ret = ads7138_read_statistics(data->client,
ADS7138_REG_RECENT_LSB_CH(chan->channel),
values, ARRAY_SIZE(values));
if (ret)
return ret;
*val = get_unaligned_le16(values);
return IIO_VAL_INT;
case IIO_CHAN_INFO_PEAK:
ret = ads7138_i2c_read_block(data->client,
ADS7138_REG_MAX_LSB_CH(chan->channel),
values, ARRAY_SIZE(values));
ret = ads7138_read_statistics(data->client,
ADS7138_REG_MAX_LSB_CH(chan->channel),
values, ARRAY_SIZE(values));
if (ret)
return ret;
*val = get_unaligned_le16(values);
return IIO_VAL_INT;
case IIO_CHAN_INFO_TROUGH:
ret = ads7138_i2c_read_block(data->client,
ADS7138_REG_MIN_LSB_CH(chan->channel),
values, ARRAY_SIZE(values));
ret = ads7138_read_statistics(data->client,
ADS7138_REG_MIN_LSB_CH(chan->channel),
values, ARRAY_SIZE(values));
if (ret)
return ret;

View File

@ -13,7 +13,6 @@
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/irq.h>
#include <linux/irq_work.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/iio/iio.h>
@ -87,7 +86,6 @@ struct atlas_data {
struct iio_trigger *trig;
const struct atlas_device *chip;
struct regmap *regmap;
struct irq_work work;
unsigned int interrupt_enabled;
/* 96-bit data + 32-bit pad + 64-bit timestamp */
__be32 buffer[6] __aligned(8);
@ -412,7 +410,11 @@ static int atlas_buffer_postenable(struct iio_dev *indio_dev)
if (ret)
return ret;
return atlas_set_interrupt(data, true);
ret = atlas_set_interrupt(data, true);
if (ret)
pm_runtime_put_autosuspend(&data->client->dev);
return ret;
}
static int atlas_buffer_predisable(struct iio_dev *indio_dev)
@ -436,13 +438,6 @@ static const struct iio_buffer_setup_ops atlas_buffer_setup_ops = {
.predisable = atlas_buffer_predisable,
};
static void atlas_work_handler(struct irq_work *work)
{
struct atlas_data *data = container_of(work, struct atlas_data, work);
iio_trigger_poll(data->trig);
}
static irqreturn_t atlas_trigger_handler(int irq, void *private)
{
struct iio_poll_func *pf = private;
@ -469,7 +464,7 @@ static irqreturn_t atlas_interrupt_handler(int irq, void *private)
struct iio_dev *indio_dev = private;
struct atlas_data *data = iio_priv(indio_dev);
irq_work_queue(&data->work);
iio_trigger_poll_nested(data->trig);
return IRQ_HANDLED;
}
@ -665,8 +660,6 @@ static int atlas_probe(struct i2c_client *client)
goto unregister_trigger;
}
init_irq_work(&data->work, atlas_work_handler);
if (client->irq > 0) {
/* interrupt pin toggles on new conversion */
ret = devm_request_threaded_irq(&client->dev, client->irq,

View File

@ -552,6 +552,7 @@ config MCP4728
config MCP47FEB02
tristate "MCP47F(E/V)B01/02/04/08/11/12/14/18/21/22/24/28 DAC driver"
depends on I2C
select REGMAP_I2C
help
Say yes here if you want to build the driver for the Microchip:
- 8-bit DAC:

View File

@ -590,7 +590,7 @@ static ssize_t ad3552r_hs_show_data_source_avail(struct file *f,
int i;
for (i = 0; i < ARRAY_SIZE(dbgfs_attr_source); i++) {
len += scnprintf(buf + len, PAGE_SIZE - len, "%s ",
len += scnprintf(buf + len, sizeof(buf) - len, "%s ",
dbgfs_attr_source[i]);
}
buf[len - 1] = '\n';

View File

@ -83,7 +83,7 @@ static const struct of_device_id ad5446_i2c_of_ids[] = {
{ .compatible = "adi,ad5622", .data = &ad5622_chip_info },
{ }
};
MODULE_DEVICE_TABLE(OF, ad5446_i2c_of_ids);
MODULE_DEVICE_TABLE(of, ad5446_i2c_of_ids);
static struct i2c_driver ad5446_i2c_driver = {
.driver = {

View File

@ -32,6 +32,7 @@ static int m62332_set_value(struct iio_dev *indio_dev, u8 val, int channel)
{
struct m62332_data *data = iio_priv(indio_dev);
struct i2c_client *client = data->client;
bool enabling, disabling;
u8 outbuf[2];
int res;
@ -43,7 +44,10 @@ static int m62332_set_value(struct iio_dev *indio_dev, u8 val, int channel)
mutex_lock(&data->mutex);
if (val) {
enabling = val && !data->raw[channel];
disabling = !val && data->raw[channel];
if (enabling) {
res = regulator_enable(data->vcc);
if (res)
goto out;
@ -52,14 +56,17 @@ static int m62332_set_value(struct iio_dev *indio_dev, u8 val, int channel)
res = i2c_master_send(client, outbuf, ARRAY_SIZE(outbuf));
if (res >= 0 && res != ARRAY_SIZE(outbuf))
res = -EIO;
if (res < 0)
if (res < 0) {
if (enabling)
regulator_disable(data->vcc);
goto out;
}
if (disabling)
regulator_disable(data->vcc);
data->raw[channel] = val;
if (!val)
regulator_disable(data->vcc);
mutex_unlock(&data->mutex);
return 0;

View File

@ -356,7 +356,7 @@ static int mpu3050_read_raw(struct iio_dev *indio_dev,
goto out_read_raw_unlock;
}
*val = be16_to_cpu(raw_val);
*val = (s16)be16_to_cpu(raw_val);
ret = IIO_VAL_INT;
goto out_read_raw_unlock;

View File

@ -47,9 +47,6 @@ struct iio_dmabuf_priv {
u64 context;
/* Spinlock used for locking the dma_fence */
spinlock_t lock;
struct dma_buf_attachment *attach;
struct sg_table *sgt;
enum dma_data_direction dir;
@ -57,7 +54,12 @@ struct iio_dmabuf_priv {
};
struct iio_dma_fence {
/*
* Must remain the first member so the default release callback can pass
* the fence directly to dma_fence_free().
*/
struct dma_fence base;
spinlock_t lock; /* protects base */
struct iio_dmabuf_priv *priv;
struct work_struct work;
};
@ -1619,12 +1621,16 @@ static int iio_buffer_chrdev_release(struct inode *inode, struct file *filep)
wake_up(&buffer->pollq);
guard(mutex)(&buffer->dmabufs_mutex);
/* Close all attached DMABUFs */
list_for_each_entry_safe(priv, tmp, &buffer->dmabufs, entry) {
list_del_init(&priv->entry);
iio_buffer_dmabuf_put(priv->attach);
/*
* The mutex must be unlocked before iio_device_put(), which might drop the
* last reference and free the buffer.
*/
scoped_guard(mutex, &buffer->dmabufs_mutex) {
/* Close all attached DMABUFs */
list_for_each_entry_safe(priv, tmp, &buffer->dmabufs, entry) {
list_del_init(&priv->entry);
iio_buffer_dmabuf_put(priv->attach);
}
}
kfree(ib);
@ -1702,7 +1708,6 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
if (!priv)
return -ENOMEM;
spin_lock_init(&priv->lock);
priv->context = dma_fence_context_alloc(1);
dmabuf = dma_buf_get(fd);
@ -1827,18 +1832,9 @@ iio_buffer_dma_fence_get_driver_name(struct dma_fence *fence)
return "iio";
}
static void iio_buffer_dma_fence_release(struct dma_fence *fence)
{
struct iio_dma_fence *iio_fence =
container_of(fence, struct iio_dma_fence, base);
kfree(iio_fence);
}
static const struct dma_fence_ops iio_buffer_dma_fence_ops = {
.get_driver_name = iio_buffer_dma_fence_get_driver_name,
.get_timeline_name = iio_buffer_dma_fence_get_driver_name,
.release = iio_buffer_dma_fence_release,
};
static int iio_buffer_enqueue_dmabuf(struct iio_dev_buffer_pair *ib,
@ -1892,6 +1888,8 @@ static int iio_buffer_enqueue_dmabuf(struct iio_dev_buffer_pair *ib,
goto err_attachment_put;
}
spin_lock_init(&fence->lock);
fence->priv = priv;
seqno = atomic_add_return(1, &priv->seqno);
@ -1902,7 +1900,7 @@ static int iio_buffer_enqueue_dmabuf(struct iio_dev_buffer_pair *ib,
* the dma_fence.
*/
dma_fence_init(&fence->base, &iio_buffer_dma_fence_ops,
&priv->lock, priv->context, seqno);
&fence->lock, priv->context, seqno);
ret = iio_dma_resv_lock(dmabuf, nonblock);
if (ret)

View File

@ -469,9 +469,9 @@ static int apds9306_read_data(struct apds9306_data *data, int *val, int reg)
int status = 0;
u8 buff[3];
ret = pm_runtime_resume_and_get(data->dev);
if (ret)
return ret;
PM_RUNTIME_ACQUIRE_AUTOSUSPEND(data->dev, pm);
if (PM_RUNTIME_ACQUIRE_ERR(&pm))
return PM_RUNTIME_ACQUIRE_ERR(&pm);
ret = regmap_field_read(rf->intg_time, &intg_time_idx);
if (ret)
@ -535,8 +535,6 @@ static int apds9306_read_data(struct apds9306_data *data, int *val, int reg)
*val = get_unaligned_le24(&buff);
pm_runtime_put_autosuspend(data->dev);
return 0;
}

View File

@ -342,6 +342,10 @@ static int gp2ap002_write_event_config(struct iio_dev *indio_dev,
bool state)
{
struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
int ret;
if (state == gp2ap002->enabled)
return 0;
if (state) {
/*
@ -349,13 +353,16 @@ static int gp2ap002_write_event_config(struct iio_dev *indio_dev,
* already) and reintialize the sensor by using runtime_pm
* callbacks.
*/
pm_runtime_get_sync(gp2ap002->dev);
gp2ap002->enabled = true;
ret = pm_runtime_resume_and_get(gp2ap002->dev);
if (ret)
return ret;
} else {
pm_runtime_put_autosuspend(gp2ap002->dev);
gp2ap002->enabled = false;
}
gp2ap002->enabled = state;
return 0;
}
@ -642,6 +649,7 @@ static int gp2ap002_runtime_suspend(struct device *dev)
/* Disable chip and IRQ, everything off */
ret = regmap_write(gp2ap002->map, GP2AP002_OPMOD, 0x00);
if (ret) {
enable_irq(gp2ap002->irq);
dev_err(gp2ap002->dev, "error setting up operation mode\n");
return ret;
}
@ -669,7 +677,7 @@ static int gp2ap002_runtime_resume(struct device *dev)
ret = regulator_enable(gp2ap002->vio);
if (ret) {
dev_err(dev, "failed to enable VIO regulator in resume path\n");
return ret;
goto out_disable_vdd;
}
msleep(20);
@ -677,13 +685,19 @@ static int gp2ap002_runtime_resume(struct device *dev)
ret = gp2ap002_init(gp2ap002);
if (ret) {
dev_err(dev, "re-initialization failed\n");
return ret;
goto out_disable_vio;
}
/* Re-activate the IRQ */
enable_irq(gp2ap002->irq);
return 0;
out_disable_vio:
regulator_disable(gp2ap002->vio);
out_disable_vdd:
regulator_disable(gp2ap002->vdd);
return ret;
}
static DEFINE_RUNTIME_DEV_PM_OPS(gp2ap002_dev_pm_ops, gp2ap002_runtime_suspend,

View File

@ -247,11 +247,10 @@ static int ltrf216a_get_lux(struct ltrf216a_data *data)
return ret;
greendata = ltrf216a_read_data(data, LTRF216A_ALS_DATA_0);
ltrf216a_set_power_state(data, false);
if (greendata < 0)
return greendata;
ltrf216a_set_power_state(data, false);
lux = greendata * data->info->lux_multiplier * LTRF216A_WIN_FAC;
return lux;

View File

@ -39,7 +39,7 @@
#define OPT4001_CTRL_OPER_MODE_MASK GENMASK(5, 4)
#define OPT4001_CTRL_LATCH_MASK GENMASK(3, 3)
#define OPT4001_CTRL_INT_POL_MASK GENMASK(2, 2)
#define OPT4001_CTRL_FAULT_COUNT GENMASK(0, 1)
#define OPT4001_CTRL_FAULT_COUNT_MASK GENMASK(1, 0)
/* OPT4001 constants */
#define OPT4001_DEVICE_ID_VAL 0x121
@ -173,6 +173,7 @@ static int opt4001_read_lux_value(struct iio_dev *indio_dev,
u8 crc;
u8 calc_crc;
u64 lux_raw;
u32 rem;
int ret;
ret = regmap_read(chip->regmap, OPT4001_LIGHT1_MSB, &light1);
@ -199,8 +200,8 @@ static int opt4001_read_lux_value(struct iio_dev *indio_dev,
lux_raw = lux_raw << exp;
lux_raw = lux_raw * chip->chip_info->mul;
*val = div_u64_rem(lux_raw, chip->chip_info->div, val2);
*val2 = *val2 * 100;
*val = div_u64_rem(lux_raw, chip->chip_info->div, &rem);
*val2 = rem * 100;
return IIO_VAL_INT_PLUS_NANO;
}
@ -222,33 +223,14 @@ static int opt4001_set_conf(struct opt4001_chip *chip)
return ret;
}
static int opt4001_power_down(struct opt4001_chip *chip)
{
struct device *dev = &chip->client->dev;
int ret;
unsigned int reg;
ret = regmap_read(chip->regmap, OPT4001_DEVICE_ID, &reg);
if (ret) {
dev_err(dev, "Failed to read configuration\n");
return ret;
}
/* MODE_OFF is 0x0 so just set bits to 0 */
reg &= ~OPT4001_CTRL_OPER_MODE_MASK;
ret = regmap_write(chip->regmap, OPT4001_CTRL, reg);
if (ret)
dev_err(dev, "Failed to set configuration to power down\n");
return ret;
}
static void opt4001_chip_off_action(void *data)
{
struct opt4001_chip *chip = data;
int ret;
opt4001_power_down(chip);
ret = regmap_clear_bits(chip->regmap, OPT4001_CTRL, OPT4001_CTRL_OPER_MODE_MASK);
if (ret)
dev_err(&chip->client->dev, "Failed to power down\n");
}
static const struct iio_chan_spec opt4001_channels[] = {
@ -287,6 +269,9 @@ static int opt4001_write_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_INT_TIME:
if (val)
return -EINVAL;
int_time = opt4001_als_time_to_index(val2);
if (int_time < 0)
return int_time;

View File

@ -632,6 +632,9 @@ static int opt4060_write_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_INT_TIME:
if (val)
return -EINVAL;
int_time = opt4060_als_time_to_index(val2);
if (int_time < 0)
return int_time;
@ -710,6 +713,7 @@ static ssize_t opt4060_read_ev_period(struct opt4060_chip *chip, int *val,
{
int ret, pers, fault_count, int_time;
u64 uval;
u32 rem;
int_time = opt4060_int_time_reg[chip->int_time][0];
@ -735,7 +739,8 @@ static ssize_t opt4060_read_ev_period(struct opt4060_chip *chip, int *val,
}
uval = mul_u32_u32(int_time, pers);
*val = div_u64_rem(uval, MICRO, val2);
*val = div_u64_rem(uval, MICRO, &rem);
*val2 = rem;
return IIO_VAL_INT_PLUS_MICRO;
}
@ -805,7 +810,7 @@ static int opt4060_get_thresholds(struct opt4060_chip *chip, u32 *th_lo, u32 *th
ret = regmap_read(chip->regmap, OPT4060_THRESHOLD_HIGH, &regval);
if (ret) {
dev_err(chip->dev, "Failed to read THRESHOLD_LOW.\n");
dev_err(chip->dev, "Failed to read THRESHOLD_HIGH.\n");
return ret;
}
*th_hi = opt4060_calc_val_from_th_reg(regval);

View File

@ -845,7 +845,6 @@ static const struct iio_info dps310_info = {
static int dps310_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct dps310_data *data;
struct iio_dev *iio;
int rc;
@ -858,7 +857,7 @@ static int dps310_probe(struct i2c_client *client)
data->client = client;
mutex_init(&data->lock);
iio->name = id->name;
iio->name = DPS310_DEV_NAME;
iio->channels = dps310_channels;
iio->num_channels = ARRAY_SIZE(dps310_channels);
iio->info = &dps310_info;

View File

@ -330,6 +330,7 @@ static int srf04_probe(struct platform_device *pdev)
if (ret) {
dev_err(data->dev, "pm_runtime_set_active: %d\n", ret);
iio_device_unregister(indio_dev);
return ret;
}
pm_runtime_enable(data->dev);

View File

@ -243,7 +243,7 @@ static int hid_temperature_probe(struct platform_device *pdev)
if (ret)
goto error_remove_trigger;
ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev);
ret = iio_device_register(indio_dev);
if (ret)
goto error_remove_callback;
@ -263,6 +263,7 @@ static void hid_temperature_remove(struct platform_device *pdev)
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct temperature_state *temp_st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE);
hid_sensor_remove_trigger(indio_dev, &temp_st->common_attributes);
}