mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-02-10 10:45:09 +07:00
IIO/Staging driver fixes for 5.8-rc6
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. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCXxBxCw8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ylX1gCgw4MzlHebbXzqCxF1Get7tJYIBDEAn0GxF+Jc udsxLSu6CsKAneGkwcsB =iT0I -----END PGP SIGNATURE----- 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.
This commit is contained in:
commit
6a058f0be5
@ -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(®istered_clients_lock);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
get_device(dev);
|
||||
get_device(cl->dev);
|
||||
cl->info = info;
|
||||
mutex_unlock(®istered_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 */
|
||||
|
Loading…
Reference in New Issue
Block a user