mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
First set of IIO and counter fixes in the 5.8 cycle.
The buffer alignment fixes continue to trickle through as we get reviews in. The rest are the standard mixed bag of long term issues just discovered an things we missed in this cycle. IIO fixes * core - Add missing IIO_MOD_H2 and ETHANOL strings. Somehow got missed when drivers were added using these in attribute names. * afe4403,afe4404
, ak8974, hdc100x, hts221, ms5611 - Fix a recently identified issue with alignment when using iio_push_to_buffers_with_timestamp which assumes the timestamp is 8 byte aligned. * ad7780 - Fix a some premature / excess cleanup in an error path. * adi-axi-adc - Fix reference counting on the wrong object. * ak8974 - Fix unbalance runtime pm. * mma8452 - Fix missing iio_device_unregister in error path. * zp2326 - Error handling for pm_runtime_get_sync failing. counter fixes * Add lock guards in 104-quad-8 to protect against races - done in 2 patches to allow easy back porting. -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAl8EvAgRHGppYzIzQGtl cm5lbC5vcmcACgkQVIU0mcT0FoheYw/9EGqfk7jh96m13nFbFia4okNpoXpxez4H a13p/t1v2FAQvfGHEQh1zDXrvS8tMjpYyiumygHKODKESfyo6O1TR07nBL3fJzMR z35Uwf7DXcizk/k4AKMjT2ivbGFnUTx2tC52wlgsrcdmfbFlgo0Uz6VioREXNk79 34j7e01t3WpzEdA+fOVPji/s8mAILXGTSTHaAbSoTyAuOFNvjnaGSAj4pLILCyPT cxIRxalmByElhPFHTO8+L1cO38/LhU35LWZC8y4idNL43uhcuOkfPu7gExaZunSt wYARrEW38WyiOVi2rY3zJlyaw52bLU70+k63Wh0VPYTrGc54y6XRau80kaFm3tgb Hi5iorTy1KZVVEuPYtKyoer4pYhKfuGuUoXliQQ4YPgG6mhkW3T60R0gNmPT61gq voNvaOWG0Hsw8vlTwE/c6xcdam+ZoU9oZK1jZHoj8/sIVLENbvEWHoSTG9uUlQNU /i7c4z0WRgQgAe0DBLXHqzDC72UtDzdNNTpkCE9yLtW2mJr8boRweBLHsxn/kJPV wRCXuH+GaEFif9ly4SidhxPJwP+nvNJL9QV00+40EMwmM4O19k13J2ON1ygxz5Rg RS+ZEKpfcsmENhaGgjDc5q8Wy4VWk2mGF6K5Ug1TcED84Tujced5PYLDBmbrh4yB 98adg/jIdOo= =tm6K -----END PGP SIGNATURE----- Merge tag 'iio-fixes-for-5.8a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus Jonathan writes: First set of IIO and counter fixes in the 5.8 cycle. The buffer alignment fixes continue to trickle through as we get reviews in. The rest are the standard mixed bag of long term issues just discovered an things we missed in this cycle. IIO fixes * core - Add missing IIO_MOD_H2 and ETHANOL strings. Somehow got missed when drivers were added using these in attribute names. * afe4403,afe4404
, ak8974, hdc100x, hts221, ms5611 - Fix a recently identified issue with alignment when using iio_push_to_buffers_with_timestamp which assumes the timestamp is 8 byte aligned. * ad7780 - Fix a some premature / excess cleanup in an error path. * adi-axi-adc - Fix reference counting on the wrong object. * ak8974 - Fix unbalance runtime pm. * mma8452 - Fix missing iio_device_unregister in error path. * zp2326 - Error handling for pm_runtime_get_sync failing. counter fixes * Add lock guards in 104-quad-8 to protect against races - done in 2 patches to allow easy back porting. * tag 'iio-fixes-for-5.8a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: 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
617894cd84
@ -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 @@ no_irq:
|
||||
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 @@ disable_pm:
|
||||
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) {
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user