Commit 6a058f0b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'staging-5.8-rc6' of...

Merge tag 'staging-5.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging into master

Pull IIO and staging driver fixes from Greg KH:
 "Here are some IIO and staging driver fixes for 5.8-rc6.

  The majority of fixes are for IIO drivers, resolving a number of small
  reported issues, and there are some counter fixes in here too that
  were tied to the IIO fixes. There's only one staging driver fix here,
  a comedi fix found by code inspection.

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'staging-5.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging:
  staging: comedi: verify array index is correct before using it
  iio: adc: ad7780: Fix a resource handling path in 'ad7780_probe()'
  iio:pressure:ms5611 Fix buffer element alignment
  iio:humidity:hts221 Fix alignment and data leak issues
  iio:humidity:hdc100x Fix alignment and data leak issues
  iio:magnetometer:ak8974: Fix alignment and data leak issues
  iio: adc: adi-axi-adc: Fix object reference counting
  iio: pressure: zpa2326: handle pm_runtime_get_sync failure
  counter: 104-quad-8: Add lock guards - filter clock prescaler
  counter: 104-quad-8: Add lock guards - differential encoder
  iio: core: add missing IIO_MOD_H2/ETHANOL string identifiers
  iio: magnetometer: ak8974: Fix runtime PM imbalance on error
  iio: mma8452: Add missed iio_device_unregister() call in mma8452_probe()
  iio:health:afe4404 Fix timestamp alignment and prevent data leak.
  iio:health:afe4403 Fix timestamp alignment and prevent data leak.
parents 7531ee31 ef75e14a
......@@ -1274,18 +1274,26 @@ static ssize_t quad8_signal_cable_fault_read(struct counter_device *counter,
struct counter_signal *signal,
void *private, char *buf)
{
const struct quad8_iio *const priv = counter->priv;
struct quad8_iio *const priv = counter->priv;
const size_t channel_id = signal->id / 2;
const bool disabled = !(priv->cable_fault_enable & BIT(channel_id));
bool disabled;
unsigned int status;
unsigned int fault;
if (disabled)
mutex_lock(&priv->lock);
disabled = !(priv->cable_fault_enable & BIT(channel_id));
if (disabled) {
mutex_unlock(&priv->lock);
return -EINVAL;
}
/* Logic 0 = cable fault */
status = inb(priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
mutex_unlock(&priv->lock);
/* Mask respective channel and invert logic */
fault = !(status & BIT(channel_id));
......@@ -1317,6 +1325,8 @@ static ssize_t quad8_signal_cable_fault_enable_write(
if (ret)
return ret;
mutex_lock(&priv->lock);
if (enable)
priv->cable_fault_enable |= BIT(channel_id);
else
......@@ -1327,6 +1337,8 @@ static ssize_t quad8_signal_cable_fault_enable_write(
outb(cable_fault_enable, priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
mutex_unlock(&priv->lock);
return len;
}
......@@ -1353,6 +1365,8 @@ static ssize_t quad8_signal_fck_prescaler_write(struct counter_device *counter,
if (ret)
return ret;
mutex_lock(&priv->lock);
priv->fck_prescaler[channel_id] = prescaler;
/* Reset Byte Pointer */
......@@ -1363,6 +1377,8 @@ static ssize_t quad8_signal_fck_prescaler_write(struct counter_device *counter,
outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC,
base_offset + 1);
mutex_unlock(&priv->lock);
return len;
}
......
......@@ -1685,10 +1685,13 @@ static int mma8452_probe(struct i2c_client *client,
ret = mma8452_set_freefall_mode(data, false);
if (ret < 0)
goto buffer_cleanup;
goto unregister_device;
return 0;
unregister_device:
iio_device_unregister(indio_dev);
buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
......
......@@ -329,7 +329,7 @@ static int ad7780_probe(struct spi_device *spi)
ret = ad7780_init_gpios(&spi->dev, st);
if (ret)
goto error_cleanup_buffer_and_trigger;
return ret;
st->reg = devm_regulator_get(&spi->dev, "avdd");
if (IS_ERR(st->reg))
......
......@@ -332,12 +332,12 @@ static struct adi_axi_adc_client *adi_axi_adc_attach_client(struct device *dev)
if (cl->dev->of_node != cln)
continue;
if (!try_module_get(dev->driver->owner)) {
if (!try_module_get(cl->dev->driver->owner)) {
mutex_unlock(&registered_clients_lock);
return ERR_PTR(-ENODEV);
}
get_device(dev);
get_device(cl->dev);
cl->info = info;
mutex_unlock(&registered_clients_lock);
return cl;
......
......@@ -65,6 +65,7 @@ static const struct reg_field afe4403_reg_fields[] = {
* @regulator: Pointer to the regulator for the IC
* @trig: IIO trigger for this device
* @irq: ADC_RDY line interrupt number
* @buffer: Used to construct data layout to push into IIO buffer.
*/
struct afe4403_data {
struct device *dev;
......@@ -74,6 +75,8 @@ struct afe4403_data {
struct regulator *regulator;
struct iio_trigger *trig;
int irq;
/* Ensure suitable alignment for timestamp */
s32 buffer[8] __aligned(8);
};
enum afe4403_chan_id {
......@@ -309,7 +312,6 @@ static irqreturn_t afe4403_trigger_handler(int irq, void *private)
struct iio_dev *indio_dev = pf->indio_dev;
struct afe4403_data *afe = iio_priv(indio_dev);
int ret, bit, i = 0;
s32 buffer[8];
u8 tx[4] = {AFE440X_CONTROL0, 0x0, 0x0, AFE440X_CONTROL0_READ};
u8 rx[3];
......@@ -326,7 +328,7 @@ static irqreturn_t afe4403_trigger_handler(int irq, void *private)
if (ret)
goto err;
buffer[i++] = get_unaligned_be24(&rx[0]);
afe->buffer[i++] = get_unaligned_be24(&rx[0]);
}
/* Disable reading from the device */
......@@ -335,7 +337,8 @@ static irqreturn_t afe4403_trigger_handler(int irq, void *private)
if (ret)
goto err;
iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp);
iio_push_to_buffers_with_timestamp(indio_dev, afe->buffer,
pf->timestamp);
err:
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -83,6 +83,7 @@ static const struct reg_field afe4404_reg_fields[] = {
* @regulator: Pointer to the regulator for the IC
* @trig: IIO trigger for this device
* @irq: ADC_RDY line interrupt number
* @buffer: Used to construct a scan to push to the iio buffer.
*/
struct afe4404_data {
struct device *dev;
......@@ -91,6 +92,7 @@ struct afe4404_data {
struct regulator *regulator;
struct iio_trigger *trig;
int irq;
s32 buffer[10] __aligned(8);
};
enum afe4404_chan_id {
......@@ -328,17 +330,17 @@ static irqreturn_t afe4404_trigger_handler(int irq, void *private)
struct iio_dev *indio_dev = pf->indio_dev;
struct afe4404_data *afe = iio_priv(indio_dev);
int ret, bit, i = 0;
s32 buffer[10];
for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->masklength) {
ret = regmap_read(afe->regmap, afe4404_channel_values[bit],
&buffer[i++]);
&afe->buffer[i++]);
if (ret)
goto err;
}
iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp);
iio_push_to_buffers_with_timestamp(indio_dev, afe->buffer,
pf->timestamp);
err:
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -38,6 +38,11 @@ struct hdc100x_data {
/* integration time of the sensor */
int adc_int_us[2];
/* Ensure natural alignment of timestamp */
struct {
__be16 channels[2];
s64 ts __aligned(8);
} scan;
};
/* integration time in us */
......@@ -322,7 +327,6 @@ static irqreturn_t hdc100x_trigger_handler(int irq, void *p)
struct i2c_client *client = data->client;
int delay = data->adc_int_us[0] + data->adc_int_us[1];
int ret;
s16 buf[8]; /* 2x s16 + padding + 8 byte timestamp */
/* dual read starts at temp register */
mutex_lock(&data->lock);
......@@ -333,13 +337,13 @@ static irqreturn_t hdc100x_trigger_handler(int irq, void *p)
}
usleep_range(delay, delay + 1000);
ret = i2c_master_recv(client, (u8 *)buf, 4);
ret = i2c_master_recv(client, (u8 *)data->scan.channels, 4);
if (ret < 0) {
dev_err(&client->dev, "cannot read sensor data\n");
goto err;
}
iio_push_to_buffers_with_timestamp(indio_dev, buf,
iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
iio_get_time_ns(indio_dev));
err:
mutex_unlock(&data->lock);
......
......@@ -14,8 +14,6 @@
#include <linux/iio/iio.h>
#define HTS221_DATA_SIZE 2
enum hts221_sensor_type {
HTS221_SENSOR_H,
HTS221_SENSOR_T,
......@@ -39,6 +37,11 @@ struct hts221_hw {
bool enabled;
u8 odr;
/* Ensure natural alignment of timestamp */
struct {
__le16 channels[2];
s64 ts __aligned(8);
} scan;
};
extern const struct dev_pm_ops hts221_pm_ops;
......
......@@ -160,7 +160,6 @@ static const struct iio_buffer_setup_ops hts221_buffer_ops = {
static irqreturn_t hts221_buffer_handler_thread(int irq, void *p)
{
u8 buffer[ALIGN(2 * HTS221_DATA_SIZE, sizeof(s64)) + sizeof(s64)];
struct iio_poll_func *pf = p;
struct iio_dev *iio_dev = pf->indio_dev;
struct hts221_hw *hw = iio_priv(iio_dev);
......@@ -170,18 +169,20 @@ static irqreturn_t hts221_buffer_handler_thread(int irq, void *p)
/* humidity data */
ch = &iio_dev->channels[HTS221_SENSOR_H];
err = regmap_bulk_read(hw->regmap, ch->address,
buffer, HTS221_DATA_SIZE);
&hw->scan.channels[0],
sizeof(hw->scan.channels[0]));
if (err < 0)
goto out;
/* temperature data */
ch = &iio_dev->channels[HTS221_SENSOR_T];
err = regmap_bulk_read(hw->regmap, ch->address,
buffer + HTS221_DATA_SIZE, HTS221_DATA_SIZE);
&hw->scan.channels[1],
sizeof(hw->scan.channels[1]));
if (err < 0)
goto out;
iio_push_to_buffers_with_timestamp(iio_dev, buffer,
iio_push_to_buffers_with_timestamp(iio_dev, &hw->scan,
iio_get_time_ns(iio_dev));
out:
......
......@@ -130,6 +130,8 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_PM2P5] = "pm2p5",
[IIO_MOD_PM4] = "pm4",
[IIO_MOD_PM10] = "pm10",
[IIO_MOD_ETHANOL] = "ethanol",
[IIO_MOD_H2] = "h2",
};
/* relies on pairs of these shared then separate */
......
......@@ -192,6 +192,11 @@ struct ak8974 {
bool drdy_irq;
struct completion drdy_complete;
bool drdy_active_low;
/* Ensure timestamp is naturally aligned */
struct {
__le16 channels[3];
s64 ts __aligned(8);
} scan;
};
static const char ak8974_reg_avdd[] = "avdd";
......@@ -657,7 +662,6 @@ static void ak8974_fill_buffer(struct iio_dev *indio_dev)
{
struct ak8974 *ak8974 = iio_priv(indio_dev);
int ret;
__le16 hw_values[8]; /* Three axes + 64bit padding */
pm_runtime_get_sync(&ak8974->i2c->dev);
mutex_lock(&ak8974->lock);
......@@ -667,13 +671,13 @@ static void ak8974_fill_buffer(struct iio_dev *indio_dev)
dev_err(&ak8974->i2c->dev, "error triggering measure\n");
goto out_unlock;
}
ret = ak8974_getresult(ak8974, hw_values);
ret = ak8974_getresult(ak8974, ak8974->scan.channels);
if (ret) {
dev_err(&ak8974->i2c->dev, "error getting measures\n");
goto out_unlock;
}
iio_push_to_buffers_with_timestamp(indio_dev, hw_values,
iio_push_to_buffers_with_timestamp(indio_dev, &ak8974->scan,
iio_get_time_ns(indio_dev));
out_unlock:
......@@ -862,19 +866,21 @@ static int ak8974_probe(struct i2c_client *i2c,
ak8974->map = devm_regmap_init_i2c(i2c, &ak8974_regmap_config);
if (IS_ERR(ak8974->map)) {
dev_err(&i2c->dev, "failed to allocate register map\n");
pm_runtime_put_noidle(&i2c->dev);
pm_runtime_disable(&i2c->dev);
return PTR_ERR(ak8974->map);
}
ret = ak8974_set_power(ak8974, AK8974_PWR_ON);
if (ret) {
dev_err(&i2c->dev, "could not power on\n");
goto power_off;
goto disable_pm;
}
ret = ak8974_detect(ak8974);
if (ret) {
dev_err(&i2c->dev, "neither AK8974 nor AMI30x found\n");
goto power_off;
goto disable_pm;
}
ret = ak8974_selftest(ak8974);
......@@ -884,14 +890,9 @@ static int ak8974_probe(struct i2c_client *i2c,
ret = ak8974_reset(ak8974);
if (ret) {
dev_err(&i2c->dev, "AK8974 reset failed\n");
goto power_off;
goto disable_pm;
}
pm_runtime_set_autosuspend_delay(&i2c->dev,
AK8974_AUTOSUSPEND_DELAY);
pm_runtime_use_autosuspend(&i2c->dev);
pm_runtime_put(&i2c->dev);
indio_dev->dev.parent = &i2c->dev;
switch (ak8974->variant) {
case AK8974_WHOAMI_VALUE_AMI306:
......@@ -957,6 +958,11 @@ static int ak8974_probe(struct i2c_client *i2c,
goto cleanup_buffer;
}
pm_runtime_set_autosuspend_delay(&i2c->dev,
AK8974_AUTOSUSPEND_DELAY);
pm_runtime_use_autosuspend(&i2c->dev);
pm_runtime_put(&i2c->dev);
return 0;
cleanup_buffer:
......@@ -965,7 +971,6 @@ static int ak8974_probe(struct i2c_client *i2c,
pm_runtime_put_noidle(&i2c->dev);
pm_runtime_disable(&i2c->dev);
ak8974_set_power(ak8974, AK8974_PWR_OFF);
power_off:
regulator_bulk_disable(ARRAY_SIZE(ak8974->regs), ak8974->regs);
return ret;
......
......@@ -212,16 +212,21 @@ static irqreturn_t ms5611_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ms5611_state *st = iio_priv(indio_dev);
s32 buf[4]; /* s32 (pressure) + s32 (temp) + 2 * s32 (timestamp) */
/* Ensure buffer elements are naturally aligned */
struct {
s32 channels[2];
s64 ts __aligned(8);
} scan;
int ret;
mutex_lock(&st->lock);
ret = ms5611_read_temp_and_pressure(indio_dev, &buf[1], &buf[0]);
ret = ms5611_read_temp_and_pressure(indio_dev, &scan.channels[1],
&scan.channels[0]);
mutex_unlock(&st->lock);
if (ret < 0)
goto err;
iio_push_to_buffers_with_timestamp(indio_dev, buf,
iio_push_to_buffers_with_timestamp(indio_dev, &scan,
iio_get_time_ns(indio_dev));
err:
......
......@@ -665,8 +665,10 @@ static int zpa2326_resume(const struct iio_dev *indio_dev)
int err;
err = pm_runtime_get_sync(indio_dev->dev.parent);
if (err < 0)
if (err < 0) {
pm_runtime_put(indio_dev->dev.parent);
return err;
}
if (err > 0) {
/*
......
......@@ -456,9 +456,9 @@ static int apci1500_di_cfg_trig(struct comedi_device *dev,
unsigned int lo_mask = data[5] << shift;
unsigned int chan_mask = hi_mask | lo_mask;
unsigned int old_mask = (1 << shift) - 1;
unsigned int pm = devpriv->pm[trig] & old_mask;
unsigned int pt = devpriv->pt[trig] & old_mask;
unsigned int pp = devpriv->pp[trig] & old_mask;
unsigned int pm;
unsigned int pt;
unsigned int pp;
if (trig > 1) {
dev_dbg(dev->class_dev,
......@@ -471,6 +471,10 @@ static int apci1500_di_cfg_trig(struct comedi_device *dev,
return -EINVAL;
}
pm = devpriv->pm[trig] & old_mask;
pt = devpriv->pt[trig] & old_mask;
pp = devpriv->pp[trig] & old_mask;
switch (data[2]) {
case COMEDI_DIGITAL_TRIG_DISABLE:
/* clear trigger configuration */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment