mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
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:
commit
05fa77078b
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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, ®);
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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, ®val);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user