Commit 9d569b1c authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-fixes-for-4.17a' of...

Merge tag 'iio-fixes-for-4.17a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus

Jonathan writes:

First round of IIO fixes for the 4.17 cycle.

* core
  - fix up some issues with overflow etc around wrong types
    for some fo the kfifo handling functions.  Seems unlikely
    this would be triggered in reality but the fixes are simple
    so let's tidy them up.  Second patch deals with checking
    the userspace value passed for length for potential overflow.
* ad7793
  - Catch up with changes to the ad_sigma_delta core and use
    read_raw / write_raw iwth IIO_CHAN_INFO_SAMP_FEW to handle
    sampling frequency control.
* at91-sama5d2
  - Channel config for differential channels was completely broken.
  - Missing Kconfig dependency for buffer support.
* hid-sensor
  - Fix an issue with powering up after resume due to wrong reference
    counting.
* stm32-dfsdm
  - Fix an issue with second writes of the oversampling settings
    failing.
  - Fix an issue with the sample rate being set to half of requested
    value when particular clock source is used.
parents 6da6c0db 76974ef9
......@@ -158,6 +158,7 @@ config AT91_SAMA5D2_ADC
depends on ARCH_AT91 || COMPILE_TEST
depends on HAS_IOMEM
depends on HAS_DMA
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for Atmel SAMA5D2 ADC which is
......
......@@ -348,55 +348,6 @@ static const u16 ad7793_sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39,
static const u16 ad7797_sample_freq_avail[16] = {0, 0, 0, 123, 62, 50, 0,
33, 0, 17, 16, 12, 10, 8, 6, 4};
static ssize_t ad7793_read_frequency(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad7793_state *st = iio_priv(indio_dev);
return sprintf(buf, "%d\n",
st->chip_info->sample_freq_avail[AD7793_MODE_RATE(st->mode)]);
}
static ssize_t ad7793_write_frequency(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad7793_state *st = iio_priv(indio_dev);
long lval;
int i, ret;
ret = kstrtol(buf, 10, &lval);
if (ret)
return ret;
if (lval == 0)
return -EINVAL;
for (i = 0; i < 16; i++)
if (lval == st->chip_info->sample_freq_avail[i])
break;
if (i == 16)
return -EINVAL;
ret = iio_device_claim_direct_mode(indio_dev);
if (ret)
return ret;
st->mode &= ~AD7793_MODE_RATE(-1);
st->mode |= AD7793_MODE_RATE(i);
ad_sd_write_reg(&st->sd, AD7793_REG_MODE, sizeof(st->mode), st->mode);
iio_device_release_direct_mode(indio_dev);
return len;
}
static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
ad7793_read_frequency,
ad7793_write_frequency);
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
"470 242 123 62 50 39 33 19 17 16 12 10 8 6 4");
......@@ -424,7 +375,6 @@ static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available,
ad7793_show_scale_available, NULL, 0);
static struct attribute *ad7793_attributes[] = {
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_in_m_in_scale_available.dev_attr.attr,
NULL
......@@ -435,7 +385,6 @@ static const struct attribute_group ad7793_attribute_group = {
};
static struct attribute *ad7797_attributes[] = {
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available_ad7797.dev_attr.attr,
NULL
};
......@@ -505,6 +454,10 @@ static int ad7793_read_raw(struct iio_dev *indio_dev,
*val -= offset;
}
return IIO_VAL_INT;
case IIO_CHAN_INFO_SAMP_FREQ:
*val = st->chip_info
->sample_freq_avail[AD7793_MODE_RATE(st->mode)];
return IIO_VAL_INT;
}
return -EINVAL;
}
......@@ -542,6 +495,26 @@ static int ad7793_write_raw(struct iio_dev *indio_dev,
break;
}
break;
case IIO_CHAN_INFO_SAMP_FREQ:
if (!val) {
ret = -EINVAL;
break;
}
for (i = 0; i < 16; i++)
if (val == st->chip_info->sample_freq_avail[i])
break;
if (i == 16) {
ret = -EINVAL;
break;
}
st->mode &= ~AD7793_MODE_RATE(-1);
st->mode |= AD7793_MODE_RATE(i);
ad_sd_write_reg(&st->sd, AD7793_REG_MODE, sizeof(st->mode),
st->mode);
break;
default:
ret = -EINVAL;
}
......
......@@ -333,6 +333,27 @@ static const struct iio_chan_spec at91_adc_channels[] = {
+ AT91_SAMA5D2_DIFF_CHAN_CNT + 1),
};
static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
{
int i;
for (i = 0; i < indio_dev->num_channels; i++) {
if (indio_dev->channels[i].scan_index == chan)
return i;
}
return -EINVAL;
}
static inline struct iio_chan_spec const *
at91_adc_chan_get(struct iio_dev *indio_dev, int chan)
{
int index = at91_adc_chan_xlate(indio_dev, chan);
if (index < 0)
return NULL;
return indio_dev->channels + index;
}
static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
{
struct iio_dev *indio = iio_trigger_get_drvdata(trig);
......@@ -350,8 +371,10 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) {
struct iio_chan_spec const *chan = indio->channels + bit;
struct iio_chan_spec const *chan = at91_adc_chan_get(indio, bit);
if (!chan)
continue;
if (state) {
at91_adc_writel(st, AT91_SAMA5D2_CHER,
BIT(chan->channel));
......@@ -448,7 +471,11 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev)
for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->num_channels) {
struct iio_chan_spec const *chan = indio_dev->channels + bit;
struct iio_chan_spec const *chan =
at91_adc_chan_get(indio_dev, bit);
if (!chan)
continue;
st->dma_st.rx_buf_sz += chan->scan_type.storagebits / 8;
}
......@@ -526,8 +553,11 @@ static int at91_adc_buffer_predisable(struct iio_dev *indio_dev)
*/
for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->num_channels) {
struct iio_chan_spec const *chan = indio_dev->channels + bit;
struct iio_chan_spec const *chan =
at91_adc_chan_get(indio_dev, bit);
if (!chan)
continue;
if (st->dma_st.dma_chan)
at91_adc_readl(st, chan->address);
}
......@@ -587,8 +617,11 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->num_channels) {
struct iio_chan_spec const *chan = indio_dev->channels + bit;
struct iio_chan_spec const *chan =
at91_adc_chan_get(indio_dev, bit);
if (!chan)
continue;
st->buffer[i] = at91_adc_readl(st, chan->address);
i++;
}
......
......@@ -144,6 +144,7 @@ static int stm32_dfsdm_set_osrs(struct stm32_dfsdm_filter *fl,
* Leave as soon as if exact resolution if reached.
* Otherwise the higher resolution below 32 bits is kept.
*/
fl->res = 0;
for (fosr = 1; fosr <= DFSDM_MAX_FL_OVERSAMPLING; fosr++) {
for (iosr = 1; iosr <= DFSDM_MAX_INT_OVERSAMPLING; iosr++) {
if (fast)
......@@ -193,7 +194,7 @@ static int stm32_dfsdm_set_osrs(struct stm32_dfsdm_filter *fl,
}
}
if (!fl->fosr)
if (!fl->res)
return -EINVAL;
return 0;
......@@ -770,7 +771,7 @@ static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev,
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id];
struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[chan->channel];
unsigned int spi_freq = adc->spi_freq;
unsigned int spi_freq;
int ret = -EINVAL;
switch (mask) {
......@@ -784,8 +785,18 @@ static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SAMP_FREQ:
if (!val)
return -EINVAL;
if (ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL)
switch (ch->src) {
case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL:
spi_freq = adc->dfsdm->spi_master_freq;
break;
case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_FALLING:
case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_RISING:
spi_freq = adc->dfsdm->spi_master_freq / 2;
break;
default:
spi_freq = adc->spi_freq;
}
if (spi_freq % val)
dev_warn(&indio_dev->dev,
......
......@@ -587,7 +587,7 @@ EXPORT_SYMBOL_GPL(iio_dma_buffer_set_bytes_per_datum);
* Should be used as the set_length callback for iio_buffer_access_ops
* struct for DMA buffers.
*/
int iio_dma_buffer_set_length(struct iio_buffer *buffer, int length)
int iio_dma_buffer_set_length(struct iio_buffer *buffer, unsigned int length)
{
/* Avoid an invalid state */
if (length < 2)
......
......@@ -22,11 +22,18 @@ struct iio_kfifo {
#define iio_to_kfifo(r) container_of(r, struct iio_kfifo, buffer)
static inline int __iio_allocate_kfifo(struct iio_kfifo *buf,
int bytes_per_datum, int length)
size_t bytes_per_datum, unsigned int length)
{
if ((length == 0) || (bytes_per_datum == 0))
return -EINVAL;
/*
* Make sure we don't overflow an unsigned int after kfifo rounds up to
* the next power of 2.
*/
if (roundup_pow_of_two(length) > UINT_MAX / bytes_per_datum)
return -EINVAL;
return __kfifo_alloc((struct __kfifo *)&buf->kf, length,
bytes_per_datum, GFP_KERNEL);
}
......@@ -67,7 +74,7 @@ static int iio_set_bytes_per_datum_kfifo(struct iio_buffer *r, size_t bpd)
return 0;
}
static int iio_set_length_kfifo(struct iio_buffer *r, int length)
static int iio_set_length_kfifo(struct iio_buffer *r, unsigned int length)
{
/* Avoid an invalid state */
if (length < 2)
......
......@@ -178,14 +178,14 @@ int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
#ifdef CONFIG_PM
int ret;
atomic_set(&st->user_requested_state, state);
if (atomic_add_unless(&st->runtime_pm_enable, 1, 1))
pm_runtime_enable(&st->pdev->dev);
if (state)
if (state) {
atomic_inc(&st->user_requested_state);
ret = pm_runtime_get_sync(&st->pdev->dev);
else {
} else {
atomic_dec(&st->user_requested_state);
pm_runtime_mark_last_busy(&st->pdev->dev);
pm_runtime_use_autosuspend(&st->pdev->dev);
ret = pm_runtime_put_autosuspend(&st->pdev->dev);
......
......@@ -53,7 +53,7 @@ struct iio_buffer_access_funcs {
int (*request_update)(struct iio_buffer *buffer);
int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd);
int (*set_length)(struct iio_buffer *buffer, int length);
int (*set_length)(struct iio_buffer *buffer, unsigned int length);
int (*enable)(struct iio_buffer *buffer, struct iio_dev *indio_dev);
int (*disable)(struct iio_buffer *buffer, struct iio_dev *indio_dev);
......@@ -72,10 +72,10 @@ struct iio_buffer_access_funcs {
*/
struct iio_buffer {
/** @length: Number of datums in buffer. */
int length;
unsigned int length;
/** @bytes_per_datum: Size of individual datum including timestamp. */
int bytes_per_datum;
size_t bytes_per_datum;
/**
* @access: Buffer access functions associated with the
......
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