3rd set of IIO fixes for the 4.0 cycle.
* A double free occured on an error path in due to an event registration issue. The fix is the minimal change rather than possibly reworking this area of the core to give a more elegant solution (future work). * A number of drivers were directly accessing indio_dev->buffer->scan_mask to identify the currently enabled channel set. This may not be correct if we have additional clients on the push interface. The correct option is indio_dev->active_scan_mask. This is fixed. * bmc150 had incorrectly specified sampling frequency (a datasheet confusion as they are specified in terms of bandwith - e.g. half the sampling frequency). * hmc5843 wasn't setting it's name and hence the name attribute was returning an empty string. * inv_mpu6050 wasn't clearing the locally held timestamp buffer when the hardware fifo was reset. Also an inconsistency existed in the interface for the scale of the channels. Magic numbers were written but real ones were used for the reads. Now uses real numbers (i.e. not array indexes) for both. * fix a missing dependency in the dummy driver. Previously shielded from the autobuilders by an earlier build error. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJVBeZ7AAoJEFSFNJnE9BaIVl4QALH5o/kG81oiTTARzglCiV9z gglyFnnRxGzAQXr7+VbptPlls68jG1/8UdzEhOrIFKY2zaU0jl0YKxZSF4irU6FY RR7ZooNchMgVzH4I/byZBhFK/SEbRZTocTxCPPBMgQy5vFlK6sDoolQkqxZ2Oem7 eVmSpwO+maavrWtYgKovLB+lIb/Pm1xQ1ndijKjydUmlfF/4kHrRaR2PZYV1tujz aXj8homGB7Yc6AOcjXZlm9+CFF9bdLFGUN3TyvdGRQLoMhIkrljrS/QX7McXt+93 Oo+x5nH7h0qsoxrJ0EMGVnbw1CqOXDHWne+3YONR+vZCyHWlO0P4KXXI8uLsyYOU kPoy/CCW9CUfgAGxQ7NbF+7eB+nnxFeQ3vQttFuTQ/U7zVQTZu1GQVaaMPGJJopj xHSbGUCW8e1DBkMZUKOQXANgdxR5HfW33hPDE5kS0rbR61fmlCXq/UDn0q9g/UUt ZlloEphpFLb3nLTgb999d3dRKBGAqqdupq9n8XF/tu1nps2KP0/SClRUU9UFe62o NRpkEEazfPfm0bspjE8zhFixR43/YpFeiVDyuGKZ0Y8QPkHtdVoutnzBSRoRXnig VwRZcx9gYjv9FfZeJa6R/5je83jBKVBpMpYSj8L/f5dYCOEngsWEoa9YfH0vtc3m JH21lKJPPAJDVVQP7aA5 =9ZzZ -----END PGP SIGNATURE----- Merge tag 'iio-fixes-for-4.0c' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus Jonathan writes: 3rd set of IIO fixes for the 4.0 cycle. * A double free occured on an error path in due to an event registration issue. The fix is the minimal change rather than possibly reworking this area of the core to give a more elegant solution (future work). * A number of drivers were directly accessing indio_dev->buffer->scan_mask to identify the currently enabled channel set. This may not be correct if we have additional clients on the push interface. The correct option is indio_dev->active_scan_mask. This is fixed. * bmc150 had incorrectly specified sampling frequency (a datasheet confusion as they are specified in terms of bandwith - e.g. half the sampling frequency). * hmc5843 wasn't setting it's name and hence the name attribute was returning an empty string. * inv_mpu6050 wasn't clearing the locally held timestamp buffer when the hardware fifo was reset. Also an inconsistency existed in the interface for the scale of the channels. Magic numbers were written but real ones were used for the reads. Now uses real numbers (i.e. not array indexes) for both. * fix a missing dependency in the dummy driver. Previously shielded from the autobuilders by an earlier build error.
This commit is contained in:
commit
3d8bbe243d
|
@ -659,7 +659,7 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p)
|
|||
|
||||
mutex_lock(&data->mutex);
|
||||
|
||||
for_each_set_bit(bit, indio_dev->buffer->scan_mask,
|
||||
for_each_set_bit(bit, indio_dev->active_scan_mask,
|
||||
indio_dev->masklength) {
|
||||
ret = bma180_get_data_reg(data, bit);
|
||||
if (ret < 0) {
|
||||
|
|
|
@ -168,14 +168,14 @@ static const struct {
|
|||
int val;
|
||||
int val2;
|
||||
u8 bw_bits;
|
||||
} bmc150_accel_samp_freq_table[] = { {7, 810000, 0x08},
|
||||
{15, 630000, 0x09},
|
||||
{31, 250000, 0x0A},
|
||||
{62, 500000, 0x0B},
|
||||
{125, 0, 0x0C},
|
||||
{250, 0, 0x0D},
|
||||
{500, 0, 0x0E},
|
||||
{1000, 0, 0x0F} };
|
||||
} bmc150_accel_samp_freq_table[] = { {15, 620000, 0x08},
|
||||
{31, 260000, 0x09},
|
||||
{62, 500000, 0x0A},
|
||||
{125, 0, 0x0B},
|
||||
{250, 0, 0x0C},
|
||||
{500, 0, 0x0D},
|
||||
{1000, 0, 0x0E},
|
||||
{2000, 0, 0x0F} };
|
||||
|
||||
static const struct {
|
||||
int bw_bits;
|
||||
|
@ -840,7 +840,7 @@ static int bmc150_accel_validate_trigger(struct iio_dev *indio_dev,
|
|||
}
|
||||
|
||||
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
|
||||
"7.810000 15.630000 31.250000 62.500000 125 250 500 1000");
|
||||
"15.620000 31.260000 62.50000 125 250 500 1000 2000");
|
||||
|
||||
static struct attribute *bmc150_accel_attributes[] = {
|
||||
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
|
||||
|
@ -986,7 +986,7 @@ static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p)
|
|||
int bit, ret, i = 0;
|
||||
|
||||
mutex_lock(&data->mutex);
|
||||
for_each_set_bit(bit, indio_dev->buffer->scan_mask,
|
||||
for_each_set_bit(bit, indio_dev->active_scan_mask,
|
||||
indio_dev->masklength) {
|
||||
ret = i2c_smbus_read_word_data(data->client,
|
||||
BMC150_ACCEL_AXIS_TO_REG(bit));
|
||||
|
|
|
@ -956,7 +956,7 @@ static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p)
|
|||
|
||||
mutex_lock(&data->mutex);
|
||||
|
||||
for_each_set_bit(bit, indio_dev->buffer->scan_mask,
|
||||
for_each_set_bit(bit, indio_dev->active_scan_mask,
|
||||
indio_dev->masklength) {
|
||||
ret = kxcjk1013_get_acc_reg(data, bit);
|
||||
if (ret < 0) {
|
||||
|
|
|
@ -544,7 +544,6 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
|
|||
{
|
||||
struct iio_dev *idev = iio_trigger_get_drvdata(trig);
|
||||
struct at91_adc_state *st = iio_priv(idev);
|
||||
struct iio_buffer *buffer = idev->buffer;
|
||||
struct at91_adc_reg_desc *reg = st->registers;
|
||||
u32 status = at91_adc_readl(st, reg->trigger_register);
|
||||
int value;
|
||||
|
@ -564,7 +563,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
|
|||
at91_adc_writel(st, reg->trigger_register,
|
||||
status | value);
|
||||
|
||||
for_each_set_bit(bit, buffer->scan_mask,
|
||||
for_each_set_bit(bit, idev->active_scan_mask,
|
||||
st->num_channels) {
|
||||
struct iio_chan_spec const *chan = idev->channels + bit;
|
||||
at91_adc_writel(st, AT91_ADC_CHER,
|
||||
|
@ -579,7 +578,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
|
|||
at91_adc_writel(st, reg->trigger_register,
|
||||
status & ~value);
|
||||
|
||||
for_each_set_bit(bit, buffer->scan_mask,
|
||||
for_each_set_bit(bit, idev->active_scan_mask,
|
||||
st->num_channels) {
|
||||
struct iio_chan_spec const *chan = idev->channels + bit;
|
||||
at91_adc_writel(st, AT91_ADC_CHDR,
|
||||
|
|
|
@ -188,12 +188,11 @@ static int tiadc_buffer_preenable(struct iio_dev *indio_dev)
|
|||
static int tiadc_buffer_postenable(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct tiadc_device *adc_dev = iio_priv(indio_dev);
|
||||
struct iio_buffer *buffer = indio_dev->buffer;
|
||||
unsigned int enb = 0;
|
||||
u8 bit;
|
||||
|
||||
tiadc_step_config(indio_dev);
|
||||
for_each_set_bit(bit, buffer->scan_mask, adc_dev->channels)
|
||||
for_each_set_bit(bit, indio_dev->active_scan_mask, adc_dev->channels)
|
||||
enb |= (get_adc_step_bit(adc_dev, bit) << 1);
|
||||
adc_dev->buffer_en_ch_steps = enb;
|
||||
|
||||
|
|
|
@ -822,7 +822,7 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p)
|
|||
int bit, ret, i = 0;
|
||||
|
||||
mutex_lock(&data->mutex);
|
||||
for_each_set_bit(bit, indio_dev->buffer->scan_mask,
|
||||
for_each_set_bit(bit, indio_dev->active_scan_mask,
|
||||
indio_dev->masklength) {
|
||||
ret = i2c_smbus_read_word_data(data->client,
|
||||
BMG160_AXIS_TO_REG(bit));
|
||||
|
|
|
@ -410,43 +410,47 @@ error_read_raw:
|
|||
}
|
||||
}
|
||||
|
||||
static int inv_mpu6050_write_fsr(struct inv_mpu6050_state *st, int fsr)
|
||||
static int inv_mpu6050_write_gyro_scale(struct inv_mpu6050_state *st, int val)
|
||||
{
|
||||
int result;
|
||||
int result, i;
|
||||
u8 d;
|
||||
|
||||
if (fsr < 0 || fsr > INV_MPU6050_MAX_GYRO_FS_PARAM)
|
||||
return -EINVAL;
|
||||
if (fsr == st->chip_config.fsr)
|
||||
return 0;
|
||||
|
||||
d = (fsr << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT);
|
||||
result = inv_mpu6050_write_reg(st, st->reg->gyro_config, d);
|
||||
for (i = 0; i < ARRAY_SIZE(gyro_scale_6050); ++i) {
|
||||
if (gyro_scale_6050[i] == val) {
|
||||
d = (i << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT);
|
||||
result = inv_mpu6050_write_reg(st,
|
||||
st->reg->gyro_config, d);
|
||||
if (result)
|
||||
return result;
|
||||
st->chip_config.fsr = fsr;
|
||||
|
||||
st->chip_config.fsr = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int inv_mpu6050_write_accel_fs(struct inv_mpu6050_state *st, int fs)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int inv_mpu6050_write_accel_scale(struct inv_mpu6050_state *st, int val)
|
||||
{
|
||||
int result;
|
||||
int result, i;
|
||||
u8 d;
|
||||
|
||||
if (fs < 0 || fs > INV_MPU6050_MAX_ACCL_FS_PARAM)
|
||||
return -EINVAL;
|
||||
if (fs == st->chip_config.accl_fs)
|
||||
return 0;
|
||||
|
||||
d = (fs << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
|
||||
result = inv_mpu6050_write_reg(st, st->reg->accl_config, d);
|
||||
for (i = 0; i < ARRAY_SIZE(accel_scale); ++i) {
|
||||
if (accel_scale[i] == val) {
|
||||
d = (i << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
|
||||
result = inv_mpu6050_write_reg(st,
|
||||
st->reg->accl_config, d);
|
||||
if (result)
|
||||
return result;
|
||||
st->chip_config.accl_fs = fs;
|
||||
|
||||
st->chip_config.accl_fs = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int inv_mpu6050_write_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
|
@ -471,10 +475,10 @@ static int inv_mpu6050_write_raw(struct iio_dev *indio_dev,
|
|||
case IIO_CHAN_INFO_SCALE:
|
||||
switch (chan->type) {
|
||||
case IIO_ANGL_VEL:
|
||||
result = inv_mpu6050_write_fsr(st, val);
|
||||
result = inv_mpu6050_write_gyro_scale(st, val2);
|
||||
break;
|
||||
case IIO_ACCEL:
|
||||
result = inv_mpu6050_write_accel_fs(st, val);
|
||||
result = inv_mpu6050_write_accel_scale(st, val2);
|
||||
break;
|
||||
default:
|
||||
result = -EINVAL;
|
||||
|
|
|
@ -24,6 +24,16 @@
|
|||
#include <linux/poll.h>
|
||||
#include "inv_mpu_iio.h"
|
||||
|
||||
static void inv_clear_kfifo(struct inv_mpu6050_state *st)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/* take the spin lock sem to avoid interrupt kick in */
|
||||
spin_lock_irqsave(&st->time_stamp_lock, flags);
|
||||
kfifo_reset(&st->timestamps);
|
||||
spin_unlock_irqrestore(&st->time_stamp_lock, flags);
|
||||
}
|
||||
|
||||
int inv_reset_fifo(struct iio_dev *indio_dev)
|
||||
{
|
||||
int result;
|
||||
|
@ -50,6 +60,10 @@ int inv_reset_fifo(struct iio_dev *indio_dev)
|
|||
INV_MPU6050_BIT_FIFO_RST);
|
||||
if (result)
|
||||
goto reset_fifo_fail;
|
||||
|
||||
/* clear timestamps fifo */
|
||||
inv_clear_kfifo(st);
|
||||
|
||||
/* enable interrupt */
|
||||
if (st->chip_config.accl_fifo_enable ||
|
||||
st->chip_config.gyro_fifo_enable) {
|
||||
|
@ -83,16 +97,6 @@ reset_fifo_fail:
|
|||
return result;
|
||||
}
|
||||
|
||||
static void inv_clear_kfifo(struct inv_mpu6050_state *st)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/* take the spin lock sem to avoid interrupt kick in */
|
||||
spin_lock_irqsave(&st->time_stamp_lock, flags);
|
||||
kfifo_reset(&st->timestamps);
|
||||
spin_unlock_irqrestore(&st->time_stamp_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* inv_mpu6050_irq_handler() - Cache a timestamp at each data ready interrupt.
|
||||
*/
|
||||
|
@ -184,7 +188,6 @@ end_session:
|
|||
flush_fifo:
|
||||
/* Flush HW and SW FIFOs. */
|
||||
inv_reset_fifo(indio_dev);
|
||||
inv_clear_kfifo(st);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
iio_trigger_notify_done(indio_dev->trig);
|
||||
|
||||
|
|
|
@ -1227,7 +1227,7 @@ static irqreturn_t kmx61_trigger_handler(int irq, void *p)
|
|||
base = KMX61_MAG_XOUT_L;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
for_each_set_bit(bit, indio_dev->buffer->scan_mask,
|
||||
for_each_set_bit(bit, indio_dev->active_scan_mask,
|
||||
indio_dev->masklength) {
|
||||
ret = kmx61_read_measurement(data, base, bit);
|
||||
if (ret < 0) {
|
||||
|
|
|
@ -847,8 +847,7 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
|
|||
* @attr_list: List of IIO device attributes
|
||||
*
|
||||
* This function frees the memory allocated for each of the IIO device
|
||||
* attributes in the list. Note: if you want to reuse the list after calling
|
||||
* this function you have to reinitialize it using INIT_LIST_HEAD().
|
||||
* attributes in the list.
|
||||
*/
|
||||
void iio_free_chan_devattr_list(struct list_head *attr_list)
|
||||
{
|
||||
|
@ -856,6 +855,7 @@ void iio_free_chan_devattr_list(struct list_head *attr_list)
|
|||
|
||||
list_for_each_entry_safe(p, n, attr_list, l) {
|
||||
kfree(p->dev_attr.attr.name);
|
||||
list_del(&p->l);
|
||||
kfree(p);
|
||||
}
|
||||
}
|
||||
|
@ -936,6 +936,7 @@ static void iio_device_unregister_sysfs(struct iio_dev *indio_dev)
|
|||
|
||||
iio_free_chan_devattr_list(&indio_dev->channel_attr_list);
|
||||
kfree(indio_dev->chan_attr_group.attrs);
|
||||
indio_dev->chan_attr_group.attrs = NULL;
|
||||
}
|
||||
|
||||
static void iio_dev_release(struct device *device)
|
||||
|
|
|
@ -500,6 +500,7 @@ int iio_device_register_eventset(struct iio_dev *indio_dev)
|
|||
error_free_setup_event_lines:
|
||||
iio_free_chan_devattr_list(&indio_dev->event_interface->dev_attr_list);
|
||||
kfree(indio_dev->event_interface);
|
||||
indio_dev->event_interface = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -494,7 +494,7 @@ static irqreturn_t sx9500_trigger_handler(int irq, void *private)
|
|||
|
||||
mutex_lock(&data->mutex);
|
||||
|
||||
for_each_set_bit(bit, indio_dev->buffer->scan_mask,
|
||||
for_each_set_bit(bit, indio_dev->active_scan_mask,
|
||||
indio_dev->masklength) {
|
||||
ret = sx9500_read_proximity(data, &indio_dev->channels[bit],
|
||||
&val);
|
||||
|
|
|
@ -38,6 +38,7 @@ config IIO_SIMPLE_DUMMY_EVENTS
|
|||
config IIO_SIMPLE_DUMMY_BUFFER
|
||||
bool "Buffered capture support"
|
||||
select IIO_BUFFER
|
||||
select IIO_TRIGGER
|
||||
select IIO_KFIFO_BUF
|
||||
help
|
||||
Add buffered data capture to the simple dummy driver.
|
||||
|
|
|
@ -592,6 +592,7 @@ int hmc5843_common_probe(struct device *dev, struct regmap *regmap,
|
|||
mutex_init(&data->lock);
|
||||
|
||||
indio_dev->dev.parent = dev;
|
||||
indio_dev->name = dev->driver->name;
|
||||
indio_dev->info = &hmc5843_info;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
indio_dev->channels = data->variant->channels;
|
||||
|
|
Loading…
Reference in New Issue