Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpio: pcie-idio-24: utilize for_each_set_clump8 macro

Replace verbose implementation in get_multiple/set_multiple callbacks
with for_each_set_clump8 macro to simplify code and improve clarity.

Link: http://lkml.kernel.org/r/d5d22fa9809dcf8330f4381dbe7e7ca37990e79f.1570641097.git.vilhelm.gray@gmail.com
Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Lukas Wunner <lukas@wunner.de>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Mathias Duckeck <m.duckeck@kunbus.de>
Cc: Morten Hein Tiljeset <morten.tiljeset@prevas.dk>
Cc: Phil Reid <preid@electromag.com.au>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Sean Nyekjaer <sean.nyekjaer@prevas.dk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

William Breathitt Gray and committed by
Linus Torvalds
c586aa8f 2dc7c3c1

+39 -68
+39 -68
drivers/gpio/gpio-pcie-idio-24.c
··· 201 201 unsigned long *mask, unsigned long *bits) 202 202 { 203 203 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip); 204 - size_t i; 205 - const unsigned int gpio_reg_size = 8; 206 - unsigned int bits_offset; 207 - size_t word_index; 208 - unsigned int word_offset; 209 - unsigned long word_mask; 210 - const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0); 211 - unsigned long port_state; 204 + unsigned long offset; 205 + unsigned long gpio_mask; 212 206 void __iomem *ports[] = { 213 207 &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15, 214 208 &idio24gpio->reg->out16_23, &idio24gpio->reg->in0_7, 215 209 &idio24gpio->reg->in8_15, &idio24gpio->reg->in16_23, 216 210 }; 211 + size_t index; 212 + unsigned long port_state; 217 213 const unsigned long out_mode_mask = BIT(1); 218 214 219 215 /* clear bits array to a clean slate */ 220 216 bitmap_zero(bits, chip->ngpio); 221 217 222 - /* get bits are evaluated a gpio port register at a time */ 223 - for (i = 0; i < ARRAY_SIZE(ports) + 1; i++) { 224 - /* gpio offset in bits array */ 225 - bits_offset = i * gpio_reg_size; 226 - 227 - /* word index for bits array */ 228 - word_index = BIT_WORD(bits_offset); 229 - 230 - /* gpio offset within current word of bits array */ 231 - word_offset = bits_offset % BITS_PER_LONG; 232 - 233 - /* mask of get bits for current gpio within current word */ 234 - word_mask = mask[word_index] & (port_mask << word_offset); 235 - if (!word_mask) { 236 - /* no get bits in this port so skip to next one */ 237 - continue; 238 - } 218 + for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) { 219 + index = offset / 8; 239 220 240 221 /* read bits from current gpio port (port 6 is TTL GPIO) */ 241 - if (i < 6) 242 - port_state = ioread8(ports[i]); 222 + if (index < 6) 223 + port_state = ioread8(ports[index]); 243 224 else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) 244 225 port_state = ioread8(&idio24gpio->reg->ttl_out0_7); 245 226 else 246 227 port_state = ioread8(&idio24gpio->reg->ttl_in0_7); 247 228 248 - /* store acquired bits at respective bits array offset */ 249 - bits[word_index] |= (port_state << word_offset) & word_mask; 229 + port_state &= gpio_mask; 230 + 231 + bitmap_set_value8(bits, port_state, offset); 250 232 } 251 233 252 234 return 0; ··· 279 297 unsigned long *mask, unsigned long *bits) 280 298 { 281 299 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip); 282 - size_t i; 283 - unsigned long bits_offset; 300 + unsigned long offset; 284 301 unsigned long gpio_mask; 285 - const unsigned int gpio_reg_size = 8; 286 - const unsigned long port_mask = GENMASK(gpio_reg_size, 0); 287 - unsigned long flags; 288 - unsigned int out_state; 289 302 void __iomem *ports[] = { 290 303 &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15, 291 304 &idio24gpio->reg->out16_23 292 305 }; 306 + size_t index; 307 + unsigned long bitmask; 308 + unsigned long flags; 309 + unsigned long out_state; 293 310 const unsigned long out_mode_mask = BIT(1); 294 - const unsigned int ttl_offset = 48; 295 - const size_t ttl_i = BIT_WORD(ttl_offset); 296 - const unsigned int word_offset = ttl_offset % BITS_PER_LONG; 297 - const unsigned long ttl_mask = (mask[ttl_i] >> word_offset) & port_mask; 298 - const unsigned long ttl_bits = (bits[ttl_i] >> word_offset) & ttl_mask; 299 311 300 - /* set bits are processed a gpio port register at a time */ 301 - for (i = 0; i < ARRAY_SIZE(ports); i++) { 302 - /* gpio offset in bits array */ 303 - bits_offset = i * gpio_reg_size; 312 + for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) { 313 + index = offset / 8; 304 314 305 - /* check if any set bits for current port */ 306 - gpio_mask = (*mask >> bits_offset) & port_mask; 307 - if (!gpio_mask) { 308 - /* no set bits for this port so move on to next port */ 309 - continue; 310 - } 315 + bitmask = bitmap_get_value8(bits, offset) & gpio_mask; 311 316 312 317 raw_spin_lock_irqsave(&idio24gpio->lock, flags); 313 318 314 - /* process output lines */ 315 - out_state = ioread8(ports[i]) & ~gpio_mask; 316 - out_state |= (*bits >> bits_offset) & gpio_mask; 317 - iowrite8(out_state, ports[i]); 319 + /* read bits from current gpio port (port 6 is TTL GPIO) */ 320 + if (index < 6) { 321 + out_state = ioread8(ports[index]); 322 + } else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) { 323 + out_state = ioread8(&idio24gpio->reg->ttl_out0_7); 324 + } else { 325 + /* skip TTL GPIO if set for input */ 326 + raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); 327 + continue; 328 + } 329 + 330 + /* set requested bit states */ 331 + out_state &= ~gpio_mask; 332 + out_state |= bitmask; 333 + 334 + /* write bits for current gpio port (port 6 is TTL GPIO) */ 335 + if (index < 6) 336 + iowrite8(out_state, ports[index]); 337 + else 338 + iowrite8(out_state, &idio24gpio->reg->ttl_out0_7); 318 339 319 340 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); 320 341 } 321 - 322 - /* check if setting TTL lines and if they are in output mode */ 323 - if (!ttl_mask || !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask)) 324 - return; 325 - 326 - /* handle TTL output */ 327 - raw_spin_lock_irqsave(&idio24gpio->lock, flags); 328 - 329 - /* process output lines */ 330 - out_state = ioread8(&idio24gpio->reg->ttl_out0_7) & ~ttl_mask; 331 - out_state |= ttl_bits; 332 - iowrite8(out_state, &idio24gpio->reg->ttl_out0_7); 333 - 334 - raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); 335 342 } 336 343 337 344 static void idio_24_irq_ack(struct irq_data *data)