diff options
-rw-r--r-- | drivers/iio/industrialio-buffer.c | 149 | ||||
-rw-r--r-- | include/linux/iio/buffer.h | 9 |
2 files changed, 74 insertions, 84 deletions
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index f971f79103ec..f667e4e7ea6d 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c | |||
@@ -178,6 +178,80 @@ static ssize_t iio_scan_el_show(struct device *dev, | |||
178 | return sprintf(buf, "%d\n", ret); | 178 | return sprintf(buf, "%d\n", ret); |
179 | } | 179 | } |
180 | 180 | ||
181 | /* Note NULL used as error indicator as it doesn't make sense. */ | ||
182 | static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks, | ||
183 | unsigned int masklength, | ||
184 | const unsigned long *mask) | ||
185 | { | ||
186 | if (bitmap_empty(mask, masklength)) | ||
187 | return NULL; | ||
188 | while (*av_masks) { | ||
189 | if (bitmap_subset(mask, av_masks, masklength)) | ||
190 | return av_masks; | ||
191 | av_masks += BITS_TO_LONGS(masklength); | ||
192 | } | ||
193 | return NULL; | ||
194 | } | ||
195 | |||
196 | static bool iio_validate_scan_mask(struct iio_dev *indio_dev, | ||
197 | const unsigned long *mask) | ||
198 | { | ||
199 | if (!indio_dev->setup_ops->validate_scan_mask) | ||
200 | return true; | ||
201 | |||
202 | return indio_dev->setup_ops->validate_scan_mask(indio_dev, mask); | ||
203 | } | ||
204 | |||
205 | /** | ||
206 | * iio_scan_mask_set() - set particular bit in the scan mask | ||
207 | * @indio_dev: the iio device | ||
208 | * @buffer: the buffer whose scan mask we are interested in | ||
209 | * @bit: the bit to be set. | ||
210 | * | ||
211 | * Note that at this point we have no way of knowing what other | ||
212 | * buffers might request, hence this code only verifies that the | ||
213 | * individual buffers request is plausible. | ||
214 | */ | ||
215 | static int iio_scan_mask_set(struct iio_dev *indio_dev, | ||
216 | struct iio_buffer *buffer, int bit) | ||
217 | { | ||
218 | const unsigned long *mask; | ||
219 | unsigned long *trialmask; | ||
220 | |||
221 | trialmask = kmalloc(sizeof(*trialmask)* | ||
222 | BITS_TO_LONGS(indio_dev->masklength), | ||
223 | GFP_KERNEL); | ||
224 | |||
225 | if (trialmask == NULL) | ||
226 | return -ENOMEM; | ||
227 | if (!indio_dev->masklength) { | ||
228 | WARN_ON("Trying to set scanmask prior to registering buffer\n"); | ||
229 | goto err_invalid_mask; | ||
230 | } | ||
231 | bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength); | ||
232 | set_bit(bit, trialmask); | ||
233 | |||
234 | if (!iio_validate_scan_mask(indio_dev, trialmask)) | ||
235 | goto err_invalid_mask; | ||
236 | |||
237 | if (indio_dev->available_scan_masks) { | ||
238 | mask = iio_scan_mask_match(indio_dev->available_scan_masks, | ||
239 | indio_dev->masklength, | ||
240 | trialmask); | ||
241 | if (!mask) | ||
242 | goto err_invalid_mask; | ||
243 | } | ||
244 | bitmap_copy(buffer->scan_mask, trialmask, indio_dev->masklength); | ||
245 | |||
246 | kfree(trialmask); | ||
247 | |||
248 | return 0; | ||
249 | |||
250 | err_invalid_mask: | ||
251 | kfree(trialmask); | ||
252 | return -EINVAL; | ||
253 | } | ||
254 | |||
181 | static int iio_scan_mask_clear(struct iio_buffer *buffer, int bit) | 255 | static int iio_scan_mask_clear(struct iio_buffer *buffer, int bit) |
182 | { | 256 | { |
183 | clear_bit(bit, buffer->scan_mask); | 257 | clear_bit(bit, buffer->scan_mask); |
@@ -455,21 +529,6 @@ ssize_t iio_buffer_show_enable(struct device *dev, | |||
455 | } | 529 | } |
456 | EXPORT_SYMBOL(iio_buffer_show_enable); | 530 | EXPORT_SYMBOL(iio_buffer_show_enable); |
457 | 531 | ||
458 | /* Note NULL used as error indicator as it doesn't make sense. */ | ||
459 | static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks, | ||
460 | unsigned int masklength, | ||
461 | const unsigned long *mask) | ||
462 | { | ||
463 | if (bitmap_empty(mask, masklength)) | ||
464 | return NULL; | ||
465 | while (*av_masks) { | ||
466 | if (bitmap_subset(mask, av_masks, masklength)) | ||
467 | return av_masks; | ||
468 | av_masks += BITS_TO_LONGS(masklength); | ||
469 | } | ||
470 | return NULL; | ||
471 | } | ||
472 | |||
473 | static int iio_compute_scan_bytes(struct iio_dev *indio_dev, | 532 | static int iio_compute_scan_bytes(struct iio_dev *indio_dev, |
474 | const unsigned long *mask, bool timestamp) | 533 | const unsigned long *mask, bool timestamp) |
475 | { | 534 | { |
@@ -808,66 +867,6 @@ bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev, | |||
808 | } | 867 | } |
809 | EXPORT_SYMBOL_GPL(iio_validate_scan_mask_onehot); | 868 | EXPORT_SYMBOL_GPL(iio_validate_scan_mask_onehot); |
810 | 869 | ||
811 | static bool iio_validate_scan_mask(struct iio_dev *indio_dev, | ||
812 | const unsigned long *mask) | ||
813 | { | ||
814 | if (!indio_dev->setup_ops->validate_scan_mask) | ||
815 | return true; | ||
816 | |||
817 | return indio_dev->setup_ops->validate_scan_mask(indio_dev, mask); | ||
818 | } | ||
819 | |||
820 | /** | ||
821 | * iio_scan_mask_set() - set particular bit in the scan mask | ||
822 | * @indio_dev: the iio device | ||
823 | * @buffer: the buffer whose scan mask we are interested in | ||
824 | * @bit: the bit to be set. | ||
825 | * | ||
826 | * Note that at this point we have no way of knowing what other | ||
827 | * buffers might request, hence this code only verifies that the | ||
828 | * individual buffers request is plausible. | ||
829 | */ | ||
830 | int iio_scan_mask_set(struct iio_dev *indio_dev, | ||
831 | struct iio_buffer *buffer, int bit) | ||
832 | { | ||
833 | const unsigned long *mask; | ||
834 | unsigned long *trialmask; | ||
835 | |||
836 | trialmask = kmalloc(sizeof(*trialmask)* | ||
837 | BITS_TO_LONGS(indio_dev->masklength), | ||
838 | GFP_KERNEL); | ||
839 | |||
840 | if (trialmask == NULL) | ||
841 | return -ENOMEM; | ||
842 | if (!indio_dev->masklength) { | ||
843 | WARN_ON("Trying to set scanmask prior to registering buffer\n"); | ||
844 | goto err_invalid_mask; | ||
845 | } | ||
846 | bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength); | ||
847 | set_bit(bit, trialmask); | ||
848 | |||
849 | if (!iio_validate_scan_mask(indio_dev, trialmask)) | ||
850 | goto err_invalid_mask; | ||
851 | |||
852 | if (indio_dev->available_scan_masks) { | ||
853 | mask = iio_scan_mask_match(indio_dev->available_scan_masks, | ||
854 | indio_dev->masklength, | ||
855 | trialmask); | ||
856 | if (!mask) | ||
857 | goto err_invalid_mask; | ||
858 | } | ||
859 | bitmap_copy(buffer->scan_mask, trialmask, indio_dev->masklength); | ||
860 | |||
861 | kfree(trialmask); | ||
862 | |||
863 | return 0; | ||
864 | |||
865 | err_invalid_mask: | ||
866 | kfree(trialmask); | ||
867 | return -EINVAL; | ||
868 | } | ||
869 | EXPORT_SYMBOL_GPL(iio_scan_mask_set); | ||
870 | |||
871 | int iio_scan_mask_query(struct iio_dev *indio_dev, | 870 | int iio_scan_mask_query(struct iio_dev *indio_dev, |
872 | struct iio_buffer *buffer, int bit) | 871 | struct iio_buffer *buffer, int bit) |
873 | { | 872 | { |
diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index 519392763393..8c8ce611949c 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h | |||
@@ -117,15 +117,6 @@ int iio_scan_mask_query(struct iio_dev *indio_dev, | |||
117 | struct iio_buffer *buffer, int bit); | 117 | struct iio_buffer *buffer, int bit); |
118 | 118 | ||
119 | /** | 119 | /** |
120 | * iio_scan_mask_set() - set particular bit in the scan mask | ||
121 | * @indio_dev IIO device structure | ||
122 | * @buffer: the buffer whose scan mask we are interested in | ||
123 | * @bit: the bit to be set. | ||
124 | **/ | ||
125 | int iio_scan_mask_set(struct iio_dev *indio_dev, | ||
126 | struct iio_buffer *buffer, int bit); | ||
127 | |||
128 | /** | ||
129 | * iio_push_to_buffers() - push to a registered buffer. | 120 | * iio_push_to_buffers() - push to a registered buffer. |
130 | * @indio_dev: iio_dev structure for device. | 121 | * @indio_dev: iio_dev structure for device. |
131 | * @data: Full scan. | 122 | * @data: Full scan. |