diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-05-13 21:51:14 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-05-13 21:51:14 +0300 |
commit | ec94efcdadab69f41d257a1054260f8295ab77ef (patch) | |
tree | 6287158245d80fa79b6017787d0bd762bad89c96 /drivers/iio/accel | |
parent | 892c89d5d7ffd1bb794fe54d86c0eef18d215fab (diff) | |
parent | f0828ba96d02d4d4b197c531b34c662ee3c928df (diff) | |
download | linux-ec94efcdadab69f41d257a1054260f8295ab77ef.tar.xz |
Merge tag 'iio-fixes-for-4.1a-take2' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus
Jonathan writes:
The usual mixed bag of fixes for IIO in the 4.1 cycle.
Second version of this pull request as a small fix to a fix turned
up before Greg pulled it for a cc10001 patch near the top of the tree.
One core fix
* Set updated for a iio kfifo was incorrectly set to false during a failed
update, resulting in atttempts to repeat the failed operation appearing
to succeed.
This time I've decided to list the driver fixes in alphabetical order rather
than 'randomly'.
* axp288_adc - a recent change added a check for valid info masks when
reading channels from consumer drivers.
* bmp280 - temperature compensation was failing to read the tfine value, hence
causing a temperature of 0 to always be returned and incorrect presure
measurements.
* cc10001 - Fix channel number mapping when some channels are reserved for
remote CPUs. Fix an issue with the use of the power-up/power-down register
(basically wrong polarity). Fix an issue due to the missinterpretting the
return value from regulator_get_voltage. Add a delay before the start bit
as recommended for the hardware to avoid data corruption.
* hid pressure - fix channel spec of modfiied, but no modifier (which makes no
sense!)
* hid proximity - fix channel spec of modified, but no modifier (which makes
no sense!). Fix a memory leak in the probe function.
* mcp320x - occasional incorrect readings on dma using spi busses due to
cacheline corruption. Fixed by forcing ___cacheline_aligned for the buffers.
* mma9551 - buffer overrun fix (miss specified maximum length of buffers)
* mma9553 - endian fix on status message. Add an enable element for activity
channel. Input checking for activity period to avoid rather unpredictable
results.
* spmi-vadc - fix an overflow in the output value normalization seen on some
boards.
* st-snesors - oops due to use of a mutex that is not yet initialized during
probe.
* xilinx adc - Some wrong register addresses, a wrong address for vccaux
channel, incorrect scale on VREFP and incorrect sign on VREFN.
Diffstat (limited to 'drivers/iio/accel')
-rw-r--r-- | drivers/iio/accel/mma9551_core.c | 21 | ||||
-rw-r--r-- | drivers/iio/accel/mma9553.c | 18 | ||||
-rw-r--r-- | drivers/iio/accel/st_accel_core.c | 1 |
3 files changed, 29 insertions, 11 deletions
diff --git a/drivers/iio/accel/mma9551_core.c b/drivers/iio/accel/mma9551_core.c index 7f55a6d7cd03..c6d5a3a40b60 100644 --- a/drivers/iio/accel/mma9551_core.c +++ b/drivers/iio/accel/mma9551_core.c @@ -389,7 +389,12 @@ int mma9551_read_config_words(struct i2c_client *client, u8 app_id, { int ret, i; int len_words = len / sizeof(u16); - __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS]; + __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2]; + + if (len_words > ARRAY_SIZE(be_buf)) { + dev_err(&client->dev, "Invalid buffer size %d\n", len); + return -EINVAL; + } ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG, reg, NULL, 0, (u8 *) be_buf, len); @@ -424,7 +429,12 @@ int mma9551_read_status_words(struct i2c_client *client, u8 app_id, { int ret, i; int len_words = len / sizeof(u16); - __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS]; + __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2]; + + if (len_words > ARRAY_SIZE(be_buf)) { + dev_err(&client->dev, "Invalid buffer size %d\n", len); + return -EINVAL; + } ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS, reg, NULL, 0, (u8 *) be_buf, len); @@ -459,7 +469,12 @@ int mma9551_write_config_words(struct i2c_client *client, u8 app_id, { int i; int len_words = len / sizeof(u16); - __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS]; + __be16 be_buf[(MMA9551_MAX_MAILBOX_DATA_REGS - 1) / 2]; + + if (len_words > ARRAY_SIZE(be_buf)) { + dev_err(&client->dev, "Invalid buffer size %d\n", len); + return -EINVAL; + } for (i = 0; i < len_words; i++) be_buf[i] = cpu_to_be16(buf[i]); diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index 2df1af7d43fc..365a109aaaef 100644 --- a/drivers/iio/accel/mma9553.c +++ b/drivers/iio/accel/mma9553.c @@ -54,6 +54,7 @@ #define MMA9553_MASK_CONF_STEPCOALESCE GENMASK(7, 0) #define MMA9553_REG_CONF_ACTTHD 0x0E +#define MMA9553_MAX_ACTTHD GENMASK(15, 0) /* Pedometer status registers (R-only) */ #define MMA9553_REG_STATUS 0x00 @@ -316,22 +317,19 @@ static int mma9553_set_config(struct mma9553_data *data, u16 reg, static int mma9553_read_activity_stepcnt(struct mma9553_data *data, u8 *activity, u16 *stepcnt) { - u32 status_stepcnt; - u16 status; + u16 buf[2]; int ret; ret = mma9551_read_status_words(data->client, MMA9551_APPID_PEDOMETER, - MMA9553_REG_STATUS, sizeof(u32), - (u16 *) &status_stepcnt); + MMA9553_REG_STATUS, sizeof(u32), buf); if (ret < 0) { dev_err(&data->client->dev, "error reading status and stepcnt\n"); return ret; } - status = status_stepcnt & MMA9553_MASK_CONF_WORD; - *activity = mma9553_get_bits(status, MMA9553_MASK_STATUS_ACTIVITY); - *stepcnt = status_stepcnt >> 16; + *activity = mma9553_get_bits(buf[0], MMA9553_MASK_STATUS_ACTIVITY); + *stepcnt = buf[1]; return 0; } @@ -872,6 +870,9 @@ static int mma9553_write_event_value(struct iio_dev *indio_dev, case IIO_EV_INFO_PERIOD: switch (chan->type) { case IIO_ACTIVITY: + if (val < 0 || val > MMA9553_ACTIVITY_THD_TO_SEC( + MMA9553_MAX_ACTTHD)) + return -EINVAL; mutex_lock(&data->mutex); ret = mma9553_set_config(data, MMA9553_REG_CONF_ACTTHD, &data->conf.actthd, @@ -971,7 +972,8 @@ static const struct iio_chan_spec_ext_info mma9553_ext_info[] = { .modified = 1, \ .channel2 = _chan2, \ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT) | \ + BIT(IIO_CHAN_INFO_ENABLE), \ .event_spec = mma9553_activity_events, \ .num_event_specs = ARRAY_SIZE(mma9553_activity_events), \ .ext_info = mma9553_ext_info, \ diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index 58d1d13d552a..211b13271c61 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -546,6 +546,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev) indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &accel_info; + mutex_init(&adata->tb.buf_lock); st_sensors_power_enable(indio_dev); |