.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * gpio-max3191x.c - GPIO driver for Maxim MAX3191x industrial serializer |
---|
3 | 4 | * |
---|
.. | .. |
---|
27 | 28 | * https://datasheets.maximintegrated.com/en/ds/MAX31912.pdf |
---|
28 | 29 | * https://datasheets.maximintegrated.com/en/ds/MAX31913.pdf |
---|
29 | 30 | * https://datasheets.maximintegrated.com/en/ds/MAX31953-MAX31963.pdf |
---|
30 | | - * |
---|
31 | | - * This program is free software; you can redistribute it and/or modify |
---|
32 | | - * it under the terms of the GNU General Public License (version 2) as |
---|
33 | | - * published by the Free Software Foundation. |
---|
34 | 31 | */ |
---|
35 | 32 | |
---|
36 | 33 | #include <linux/bitmap.h> |
---|
| 34 | +#include <linux/bitops.h> |
---|
37 | 35 | #include <linux/crc8.h> |
---|
38 | 36 | #include <linux/gpio/consumer.h> |
---|
39 | 37 | #include <linux/gpio/driver.h> |
---|
.. | .. |
---|
97 | 95 | |
---|
98 | 96 | static int max3191x_get_direction(struct gpio_chip *gpio, unsigned int offset) |
---|
99 | 97 | { |
---|
100 | | - return 1; /* always in */ |
---|
| 98 | + return GPIO_LINE_DIRECTION_IN; /* always in */ |
---|
101 | 99 | } |
---|
102 | 100 | |
---|
103 | 101 | static int max3191x_direction_input(struct gpio_chip *gpio, unsigned int offset) |
---|
.. | .. |
---|
235 | 233 | unsigned long *bits) |
---|
236 | 234 | { |
---|
237 | 235 | struct max3191x_chip *max3191x = gpiochip_get_data(gpio); |
---|
238 | | - int ret, bit = 0, wordlen = max3191x_wordlen(max3191x); |
---|
| 236 | + const unsigned int wordlen = max3191x_wordlen(max3191x); |
---|
| 237 | + int ret; |
---|
| 238 | + unsigned long bit; |
---|
| 239 | + unsigned long gpio_mask; |
---|
| 240 | + unsigned long in; |
---|
239 | 241 | |
---|
240 | 242 | mutex_lock(&max3191x->lock); |
---|
241 | 243 | ret = max3191x_readout_locked(max3191x); |
---|
242 | 244 | if (ret) |
---|
243 | 245 | goto out_unlock; |
---|
244 | 246 | |
---|
245 | | - while ((bit = find_next_bit(mask, gpio->ngpio, bit)) != gpio->ngpio) { |
---|
| 247 | + bitmap_zero(bits, gpio->ngpio); |
---|
| 248 | + for_each_set_clump8(bit, gpio_mask, mask, gpio->ngpio) { |
---|
246 | 249 | unsigned int chipnum = bit / MAX3191X_NGPIO; |
---|
247 | | - unsigned long in, shift, index; |
---|
248 | 250 | |
---|
249 | 251 | if (max3191x_chip_is_faulting(max3191x, chipnum)) { |
---|
250 | 252 | ret = -EIO; |
---|
.. | .. |
---|
252 | 254 | } |
---|
253 | 255 | |
---|
254 | 256 | in = ((u8 *)max3191x->xfer.rx_buf)[chipnum * wordlen]; |
---|
255 | | - shift = round_down(bit % BITS_PER_LONG, MAX3191X_NGPIO); |
---|
256 | | - index = bit / BITS_PER_LONG; |
---|
257 | | - bits[index] &= ~(mask[index] & (0xff << shift)); |
---|
258 | | - bits[index] |= mask[index] & (in << shift); /* copy bits */ |
---|
259 | | - |
---|
260 | | - bit = (chipnum + 1) * MAX3191X_NGPIO; /* go to next chip */ |
---|
| 257 | + in &= gpio_mask; |
---|
| 258 | + bitmap_set_value8(bits, in, bit); |
---|
261 | 259 | } |
---|
262 | 260 | |
---|
263 | 261 | out_unlock: |
---|
.. | .. |
---|
313 | 311 | |
---|
314 | 312 | static void gpiod_set_array_single_value_cansleep(unsigned int ndescs, |
---|
315 | 313 | struct gpio_desc **desc, |
---|
| 314 | + struct gpio_array *info, |
---|
316 | 315 | int value) |
---|
317 | 316 | { |
---|
318 | | - int i, *values; |
---|
| 317 | + unsigned long *values; |
---|
319 | 318 | |
---|
320 | | - values = kmalloc_array(ndescs, sizeof(*values), GFP_KERNEL); |
---|
| 319 | + values = bitmap_alloc(ndescs, GFP_KERNEL); |
---|
321 | 320 | if (!values) |
---|
322 | 321 | return; |
---|
323 | 322 | |
---|
324 | | - for (i = 0; i < ndescs; i++) |
---|
325 | | - values[i] = value; |
---|
| 323 | + if (value) |
---|
| 324 | + bitmap_fill(values, ndescs); |
---|
| 325 | + else |
---|
| 326 | + bitmap_zero(values, ndescs); |
---|
326 | 327 | |
---|
327 | | - gpiod_set_array_value_cansleep(ndescs, desc, values); |
---|
| 328 | + gpiod_set_array_value_cansleep(ndescs, desc, info, values); |
---|
328 | 329 | kfree(values); |
---|
329 | 330 | } |
---|
330 | 331 | |
---|
.. | .. |
---|
397 | 398 | if (max3191x->modesel_pins) |
---|
398 | 399 | gpiod_set_array_single_value_cansleep( |
---|
399 | 400 | max3191x->modesel_pins->ndescs, |
---|
400 | | - max3191x->modesel_pins->desc, max3191x->mode); |
---|
| 401 | + max3191x->modesel_pins->desc, |
---|
| 402 | + max3191x->modesel_pins->info, max3191x->mode); |
---|
401 | 403 | |
---|
402 | 404 | max3191x->ignore_uv = device_property_read_bool(dev, |
---|
403 | 405 | "maxim,ignore-undervoltage"); |
---|