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. -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAlrwhdsRHGppYzIzQGtl cm5lbC5vcmcACgkQVIU0mcT0Fog75w//SWKY1QTUdP3fdcvMlF8K9/Lu++MM8XcN c90LjoWbWJz8Qne9va8+JIb00FdWC4xUDXSD3T73RUqxpj2L+PhuhByYgLHrkuNG vhF21gK+NFYkreNo7N8LyVVStLQn28upIDW39fcxPPZrxuhW5+7bJ6c2ovUJ4uqB Waljqj7sPxZQHDt9K+0WoRhsxvDVKKKqDYe3jvOqhK1Z7cylBtMct6Pa7vk6VDon LBPrObHNFcrkuC2eVVryBOff4y5nvi6sGHo9xeWyG6wLg5N7eXMWGnpvB56qLt+M ywT0U6EILvCbLaCFC7Qyinvcsn+W1udQi3zNbFNYI+nBvdMiOA14dEfb5IC2iH1g Nkinnc0HpPvZJPqTijS7ngQ89LiUZAdYPPEt2rodoNu5yZ4Vt/6rNvJasdJUMV78 IEgn4Be1dfw9fIKJJXu7Jnp9Dr444sRxjgFNPByOobjtozN4ENgkfGyItBP7jsbJ oXzX+Pt90Jc6plw28zx+tGx76SB52HLgPwZgfRCjpH6lZ730keTA7d+e7DbBGf0A Bfm5DGD3NWBRfFWsr0ImGMEeST0ZwqbEWsnfPpEQxGZe9WvP60WPYVF0DgmQw1On CTgUR3QF7MtwddBL4NaluPgHJeuYHJAihy3KtIK+NSDNIUXgzdjqCQioaniLmzQx q1egq6KxqRU= =1bkD -----END PGP SIGNATURE----- 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.
This commit is contained in:
commit
9d569b1cf7
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user