Lines Matching +full:lock +full:- +full:offset
1 // SPDX-License-Identifier: GPL-2.0-only
3 * GPIO driver for the ACCES PCI-IDIO-16
20 * struct idio_16_gpio_reg - GPIO device registers structure
21 * @out0_7: Read: FET Drive Outputs 0-7
22 * Write: FET Drive Outputs 0-7
23 * @in0_7: Read: Isolated Inputs 0-7
27 * @filter_ctl: Read: Activate Input Filters 0-15
28 * Write: Deactivate Input Filters 0-15
29 * @out8_15: Read: FET Drive Outputs 8-15
30 * Write: FET Drive Outputs 8-15
31 * @in8_15: Read: Isolated Inputs 8-15
47 * struct idio_16_gpio - GPIO device private data structure
49 * @lock: synchronization lock to prevent I/O race conditions
50 * @reg: I/O address offset for the GPIO device registers
55 raw_spinlock_t lock; member
61 unsigned int offset) in idio_16_gpio_get_direction() argument
63 if (offset > 15) in idio_16_gpio_get_direction()
70 unsigned int offset) in idio_16_gpio_direction_input() argument
76 unsigned int offset, int value) in idio_16_gpio_direction_output() argument
78 chip->set(chip, offset, value); in idio_16_gpio_direction_output()
82 static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset) in idio_16_gpio_get() argument
85 unsigned long mask = BIT(offset); in idio_16_gpio_get()
87 if (offset < 8) in idio_16_gpio_get()
88 return !!(ioread8(&idio16gpio->reg->out0_7) & mask); in idio_16_gpio_get()
90 if (offset < 16) in idio_16_gpio_get()
91 return !!(ioread8(&idio16gpio->reg->out8_15) & (mask >> 8)); in idio_16_gpio_get()
93 if (offset < 24) in idio_16_gpio_get()
94 return !!(ioread8(&idio16gpio->reg->in0_7) & (mask >> 16)); in idio_16_gpio_get()
96 return !!(ioread8(&idio16gpio->reg->in8_15) & (mask >> 24)); in idio_16_gpio_get()
103 unsigned long offset; in idio_16_gpio_get_multiple() local
106 &idio16gpio->reg->out0_7, &idio16gpio->reg->out8_15, in idio_16_gpio_get_multiple()
107 &idio16gpio->reg->in0_7, &idio16gpio->reg->in8_15, in idio_16_gpio_get_multiple()
113 bitmap_zero(bits, chip->ngpio); in idio_16_gpio_get_multiple()
115 for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) { in idio_16_gpio_get_multiple()
116 port_addr = ports[offset / 8]; in idio_16_gpio_get_multiple()
119 bitmap_set_value8(bits, port_state, offset); in idio_16_gpio_get_multiple()
125 static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset, in idio_16_gpio_set() argument
129 unsigned int mask = BIT(offset); in idio_16_gpio_set()
134 if (offset > 15) in idio_16_gpio_set()
137 if (offset > 7) { in idio_16_gpio_set()
139 base = &idio16gpio->reg->out8_15; in idio_16_gpio_set()
141 base = &idio16gpio->reg->out0_7; in idio_16_gpio_set()
143 raw_spin_lock_irqsave(&idio16gpio->lock, flags); in idio_16_gpio_set()
152 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); in idio_16_gpio_set()
159 unsigned long offset; in idio_16_gpio_set_multiple() local
162 &idio16gpio->reg->out0_7, &idio16gpio->reg->out8_15, in idio_16_gpio_set_multiple()
170 for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) { in idio_16_gpio_set_multiple()
171 index = offset / 8; in idio_16_gpio_set_multiple()
174 bitmask = bitmap_get_value8(bits, offset) & gpio_mask; in idio_16_gpio_set_multiple()
176 raw_spin_lock_irqsave(&idio16gpio->lock, flags); in idio_16_gpio_set_multiple()
182 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); in idio_16_gpio_set_multiple()
197 idio16gpio->irq_mask &= ~mask; in idio_16_irq_mask()
199 if (!idio16gpio->irq_mask) { in idio_16_irq_mask()
200 raw_spin_lock_irqsave(&idio16gpio->lock, flags); in idio_16_irq_mask()
202 iowrite8(0, &idio16gpio->reg->irq_ctl); in idio_16_irq_mask()
204 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); in idio_16_irq_mask()
213 const unsigned long prev_irq_mask = idio16gpio->irq_mask; in idio_16_irq_unmask()
216 idio16gpio->irq_mask |= mask; in idio_16_irq_unmask()
219 raw_spin_lock_irqsave(&idio16gpio->lock, flags); in idio_16_irq_unmask()
221 ioread8(&idio16gpio->reg->irq_ctl); in idio_16_irq_unmask()
223 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); in idio_16_irq_unmask()
229 /* The only valid irq types are none and both-edges */ in idio_16_irq_set_type()
232 return -EINVAL; in idio_16_irq_set_type()
238 .name = "pci-idio-16",
249 struct gpio_chip *const chip = &idio16gpio->chip; in idio_16_irq_handler()
252 raw_spin_lock(&idio16gpio->lock); in idio_16_irq_handler()
254 irq_status = ioread8(&idio16gpio->reg->irq_status); in idio_16_irq_handler()
256 raw_spin_unlock(&idio16gpio->lock); in idio_16_irq_handler()
262 for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio) in idio_16_irq_handler()
263 generic_handle_domain_irq(chip->irq.domain, gpio); in idio_16_irq_handler()
265 raw_spin_lock(&idio16gpio->lock); in idio_16_irq_handler()
268 iowrite8(0, &idio16gpio->reg->in0_7); in idio_16_irq_handler()
270 raw_spin_unlock(&idio16gpio->lock); in idio_16_irq_handler()
288 iowrite8(0, &idio16gpio->reg->irq_ctl); in idio_16_irq_init_hw()
289 iowrite8(0, &idio16gpio->reg->in0_7); in idio_16_irq_init_hw()
296 struct device *const dev = &pdev->dev; in idio_16_probe()
305 return -ENOMEM; in idio_16_probe()
319 idio16gpio->reg = pcim_iomap_table(pdev)[pci_bar_index]; in idio_16_probe()
322 iowrite8(0, &idio16gpio->reg->filter_ctl); in idio_16_probe()
324 idio16gpio->chip.label = name; in idio_16_probe()
325 idio16gpio->chip.parent = dev; in idio_16_probe()
326 idio16gpio->chip.owner = THIS_MODULE; in idio_16_probe()
327 idio16gpio->chip.base = -1; in idio_16_probe()
328 idio16gpio->chip.ngpio = IDIO_16_NGPIO; in idio_16_probe()
329 idio16gpio->chip.names = idio_16_names; in idio_16_probe()
330 idio16gpio->chip.get_direction = idio_16_gpio_get_direction; in idio_16_probe()
331 idio16gpio->chip.direction_input = idio_16_gpio_direction_input; in idio_16_probe()
332 idio16gpio->chip.direction_output = idio_16_gpio_direction_output; in idio_16_probe()
333 idio16gpio->chip.get = idio_16_gpio_get; in idio_16_probe()
334 idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple; in idio_16_probe()
335 idio16gpio->chip.set = idio_16_gpio_set; in idio_16_probe()
336 idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple; in idio_16_probe()
338 girq = &idio16gpio->chip.irq; in idio_16_probe()
339 girq->chip = &idio_16_irqchip; in idio_16_probe()
341 girq->parent_handler = NULL; in idio_16_probe()
342 girq->num_parents = 0; in idio_16_probe()
343 girq->parents = NULL; in idio_16_probe()
344 girq->default_type = IRQ_TYPE_NONE; in idio_16_probe()
345 girq->handler = handle_edge_irq; in idio_16_probe()
346 girq->init_hw = idio_16_irq_init_hw; in idio_16_probe()
348 raw_spin_lock_init(&idio16gpio->lock); in idio_16_probe()
350 err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio); in idio_16_probe()
356 err = devm_request_irq(dev, pdev->irq, idio_16_irq_handler, IRQF_SHARED, in idio_16_probe()
372 .name = "pci-idio-16",
380 MODULE_DESCRIPTION("ACCES PCI-IDIO-16 GPIO driver");