.. | .. |
---|
146 | 146 | |
---|
147 | 147 | /* FET Outputs */ |
---|
148 | 148 | if (offset < 24) |
---|
149 | | - return 0; |
---|
| 149 | + return GPIO_LINE_DIRECTION_OUT; |
---|
150 | 150 | |
---|
151 | 151 | /* Isolated Inputs */ |
---|
152 | 152 | if (offset < 48) |
---|
153 | | - return 1; |
---|
| 153 | + return GPIO_LINE_DIRECTION_IN; |
---|
154 | 154 | |
---|
155 | 155 | /* TTL/CMOS I/O */ |
---|
156 | 156 | /* OUT MODE = 1 when TTL/CMOS Output Mode is set */ |
---|
157 | | - return !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask); |
---|
| 157 | + if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) |
---|
| 158 | + return GPIO_LINE_DIRECTION_OUT; |
---|
| 159 | + |
---|
| 160 | + return GPIO_LINE_DIRECTION_IN; |
---|
158 | 161 | } |
---|
159 | 162 | |
---|
160 | 163 | static int idio_24_gpio_direction_input(struct gpio_chip *chip, |
---|
.. | .. |
---|
240 | 243 | unsigned long *mask, unsigned long *bits) |
---|
241 | 244 | { |
---|
242 | 245 | struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip); |
---|
243 | | - size_t i; |
---|
244 | | - const unsigned int gpio_reg_size = 8; |
---|
245 | | - unsigned int bits_offset; |
---|
246 | | - size_t word_index; |
---|
247 | | - unsigned int word_offset; |
---|
248 | | - unsigned long word_mask; |
---|
249 | | - const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0); |
---|
250 | | - unsigned long port_state; |
---|
| 246 | + unsigned long offset; |
---|
| 247 | + unsigned long gpio_mask; |
---|
251 | 248 | void __iomem *ports[] = { |
---|
252 | 249 | &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15, |
---|
253 | 250 | &idio24gpio->reg->out16_23, &idio24gpio->reg->in0_7, |
---|
254 | 251 | &idio24gpio->reg->in8_15, &idio24gpio->reg->in16_23, |
---|
255 | 252 | }; |
---|
| 253 | + size_t index; |
---|
| 254 | + unsigned long port_state; |
---|
256 | 255 | const unsigned long out_mode_mask = BIT(1); |
---|
257 | 256 | |
---|
258 | 257 | /* clear bits array to a clean slate */ |
---|
259 | 258 | bitmap_zero(bits, chip->ngpio); |
---|
260 | 259 | |
---|
261 | | - /* get bits are evaluated a gpio port register at a time */ |
---|
262 | | - for (i = 0; i < ARRAY_SIZE(ports) + 1; i++) { |
---|
263 | | - /* gpio offset in bits array */ |
---|
264 | | - bits_offset = i * gpio_reg_size; |
---|
265 | | - |
---|
266 | | - /* word index for bits array */ |
---|
267 | | - word_index = BIT_WORD(bits_offset); |
---|
268 | | - |
---|
269 | | - /* gpio offset within current word of bits array */ |
---|
270 | | - word_offset = bits_offset % BITS_PER_LONG; |
---|
271 | | - |
---|
272 | | - /* mask of get bits for current gpio within current word */ |
---|
273 | | - word_mask = mask[word_index] & (port_mask << word_offset); |
---|
274 | | - if (!word_mask) { |
---|
275 | | - /* no get bits in this port so skip to next one */ |
---|
276 | | - continue; |
---|
277 | | - } |
---|
| 260 | + for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) { |
---|
| 261 | + index = offset / 8; |
---|
278 | 262 | |
---|
279 | 263 | /* read bits from current gpio port (port 6 is TTL GPIO) */ |
---|
280 | | - if (i < 6) |
---|
281 | | - port_state = ioread8(ports[i]); |
---|
| 264 | + if (index < 6) |
---|
| 265 | + port_state = ioread8(ports[index]); |
---|
282 | 266 | else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) |
---|
283 | 267 | port_state = ioread8(&idio24gpio->reg->ttl_out0_7); |
---|
284 | 268 | else |
---|
285 | 269 | port_state = ioread8(&idio24gpio->reg->ttl_in0_7); |
---|
286 | 270 | |
---|
287 | | - /* store acquired bits at respective bits array offset */ |
---|
288 | | - bits[word_index] |= port_state << word_offset; |
---|
| 271 | + port_state &= gpio_mask; |
---|
| 272 | + |
---|
| 273 | + bitmap_set_value8(bits, port_state, offset); |
---|
289 | 274 | } |
---|
290 | 275 | |
---|
291 | 276 | return 0; |
---|
.. | .. |
---|
336 | 321 | unsigned long *mask, unsigned long *bits) |
---|
337 | 322 | { |
---|
338 | 323 | struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip); |
---|
339 | | - size_t i; |
---|
340 | | - unsigned long bits_offset; |
---|
| 324 | + unsigned long offset; |
---|
341 | 325 | unsigned long gpio_mask; |
---|
342 | | - const unsigned int gpio_reg_size = 8; |
---|
343 | | - const unsigned long port_mask = GENMASK(gpio_reg_size, 0); |
---|
344 | | - unsigned long flags; |
---|
345 | | - unsigned int out_state; |
---|
346 | 326 | void __iomem *ports[] = { |
---|
347 | 327 | &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15, |
---|
348 | 328 | &idio24gpio->reg->out16_23 |
---|
349 | 329 | }; |
---|
| 330 | + size_t index; |
---|
| 331 | + unsigned long bitmask; |
---|
| 332 | + unsigned long flags; |
---|
| 333 | + unsigned long out_state; |
---|
350 | 334 | const unsigned long out_mode_mask = BIT(1); |
---|
351 | | - const unsigned int ttl_offset = 48; |
---|
352 | | - const size_t ttl_i = BIT_WORD(ttl_offset); |
---|
353 | | - const unsigned int word_offset = ttl_offset % BITS_PER_LONG; |
---|
354 | | - const unsigned long ttl_mask = (mask[ttl_i] >> word_offset) & port_mask; |
---|
355 | | - const unsigned long ttl_bits = (bits[ttl_i] >> word_offset) & ttl_mask; |
---|
356 | 335 | |
---|
357 | | - /* set bits are processed a gpio port register at a time */ |
---|
358 | | - for (i = 0; i < ARRAY_SIZE(ports); i++) { |
---|
359 | | - /* gpio offset in bits array */ |
---|
360 | | - bits_offset = i * gpio_reg_size; |
---|
| 336 | + for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) { |
---|
| 337 | + index = offset / 8; |
---|
361 | 338 | |
---|
362 | | - /* check if any set bits for current port */ |
---|
363 | | - gpio_mask = (*mask >> bits_offset) & port_mask; |
---|
364 | | - if (!gpio_mask) { |
---|
365 | | - /* no set bits for this port so move on to next port */ |
---|
366 | | - continue; |
---|
367 | | - } |
---|
| 339 | + bitmask = bitmap_get_value8(bits, offset) & gpio_mask; |
---|
368 | 340 | |
---|
369 | 341 | raw_spin_lock_irqsave(&idio24gpio->lock, flags); |
---|
370 | 342 | |
---|
371 | | - /* process output lines */ |
---|
372 | | - out_state = ioread8(ports[i]) & ~gpio_mask; |
---|
373 | | - out_state |= (*bits >> bits_offset) & gpio_mask; |
---|
374 | | - iowrite8(out_state, ports[i]); |
---|
| 343 | + /* read bits from current gpio port (port 6 is TTL GPIO) */ |
---|
| 344 | + if (index < 6) { |
---|
| 345 | + out_state = ioread8(ports[index]); |
---|
| 346 | + } else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) { |
---|
| 347 | + out_state = ioread8(&idio24gpio->reg->ttl_out0_7); |
---|
| 348 | + } else { |
---|
| 349 | + /* skip TTL GPIO if set for input */ |
---|
| 350 | + raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); |
---|
| 351 | + continue; |
---|
| 352 | + } |
---|
| 353 | + |
---|
| 354 | + /* set requested bit states */ |
---|
| 355 | + out_state &= ~gpio_mask; |
---|
| 356 | + out_state |= bitmask; |
---|
| 357 | + |
---|
| 358 | + /* write bits for current gpio port (port 6 is TTL GPIO) */ |
---|
| 359 | + if (index < 6) |
---|
| 360 | + iowrite8(out_state, ports[index]); |
---|
| 361 | + else |
---|
| 362 | + iowrite8(out_state, &idio24gpio->reg->ttl_out0_7); |
---|
375 | 363 | |
---|
376 | 364 | raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); |
---|
377 | 365 | } |
---|
378 | | - |
---|
379 | | - /* check if setting TTL lines and if they are in output mode */ |
---|
380 | | - if (!ttl_mask || !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask)) |
---|
381 | | - return; |
---|
382 | | - |
---|
383 | | - /* handle TTL output */ |
---|
384 | | - raw_spin_lock_irqsave(&idio24gpio->lock, flags); |
---|
385 | | - |
---|
386 | | - /* process output lines */ |
---|
387 | | - out_state = ioread8(&idio24gpio->reg->ttl_out0_7) & ~ttl_mask; |
---|
388 | | - out_state |= ttl_bits; |
---|
389 | | - iowrite8(out_state, &idio24gpio->reg->ttl_out0_7); |
---|
390 | | - |
---|
391 | | - raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); |
---|
392 | 366 | } |
---|
393 | 367 | |
---|
394 | 368 | static void idio_24_irq_ack(struct irq_data *data) |
---|
.. | .. |
---|
526 | 500 | const size_t pci_plx_bar_index = 1; |
---|
527 | 501 | const size_t pci_bar_index = 2; |
---|
528 | 502 | const char *const name = pci_name(pdev); |
---|
| 503 | + struct gpio_irq_chip *girq; |
---|
529 | 504 | |
---|
530 | 505 | idio24gpio = devm_kzalloc(dev, sizeof(*idio24gpio), GFP_KERNEL); |
---|
531 | 506 | if (!idio24gpio) |
---|
.. | .. |
---|
560 | 535 | idio24gpio->chip.set = idio_24_gpio_set; |
---|
561 | 536 | idio24gpio->chip.set_multiple = idio_24_gpio_set_multiple; |
---|
562 | 537 | |
---|
| 538 | + girq = &idio24gpio->chip.irq; |
---|
| 539 | + girq->chip = &idio_24_irqchip; |
---|
| 540 | + /* This will let us handle the parent IRQ in the driver */ |
---|
| 541 | + girq->parent_handler = NULL; |
---|
| 542 | + girq->num_parents = 0; |
---|
| 543 | + girq->parents = NULL; |
---|
| 544 | + girq->default_type = IRQ_TYPE_NONE; |
---|
| 545 | + girq->handler = handle_edge_irq; |
---|
| 546 | + |
---|
563 | 547 | raw_spin_lock_init(&idio24gpio->lock); |
---|
564 | 548 | |
---|
565 | 549 | /* Software board reset */ |
---|
.. | .. |
---|
574 | 558 | err = devm_gpiochip_add_data(dev, &idio24gpio->chip, idio24gpio); |
---|
575 | 559 | if (err) { |
---|
576 | 560 | dev_err(dev, "GPIO registering failed (%d)\n", err); |
---|
577 | | - return err; |
---|
578 | | - } |
---|
579 | | - |
---|
580 | | - err = gpiochip_irqchip_add(&idio24gpio->chip, &idio_24_irqchip, 0, |
---|
581 | | - handle_edge_irq, IRQ_TYPE_NONE); |
---|
582 | | - if (err) { |
---|
583 | | - dev_err(dev, "Could not add irqchip (%d)\n", err); |
---|
584 | 561 | return err; |
---|
585 | 562 | } |
---|
586 | 563 | |
---|