Lines Matching +full:lock +full:- +full:offset

1 // SPDX-License-Identifier: GPL-2.0-only
3 * GPIO driver for the ACCES 104-IDIO-16 family
6 * This driver supports the following ACCES devices: 104-IDIO-16,
7 * 104-IDIO-16E, 104-IDO-16, 104-IDIO-8, 104-IDIO-8E, and 104-IDO-8.
30 MODULE_PARM_DESC(base, "ACCES 104-IDIO-16 base addresses");
35 MODULE_PARM_DESC(irq, "ACCES 104-IDIO-16 interrupt line numbers");
38 * struct idio_16_reg - device registers structure
40 * Write: FET Drive Outputs 0-7
41 * @in0_7: Read: Isolated Inputs 0-7
47 * Write: FET Drive Outputs 8-15
48 * @in8_15: Read: Isolated Inputs 8-15
61 * struct idio_16_gpio - GPIO device private data structure
63 * @lock: synchronization lock to prevent I/O race conditions
65 * @reg: I/O address offset for the device registers
70 raw_spinlock_t lock; member
77 unsigned int offset) in idio_16_gpio_get_direction() argument
79 if (offset > 15) in idio_16_gpio_get_direction()
86 unsigned int offset) in idio_16_gpio_direction_input() argument
92 unsigned int offset, int value) in idio_16_gpio_direction_output() argument
94 chip->set(chip, offset, value); in idio_16_gpio_direction_output()
98 static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset) in idio_16_gpio_get() argument
101 const unsigned int mask = BIT(offset-16); in idio_16_gpio_get()
103 if (offset < 16) in idio_16_gpio_get()
104 return -EINVAL; in idio_16_gpio_get()
106 if (offset < 24) in idio_16_gpio_get()
107 return !!(ioread8(&idio16gpio->reg->in0_7) & mask); in idio_16_gpio_get()
109 return !!(ioread8(&idio16gpio->reg->in8_15) & (mask>>8)); in idio_16_gpio_get()
119 *bits |= (unsigned long)ioread8(&idio16gpio->reg->in0_7) << 16; in idio_16_gpio_get_multiple()
121 *bits |= (unsigned long)ioread8(&idio16gpio->reg->in8_15) << 24; in idio_16_gpio_get_multiple()
126 static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset, in idio_16_gpio_set() argument
130 const unsigned int mask = BIT(offset); in idio_16_gpio_set()
133 if (offset > 15) in idio_16_gpio_set()
136 raw_spin_lock_irqsave(&idio16gpio->lock, flags); in idio_16_gpio_set()
139 idio16gpio->out_state |= mask; in idio_16_gpio_set()
141 idio16gpio->out_state &= ~mask; in idio_16_gpio_set()
143 if (offset > 7) in idio_16_gpio_set()
144 iowrite8(idio16gpio->out_state >> 8, &idio16gpio->reg->out8_15); in idio_16_gpio_set()
146 iowrite8(idio16gpio->out_state, &idio16gpio->reg->out0_7); in idio_16_gpio_set()
148 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); in idio_16_gpio_set()
157 raw_spin_lock_irqsave(&idio16gpio->lock, flags); in idio_16_gpio_set_multiple()
159 idio16gpio->out_state &= ~*mask; in idio_16_gpio_set_multiple()
160 idio16gpio->out_state |= *mask & *bits; in idio_16_gpio_set_multiple()
163 iowrite8(idio16gpio->out_state, &idio16gpio->reg->out0_7); in idio_16_gpio_set_multiple()
165 iowrite8(idio16gpio->out_state >> 8, &idio16gpio->reg->out8_15); in idio_16_gpio_set_multiple()
167 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); in idio_16_gpio_set_multiple()
178 const unsigned long offset = irqd_to_hwirq(data); in idio_16_irq_mask() local
181 idio16gpio->irq_mask &= ~BIT(offset); in idio_16_irq_mask()
182 gpiochip_disable_irq(chip, offset); in idio_16_irq_mask()
184 if (!idio16gpio->irq_mask) { in idio_16_irq_mask()
185 raw_spin_lock_irqsave(&idio16gpio->lock, flags); in idio_16_irq_mask()
187 iowrite8(0, &idio16gpio->reg->irq_ctl); in idio_16_irq_mask()
189 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); in idio_16_irq_mask()
197 const unsigned long offset = irqd_to_hwirq(data); in idio_16_irq_unmask() local
198 const unsigned long prev_irq_mask = idio16gpio->irq_mask; in idio_16_irq_unmask()
201 gpiochip_enable_irq(chip, offset); in idio_16_irq_unmask()
202 idio16gpio->irq_mask |= BIT(offset); in idio_16_irq_unmask()
205 raw_spin_lock_irqsave(&idio16gpio->lock, flags); in idio_16_irq_unmask()
207 ioread8(&idio16gpio->reg->irq_ctl); in idio_16_irq_unmask()
209 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); in idio_16_irq_unmask()
215 /* The only valid irq types are none and both-edges */ in idio_16_irq_set_type()
218 return -EINVAL; in idio_16_irq_set_type()
224 .name = "104-idio-16",
236 struct gpio_chip *const chip = &idio16gpio->chip; in idio_16_irq_handler()
239 for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio) in idio_16_irq_handler()
240 generic_handle_domain_irq(chip->irq.domain, gpio); in idio_16_irq_handler()
242 raw_spin_lock(&idio16gpio->lock); in idio_16_irq_handler()
244 iowrite8(0, &idio16gpio->reg->in0_7); in idio_16_irq_handler()
246 raw_spin_unlock(&idio16gpio->lock); in idio_16_irq_handler()
264 iowrite8(0, &idio16gpio->reg->irq_ctl); in idio_16_irq_init_hw()
265 iowrite8(0, &idio16gpio->reg->in0_7); in idio_16_irq_init_hw()
279 return -ENOMEM; in idio_16_probe()
282 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", in idio_16_probe()
284 return -EBUSY; in idio_16_probe()
287 idio16gpio->reg = devm_ioport_map(dev, base[id], IDIO_16_EXTENT); in idio_16_probe()
288 if (!idio16gpio->reg) in idio_16_probe()
289 return -ENOMEM; in idio_16_probe()
291 idio16gpio->chip.label = name; in idio_16_probe()
292 idio16gpio->chip.parent = dev; in idio_16_probe()
293 idio16gpio->chip.owner = THIS_MODULE; in idio_16_probe()
294 idio16gpio->chip.base = -1; in idio_16_probe()
295 idio16gpio->chip.ngpio = IDIO_16_NGPIO; in idio_16_probe()
296 idio16gpio->chip.names = idio_16_names; in idio_16_probe()
297 idio16gpio->chip.get_direction = idio_16_gpio_get_direction; in idio_16_probe()
298 idio16gpio->chip.direction_input = idio_16_gpio_direction_input; in idio_16_probe()
299 idio16gpio->chip.direction_output = idio_16_gpio_direction_output; in idio_16_probe()
300 idio16gpio->chip.get = idio_16_gpio_get; in idio_16_probe()
301 idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple; in idio_16_probe()
302 idio16gpio->chip.set = idio_16_gpio_set; in idio_16_probe()
303 idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple; in idio_16_probe()
304 idio16gpio->out_state = 0xFFFF; in idio_16_probe()
306 girq = &idio16gpio->chip.irq; in idio_16_probe()
309 girq->parent_handler = NULL; in idio_16_probe()
310 girq->num_parents = 0; in idio_16_probe()
311 girq->parents = NULL; in idio_16_probe()
312 girq->default_type = IRQ_TYPE_NONE; in idio_16_probe()
313 girq->handler = handle_edge_irq; in idio_16_probe()
314 girq->init_hw = idio_16_irq_init_hw; in idio_16_probe()
316 raw_spin_lock_init(&idio16gpio->lock); in idio_16_probe()
318 err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio); in idio_16_probe()
337 .name = "104-idio-16"
344 MODULE_DESCRIPTION("ACCES 104-IDIO-16 GPIO driver");