diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index d67d78394cb9a621e1239b9c0d17ee7b34d9d5ec..c8169338b2761e59ca49e47467ed84dd185480f0 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -61,8 +61,9 @@ ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring, ret = ring->access->read_last(ring, (u8 *)data); if (ret) goto error_free_data; - *val = data[bitmap_weight(&ring->scan_mask, index)]; + *val = data[bitmap_weight(ring->scan_mask, index)]; error_free_data: + kfree(data); return ret; @@ -99,7 +100,7 @@ static int lis3l02dq_read_all(struct iio_dev *indio_dev, u8 *rx_array) mutex_lock(&st->buf_lock); for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++) - if (ring->scan_mask & (1 << i)) { + if (test_bit(i, ring->scan_mask)) { /* lower byte */ xfers[j].tx_buf = st->tx + 2*j; st->tx[2*j] = read_all_tx_array[i*4]; diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 80b067c5b21251f6fcd9182451e5dd276ee797e0..c67da6aac9999e0f45de044f9fa1413a161ff4cc 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -146,7 +146,7 @@ struct ad7192_state { u32 mode; u32 conf; u32 scale_avail[8][2]; - u32 available_scan_masks[9]; + long available_scan_masks[9]; u8 gpocon; u8 devid; /* @@ -460,7 +460,7 @@ static int ad7192_scan_from_ring(struct ad7192_state *st, unsigned ch, int *val) s64 dat64[2]; u32 *dat32 = (u32 *)dat64; - if (!(ring->scan_mask & (1 << ch))) + if (!(test_bit(ch, ring->scan_mask))) return -EBUSY; ret = ring->access->read_last(ring, (u8 *) &dat64); @@ -482,7 +482,7 @@ static int ad7192_ring_preenable(struct iio_dev *indio_dev) if (!ring->scan_count) return -EINVAL; - channel = __ffs(ring->scan_mask); + channel = find_first_bit(ring->scan_mask, indio_dev->masklength); d_size = ring->scan_count * indio_dev->channels[0].scan_type.storagebits / 8; diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index 741818c0b8290b2426fdf111e92e827779b4b628..246b2e724d385b41357d0f376efd83f7f3d80555 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c @@ -24,7 +24,7 @@ int ad7298_scan_from_ring(struct iio_dev *dev_info, long ch) int ret; u16 *ring_data; - if (!(ring->scan_mask & (1 << ch))) { + if (!(test_bit(ch, ring->scan_mask))) { ret = -EBUSY; goto error_ret; } @@ -79,7 +79,7 @@ static int ad7298_ring_preenable(struct iio_dev *indio_dev) command = AD7298_WRITE | st->ext_ref; for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1) - if (ring->scan_mask & (1 << i)) + if (test_bit(i, ring->scan_mask)) command |= m; st->tx_buf[0] = cpu_to_be16(command); diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 38095eba0994da4da8c5ccdd1f00d220089ace75..b42a7ace426de681c2edffa34e1f1c9dfcd2ef1a 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -51,7 +51,8 @@ struct ad7793_state { u16 mode; u16 conf; u32 scale_avail[8][2]; - u32 available_scan_masks[7]; + /* Note this uses fact that 8 the mask always fits in a long */ + unsigned long available_scan_masks[7]; /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. @@ -321,7 +322,7 @@ static int ad7793_scan_from_ring(struct ad7793_state *st, unsigned ch, int *val) s64 dat64[2]; u32 *dat32 = (u32 *)dat64; - if (!(ring->scan_mask & (1 << ch))) + if (!(test_bit(ch, ring->scan_mask))) return -EBUSY; ret = ring->access->read_last(ring, (u8 *) &dat64); @@ -343,7 +344,8 @@ static int ad7793_ring_preenable(struct iio_dev *indio_dev) if (!ring->scan_count) return -EINVAL; - channel = __ffs(ring->scan_mask); + channel = find_first_bit(ring->scan_mask, + indio_dev->masklength); d_size = ring->scan_count * indio_dev->channels[0].scan_type.storagebits / 8; @@ -875,10 +877,12 @@ static int __devinit ad7793_probe(struct spi_device *spi) indio_dev->num_channels = 7; indio_dev->info = &ad7793_info; - for (i = 0; i < indio_dev->num_channels; i++) - st->available_scan_masks[i] = (1 << i) | (1 << - indio_dev->channels[indio_dev->num_channels - 1]. - scan_index); + for (i = 0; i < indio_dev->num_channels; i++) { + set_bit(i, &st->available_scan_masks[i]); + set_bit(indio_dev-> + channels[indio_dev->num_channels - 1].scan_index, + &st->available_scan_masks[i]); + } init_waitqueue_head(&st->wq_data_avail); diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h index 837046c7b894f54db1e11c963db45dd487af2c73..1b7a772934cc1b2b57761bb525d62d84f30ad897 100644 --- a/drivers/staging/iio/adc/ad7887.h +++ b/drivers/staging/iio/adc/ad7887.h @@ -83,11 +83,11 @@ enum ad7887_supported_device_ids { }; #ifdef CONFIG_IIO_RING_BUFFER -int ad7887_scan_from_ring(struct ad7887_state *st, long mask); +int ad7887_scan_from_ring(struct ad7887_state *st, int channum); int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev); void ad7887_ring_cleanup(struct iio_dev *indio_dev); #else /* CONFIG_IIO_RING_BUFFER */ -static inline int ad7887_scan_from_ring(struct ad7887_state *st, long mask) +static inline int ad7887_scan_from_ring(struct ad7887_state *st, int channum) { return 0; } diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c index 6b3daf41e0c69828d5c2495fc34dce9aec1aeea2..36e118cf32e2b95728fe3a0773f6272a92418a4a 100644 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -19,13 +19,13 @@ #include "ad7887.h" -int ad7887_scan_from_ring(struct ad7887_state *st, long mask) +int ad7887_scan_from_ring(struct ad7887_state *st, int channum) { struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring; int count = 0, ret; u16 *ring_data; - if (!(ring->scan_mask & mask)) { + if (!(test_bit(channum, ring->scan_mask))) { ret = -EBUSY; goto error_ret; } @@ -41,7 +41,8 @@ int ad7887_scan_from_ring(struct ad7887_state *st, long mask) goto error_free_ring_data; /* for single channel scan the result is stored with zero offset */ - if ((ring->scan_mask == ((1 << 1) | (1 << 0))) && (mask == (1 << 1))) + if ((test_bit(1, ring->scan_mask) || test_bit(0, ring->scan_mask)) && + (channum == 1)) count = 1; ret = be16_to_cpu(ring_data[count]); @@ -78,7 +79,8 @@ static int ad7887_ring_preenable(struct iio_dev *indio_dev) indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring, st->d_size); - switch (ring->scan_mask) { + /* We know this is a single long so can 'cheat' */ + switch (*ring->scan_mask) { case (1 << 0): st->ring_msg = &st->msg[AD7887_CH0]; break; diff --git a/drivers/staging/iio/adc/ad799x.h b/drivers/staging/iio/adc/ad799x.h index 0dc9b4c73a33af36ac2ede6e19f7ded3d71111ab..98f06f682b8e4418793b7c8f35a351769d7db0e8 100644 --- a/drivers/staging/iio/adc/ad799x.h +++ b/drivers/staging/iio/adc/ad799x.h @@ -124,11 +124,11 @@ struct ad799x_platform_data { int ad7997_8_set_scan_mode(struct ad799x_state *st, unsigned mask); #ifdef CONFIG_AD799X_RING_BUFFER -int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask); +int ad799x_single_channel_from_ring(struct ad799x_state *st, int channum); int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev); void ad799x_ring_cleanup(struct iio_dev *indio_dev); #else /* CONFIG_AD799X_RING_BUFFER */ -int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask) +int ad799x_single_channel_from_ring(struct ad799x_state *st, int channum) { return -EINVAL; } diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c index 299183c05d434835ee96e62335f0955e6f861d21..cfe4b2caea8c672a5ef6ab978a57ad82be373ad5 100644 --- a/drivers/staging/iio/adc/ad799x_core.c +++ b/drivers/staging/iio/adc/ad799x_core.c @@ -151,7 +151,7 @@ static int ad799x_read_raw(struct iio_dev *dev_info, mutex_lock(&dev_info->mlock); if (iio_ring_enabled(dev_info)) ret = ad799x_single_channel_from_ring(st, - 1 << chan->address); + chan->address); else ret = ad799x_scan_direct(st, chan->address); mutex_unlock(&dev_info->mlock); diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c index 8f1fc52560f1473caa25a584f04c29074c1d1d88..438e81d190c68ea06ff1d4bea8dee12a931e08a2 100644 --- a/drivers/staging/iio/adc/ad799x_ring.c +++ b/drivers/staging/iio/adc/ad799x_ring.c @@ -23,13 +23,13 @@ #include "ad799x.h" -int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask) +int ad799x_single_channel_from_ring(struct ad799x_state *st, int channum) { struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring; int count = 0, ret; u16 *ring_data; - if (!(ring->scan_mask & mask)) { + if (!(test_bit(channum, ring->scan_mask))) { ret = -EBUSY; goto error_ret; } @@ -44,13 +44,7 @@ int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask) if (ret) goto error_free_ring_data; /* Need a count of channels prior to this one */ - mask >>= 1; - while (mask) { - if (mask & ring->scan_mask) - count++; - mask >>= 1; - } - + count = bitmap_weight(ring->scan_mask, channum); ret = be16_to_cpu(ring_data[count]); error_free_ring_data: @@ -77,7 +71,7 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev) */ if (st->id == ad7997 || st->id == ad7998) - ad7997_8_set_scan_mode(st, ring->scan_mask); + ad7997_8_set_scan_mode(st, *ring->scan_mask); st->d_size = ring->scan_count * 2; @@ -121,12 +115,12 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p) case ad7991: case ad7995: case ad7999: - cmd = st->config | (ring->scan_mask << AD799X_CHANNEL_SHIFT); + cmd = st->config | (*ring->scan_mask << AD799X_CHANNEL_SHIFT); break; case ad7992: case ad7993: case ad7994: - cmd = (ring->scan_mask << AD799X_CHANNEL_SHIFT) | + cmd = (*ring->scan_mask << AD799X_CHANNEL_SHIFT) | AD7998_CONV_RES_REG; break; case ad7997: diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h index 360bfc5398fc7d7c6d6d3192bf9621769af34f66..cbcb08a2cb50de65774c9f8304c6bb010919c672 100644 --- a/drivers/staging/iio/adc/max1363.h +++ b/drivers/staging/iio/adc/max1363.h @@ -57,6 +57,7 @@ #define MAX1363_SCAN_MASK 0x60 #define MAX1363_SE_DE_MASK 0x01 +#define MAX1363_MAX_CHANNELS 25 /** * struct max1363_mode - scan mode information * @conf: The corresponding value of the configuration register @@ -64,7 +65,7 @@ */ struct max1363_mode { int8_t conf; - long modemask; + DECLARE_BITMAP(modemask, MAX1363_MAX_CHANNELS); }; /* This must be maintained along side the max1363_mode_table in max1363_core */ @@ -145,13 +146,14 @@ struct max1363_state { }; const struct max1363_mode -*max1363_match_mode(u32 mask, const struct max1363_chip_info *ci); +*max1363_match_mode(unsigned long *mask, const struct max1363_chip_info *ci); int max1363_set_scan_mode(struct max1363_state *st); #ifdef CONFIG_MAX1363_RING_BUFFER -int max1363_single_channel_from_ring(long mask, struct max1363_state *st); +int max1363_single_channel_from_ring(const long *mask, + struct max1363_state *st); int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev); void max1363_ring_cleanup(struct iio_dev *indio_dev); diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index e921efa7196f59f353eacc47f63f703ca5473740..49b2ce22e6edb6b27f57cf080b19646260bd9969 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -42,14 +42,14 @@ .conf = MAX1363_CHANNEL_SEL(_num) \ | MAX1363_CONFIG_SCAN_SINGLE_1 \ | MAX1363_CONFIG_SE, \ - .modemask = _mask, \ + .modemask[0] = _mask, \ } #define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) { \ .conf = MAX1363_CHANNEL_SEL(_num) \ | MAX1363_CONFIG_SCAN_TO_CS \ | MAX1363_CONFIG_SE, \ - .modemask = _mask, \ + .modemask[0] = _mask, \ } /* note not available for max1363 hence naming */ @@ -57,14 +57,14 @@ .conf = MAX1363_CHANNEL_SEL(_num) \ | MAX1236_SCAN_MID_TO_CHANNEL \ | MAX1363_CONFIG_SE, \ - .modemask = _mask \ + .modemask[0] = _mask \ } #define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) { \ .conf = MAX1363_CHANNEL_SEL(_nump) \ | MAX1363_CONFIG_SCAN_SINGLE_1 \ | MAX1363_CONFIG_DE, \ - .modemask = _mask \ + .modemask[0] = _mask \ } /* Can't think how to automate naming so specify for now */ @@ -72,7 +72,7 @@ .conf = MAX1363_CHANNEL_SEL(_num) \ | MAX1363_CONFIG_SCAN_TO_CS \ | MAX1363_CONFIG_DE, \ - .modemask = _mask \ + .modemask[0] = _mask \ } /* note only available for max1363 hence naming */ @@ -80,7 +80,7 @@ .conf = MAX1363_CHANNEL_SEL(_num) \ | MAX1236_SCAN_MID_TO_CHANNEL \ | MAX1363_CONFIG_SE, \ - .modemask = _mask \ + .modemask[0] = _mask \ } static const struct max1363_mode max1363_mode_table[] = { @@ -147,13 +147,15 @@ static const struct max1363_mode max1363_mode_table[] = { }; const struct max1363_mode -*max1363_match_mode(u32 mask, const struct max1363_chip_info *ci) +*max1363_match_mode(unsigned long *mask, const struct max1363_chip_info *ci) { int i; if (mask) for (i = 0; i < ci->num_modes; i++) - if (!((~max1363_mode_table[ci->mode_list[i]].modemask) & - mask)) + if (bitmap_subset(mask, + max1363_mode_table[ci->mode_list[i]]. + modemask, + MAX1363_MAX_CHANNELS)) return &max1363_mode_table[ci->mode_list[i]]; return NULL; } @@ -187,7 +189,7 @@ static int max1363_read_single_chan(struct iio_dev *indio_dev, int ret = 0; s32 data; char rxbuf[2]; - long mask; + const unsigned long *mask; struct max1363_state *st = iio_priv(indio_dev); struct i2c_client *client = st->client; @@ -644,7 +646,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled) int ret, i = 3, j; unsigned long numelements; int len; - long modemask; + const long *modemask; if (!enabled) { /* transition to ring capture is not currently supported */ @@ -672,7 +674,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled) st->configbyte |= max1363_mode_table[d1m0to3m2].conf; modemask = max1363_mode_table[d1m0to3m2].modemask; } - numelements = hweight_long(modemask); + numelements = bitmap_weight(modemask, MAX1363_MAX_CHANNELS); len = 3 * numelements + 3; tx_buf = kmalloc(len, GFP_KERNEL); if (!tx_buf) { @@ -688,7 +690,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled) * setup to match what we need. */ for (j = 0; j < 8; j++) - if (modemask & (1 << j)) { + if (test_bit(j, modemask)) { /* Establish the mode is in the scan */ if (st->mask_low & (1 << j)) { tx_buf[i] = (st->thresh_low[j] >> 4) & 0xFF; @@ -1281,7 +1283,7 @@ static int __devinit max1363_probe(struct i2c_client *client, st->client = client; indio_dev->available_scan_masks - = kzalloc(sizeof(*indio_dev->available_scan_masks)* + = kzalloc(BITS_TO_LONGS(MAX1363_MAX_CHANNELS)* (st->chip_info->num_modes + 1), GFP_KERNEL); if (!indio_dev->available_scan_masks) { ret = -ENOMEM; @@ -1289,9 +1291,10 @@ static int __devinit max1363_probe(struct i2c_client *client, } for (i = 0; i < st->chip_info->num_modes; i++) - indio_dev->available_scan_masks[i] = - max1363_mode_table[st->chip_info->mode_list[i]] - .modemask; + bitmap_copy(indio_dev->available_scan_masks + + BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*i, + max1363_mode_table[st->chip_info->mode_list[i]] + .modemask, MAX1363_MAX_CHANNELS); /* Estabilish that the iio_dev is a child of the i2c device */ indio_dev->dev.parent = &client->dev; indio_dev->name = id->name; diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index be601e07639db4983129c8523364676c1a9354a0..abe9e03f36e33ca9c4193c77d3c32d0840f054a6 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -21,12 +21,14 @@ #include "max1363.h" -int max1363_single_channel_from_ring(long mask, struct max1363_state *st) +int max1363_single_channel_from_ring(const long *mask, struct max1363_state *st) { struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring; - int count = 0, ret; + int count = 0, ret, index; u8 *ring_data; - if (!(st->current_mode->modemask & mask)) { + index = find_first_bit(mask, MAX1363_MAX_CHANNELS); + + if (!(test_bit(index, st->current_mode->modemask))) { ret = -EBUSY; goto error_ret; } @@ -41,12 +43,8 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st) if (ret) goto error_free_ring_data; /* Need a count of channels prior to this one */ - mask >>= 1; - while (mask) { - if (mask & st->current_mode->modemask) - count++; - mask >>= 1; - } + + count = bitmap_weight(mask, index - 1); if (st->chip_info->bits != 8) ret = ((int)(ring_data[count*2 + 0] & 0x0F) << 8) + (int)(ring_data[count*2 + 1]); @@ -85,7 +83,8 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev) max1363_set_scan_mode(st); - numvals = hweight_long(st->current_mode->modemask); + numvals = bitmap_weight(st->current_mode->modemask, + indio_dev->masklength); if (ring->access->set_bytes_per_datum) { if (ring->scan_timestamp) d_size += sizeof(s64); @@ -110,7 +109,8 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p) __u8 *rxbuf; int b_sent; size_t d_size; - unsigned long numvals = hweight_long(st->current_mode->modemask); + unsigned long numvals = bitmap_weight(st->current_mode->modemask, + MAX1363_MAX_CHANNELS); /* Ensure the timestamp is 8 byte aligned */ if (st->chip_info->bits != 8) diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index daaea94a5e6d26ec5e93425f7991794b593a4fe3..635fa73e4623f5edff9640dfd1837e2941caa315 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -272,6 +272,8 @@ struct iio_info { * @mlock: [INTERN] lock used to prevent simultaneous device state * changes * @available_scan_masks: [DRIVER] optional array of allowed bitmasks + * @masklength: [INTERN] the length of the mask established from + * channels * @trig: [INTERN] current device trigger (ring buffer modes) * @pollfunc: [DRIVER] function run on trigger being received * @channels: [DRIVER] channel specification structure table @@ -294,7 +296,8 @@ struct iio_dev { struct iio_ring_buffer *ring; struct mutex mlock; - u32 *available_scan_masks; + unsigned long *available_scan_masks; + unsigned masklength; struct iio_trigger *trig; struct iio_poll_func *pollfunc; diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 1c1cd8eac9de4aa5bcc8b5f8fab70b8a4ad9c4d1..e199bbed75e953bdc20da925715b0d8d5c8137c9 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -640,7 +640,7 @@ static void ad5933_work(struct work_struct *work) if (status & AD5933_STAT_DATA_VALID) { ad5933_i2c_read(st->client, - (ring->scan_mask & (1 << 0)) ? + test_bit(1, ring->scan_mask) ? AD5933_REG_REAL_DATA : AD5933_REG_IMAG_DATA, ring->scan_count * 2, (u8 *)buf); diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c index d2506b1b2db0e8352eddd3276b2102acd19208b9..af25697dab987073062d2b0748b6d66e55ee8c4e 100644 --- a/drivers/staging/iio/imu/adis16400_ring.c +++ b/drivers/staging/iio/imu/adis16400_ring.c @@ -85,7 +85,7 @@ static int adis16350_spi_read_all(struct device *dev, u8 *rx) return -ENOMEM; for (i = 0; i < ARRAY_SIZE(read_all_tx_array); i++) - if (indio_dev->ring->scan_mask & (1 << i)) { + if (test_bit(i, indio_dev->ring->scan_mask)) { xfers[j].tx_buf = &read_all_tx_array[i]; xfers[j].bits_per_word = 16; xfers[j].len = 2; @@ -117,7 +117,8 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p) int i = 0, j, ret = 0; s16 *data; size_t datasize = ring->access->get_bytes_per_datum(ring); - unsigned long mask = ring->scan_mask; + /* Asumption that long is enough for maximum channels */ + unsigned long mask = *ring->scan_mask; data = kmalloc(datasize , GFP_KERNEL); if (data == NULL) { diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c index 23967d491925123c59ae4d6bc176ebeeb0ddd6cf..6f14c0d848677ce21edb3ba67a6200df9ac3652d 100644 --- a/drivers/staging/iio/industrialio-ring.c +++ b/drivers/staging/iio/industrialio-ring.c @@ -132,9 +132,7 @@ static ssize_t iio_scan_el_show(struct device *dev, static int iio_scan_mask_clear(struct iio_ring_buffer *ring, int bit) { - if (bit > IIO_MAX_SCAN_LENGTH) - return -EINVAL; - ring->scan_mask &= ~(1 << bit); + clear_bit(bit, ring->scan_mask); ring->scan_count--; return 0; } @@ -323,11 +321,27 @@ int iio_ring_buffer_register(struct iio_dev *indio_dev, if (channels) { /* new magic */ for (i = 0; i < num_channels; i++) { + /* Establish necessary mask length */ + if (channels[i].scan_index > + (int)indio_dev->masklength - 1) + indio_dev->masklength + = indio_dev->channels[i].scan_index + 1; + ret = iio_ring_add_channel_sysfs(indio_dev, &channels[i]); if (ret < 0) goto error_cleanup_group; } + if (indio_dev->masklength && ring->scan_mask == NULL) { + ring->scan_mask + = kzalloc(sizeof(*ring->scan_mask)* + BITS_TO_LONGS(indio_dev->masklength), + GFP_KERNEL); + if (ring->scan_mask == NULL) { + ret = -ENOMEM; + goto error_cleanup_group; + } + } } return 0; @@ -343,6 +357,7 @@ EXPORT_SYMBOL(iio_ring_buffer_register); void iio_ring_buffer_unregister(struct iio_dev *indio_dev) { + kfree(indio_dev->ring->scan_mask); if (indio_dev->ring->attrs) sysfs_remove_group(&indio_dev->dev.kobj, indio_dev->ring->attrs); @@ -539,3 +554,85 @@ int iio_sw_ring_preenable(struct iio_dev *indio_dev) return 0; } EXPORT_SYMBOL(iio_sw_ring_preenable); + + +/* note NULL used as error indicator as it doesn't make sense. */ +static unsigned long *iio_scan_mask_match(unsigned long *av_masks, + unsigned int masklength, + unsigned long *mask) +{ + if (bitmap_empty(mask, masklength)) + return NULL; + while (*av_masks) { + if (bitmap_subset(mask, av_masks, masklength)) + return av_masks; + av_masks += BITS_TO_LONGS(masklength); + } + return NULL; +} + +/** + * iio_scan_mask_set() - set particular bit in the scan mask + * @ring: the ring buffer whose scan mask we are interested in + * @bit: the bit to be set. + **/ +int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit) +{ + struct iio_dev *dev_info = ring->indio_dev; + unsigned long *mask; + unsigned long *trialmask; + + trialmask = kmalloc(sizeof(*trialmask)* + BITS_TO_LONGS(dev_info->masklength), + GFP_KERNEL); + + if (trialmask == NULL) + return -ENOMEM; + if (!dev_info->masklength) { + WARN_ON("trying to set scan mask prior to registering ring\n"); + kfree(trialmask); + return -EINVAL; + } + bitmap_copy(trialmask, ring->scan_mask, dev_info->masklength); + set_bit(bit, trialmask); + + if (dev_info->available_scan_masks) { + mask = iio_scan_mask_match(dev_info->available_scan_masks, + dev_info->masklength, + trialmask); + if (!mask) { + kfree(trialmask); + return -EINVAL; + } + } + bitmap_copy(ring->scan_mask, trialmask, dev_info->masklength); + ring->scan_count++; + + kfree(trialmask); + + return 0; +}; +EXPORT_SYMBOL_GPL(iio_scan_mask_set); + +int iio_scan_mask_query(struct iio_ring_buffer *ring, int bit) +{ + struct iio_dev *dev_info = ring->indio_dev; + long *mask; + + if (bit > dev_info->masklength) + return -EINVAL; + + if (!ring->scan_mask) + return 0; + if (dev_info->available_scan_masks) + mask = iio_scan_mask_match(dev_info->available_scan_masks, + dev_info->masklength, + ring->scan_mask); + else + mask = ring->scan_mask; + if (!mask) + return 0; + + return test_bit(bit, mask); +}; +EXPORT_SYMBOL_GPL(iio_scan_mask_query); diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h index 4d73e1a38815bd375c3f3a231f1ce5eb98bcc70d..20a2bcace7f41c673eb4b3220f7e53c3aa6fa7f8 100644 --- a/drivers/staging/iio/meter/ade7758.h +++ b/drivers/staging/iio/meter/ade7758.h @@ -122,7 +122,7 @@ struct ade7758_state { u8 *tx; u8 *rx; struct mutex buf_lock; - u32 available_scan_masks[AD7758_NUM_WAVESRC]; + unsigned long available_scan_masks[AD7758_NUM_WAVESRC]; struct iio_chan_spec *ade7758_ring_channels; struct spi_transfer ring_xfer[4]; struct spi_message ring_msg; diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 77bd2761f272f5ba1325b8e3351cee503ecdd1e5..ce513bda0216134df9704ed6fd3480cca84bccf8 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -767,7 +767,7 @@ static int __devinit ade7758_probe(struct spi_device *spi) indio_dev->modes = INDIO_DIRECT_MODE; for (i = 0; i < AD7758_NUM_WAVESRC; i++) - st->available_scan_masks[i] = 1 << i; + set_bit(i, &st->available_scan_masks[i]); indio_dev->available_scan_masks = st->available_scan_masks; diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c index 5e740e386162cb9ab75dd3931a67338dbc8b7297..9934f508ded27d46ef48aab7cf275c782e59a964 100644 --- a/drivers/staging/iio/meter/ade7758_ring.c +++ b/drivers/staging/iio/meter/ade7758_ring.c @@ -98,7 +98,7 @@ static int ade7758_ring_preenable(struct iio_dev *indio_dev) if (!ring->scan_count) return -EINVAL; - channel = __ffs(ring->scan_mask); + channel = find_first_bit(ring->scan_mask, indio_dev->masklength); d_size = st->ade7758_ring_channels[channel].scan_type.storagebits / 8; diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h index 25aacf3b89331f67f42bee8e324dcc7aa3e81432..7a47f62755692c18d8639508ba4c898509c6789a 100644 --- a/drivers/staging/iio/ring_generic.h +++ b/drivers/staging/iio/ring_generic.h @@ -104,7 +104,7 @@ struct iio_ring_buffer { int bpe; struct attribute_group *scan_el_attrs; int scan_count; - unsigned long scan_mask; + long *scan_mask; bool scan_timestamp; const struct iio_ring_access_funcs *access; const struct iio_ring_setup_ops *setup_ops; @@ -124,6 +124,8 @@ struct iio_ring_buffer { void iio_ring_buffer_init(struct iio_ring_buffer *ring, struct iio_dev *dev_info); +void iio_ring_buffer_deinit(struct iio_ring_buffer *ring); + /** * __iio_update_ring_buffer() - update common elements of ring buffers * @ring: ring buffer that is the event source @@ -137,70 +139,14 @@ static inline void __iio_update_ring_buffer(struct iio_ring_buffer *ring, ring->length = length; } -/* - * These are mainly provided to allow for a change of implementation if a device - * has a large number of scan elements - */ -#define IIO_MAX_SCAN_LENGTH 31 - -/* note 0 used as error indicator as it doesn't make sense. */ -static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask) -{ - while (*av_masks) { - if (!(~*av_masks & mask)) - return *av_masks; - av_masks++; - } - return 0; -} - -static inline int iio_scan_mask_query(struct iio_ring_buffer *ring, int bit) -{ - struct iio_dev *dev_info = ring->indio_dev; - u32 mask; - - if (bit > IIO_MAX_SCAN_LENGTH) - return -EINVAL; - - if (!ring->scan_mask) - return 0; - - if (dev_info->available_scan_masks) - mask = iio_scan_mask_match(dev_info->available_scan_masks, - ring->scan_mask); - else - mask = ring->scan_mask; - - if (!mask) - return -EINVAL; - - return !!(mask & (1 << bit)); -}; +int iio_scan_mask_query(struct iio_ring_buffer *ring, int bit); /** * iio_scan_mask_set() - set particular bit in the scan mask * @ring: the ring buffer whose scan mask we are interested in * @bit: the bit to be set. **/ -static inline int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit) -{ - struct iio_dev *dev_info = ring->indio_dev; - u32 mask; - u32 trialmask = ring->scan_mask | (1 << bit); - - if (bit > IIO_MAX_SCAN_LENGTH) - return -EINVAL; - if (dev_info->available_scan_masks) { - mask = iio_scan_mask_match(dev_info->available_scan_masks, - trialmask); - if (!mask) - return -EINVAL; - } - ring->scan_mask = trialmask; - ring->scan_count++; - - return 0; -}; +int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit); #define to_iio_ring_buffer(d) \ container_of(d, struct iio_ring_buffer, dev)