Lines Matching +full:lock +full:- +full:offset
42 * struct ws16c48_gpio - GPIO device private data structure
46 * @lock: synchronization lock to prevent I/O race conditions
55 raw_spinlock_t lock; member
61 static int ws16c48_gpio_get_direction(struct gpio_chip *chip, unsigned offset) in ws16c48_gpio_get_direction() argument
64 const unsigned port = offset / 8; in ws16c48_gpio_get_direction()
65 const unsigned mask = BIT(offset % 8); in ws16c48_gpio_get_direction()
67 return !!(ws16c48gpio->io_state[port] & mask); in ws16c48_gpio_get_direction()
70 static int ws16c48_gpio_direction_input(struct gpio_chip *chip, unsigned offset) in ws16c48_gpio_direction_input() argument
73 const unsigned port = offset / 8; in ws16c48_gpio_direction_input()
74 const unsigned mask = BIT(offset % 8); in ws16c48_gpio_direction_input()
77 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_gpio_direction_input()
79 ws16c48gpio->io_state[port] |= mask; in ws16c48_gpio_direction_input()
80 ws16c48gpio->out_state[port] &= ~mask; in ws16c48_gpio_direction_input()
81 outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); in ws16c48_gpio_direction_input()
83 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_direction_input()
89 unsigned offset, int value) in ws16c48_gpio_direction_output() argument
92 const unsigned port = offset / 8; in ws16c48_gpio_direction_output()
93 const unsigned mask = BIT(offset % 8); in ws16c48_gpio_direction_output()
96 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_gpio_direction_output()
98 ws16c48gpio->io_state[port] &= ~mask; in ws16c48_gpio_direction_output()
100 ws16c48gpio->out_state[port] |= mask; in ws16c48_gpio_direction_output()
102 ws16c48gpio->out_state[port] &= ~mask; in ws16c48_gpio_direction_output()
103 outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); in ws16c48_gpio_direction_output()
105 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_direction_output()
110 static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset) in ws16c48_gpio_get() argument
113 const unsigned port = offset / 8; in ws16c48_gpio_get()
114 const unsigned mask = BIT(offset % 8); in ws16c48_gpio_get()
118 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_gpio_get()
121 if (!(ws16c48gpio->io_state[port] & mask)) { in ws16c48_gpio_get()
122 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_get()
123 return -EINVAL; in ws16c48_gpio_get()
126 port_state = inb(ws16c48gpio->base + port); in ws16c48_gpio_get()
128 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_get()
139 const size_t num_ports = chip->ngpio / gpio_reg_size; in ws16c48_gpio_get_multiple()
144 const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0); in ws16c48_gpio_get_multiple()
148 bitmap_zero(bits, chip->ngpio); in ws16c48_gpio_get_multiple()
152 /* gpio offset in bits array */ in ws16c48_gpio_get_multiple()
158 /* gpio offset within current word of bits array */ in ws16c48_gpio_get_multiple()
169 port_state = inb(ws16c48gpio->base + i); in ws16c48_gpio_get_multiple()
171 /* store acquired bits at respective bits array offset */ in ws16c48_gpio_get_multiple()
178 static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value) in ws16c48_gpio_set() argument
181 const unsigned port = offset / 8; in ws16c48_gpio_set()
182 const unsigned mask = BIT(offset % 8); in ws16c48_gpio_set()
185 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_gpio_set()
188 if (ws16c48gpio->io_state[port] & mask) { in ws16c48_gpio_set()
189 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_set()
194 ws16c48gpio->out_state[port] |= mask; in ws16c48_gpio_set()
196 ws16c48gpio->out_state[port] &= ~mask; in ws16c48_gpio_set()
197 outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); in ws16c48_gpio_set()
199 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_set()
214 for (i = 0; i < chip->ngpio; i += gpio_reg_size) { in ws16c48_gpio_set_multiple()
217 i = (BIT_WORD(i) + 1) * BITS_PER_LONG - gpio_reg_size; in ws16c48_gpio_set_multiple()
224 iomask = mask[BIT_WORD(i)] & ~ws16c48gpio->io_state[port]; in ws16c48_gpio_set_multiple()
227 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_gpio_set_multiple()
230 ws16c48gpio->out_state[port] &= ~iomask; in ws16c48_gpio_set_multiple()
231 ws16c48gpio->out_state[port] |= bitmask; in ws16c48_gpio_set_multiple()
232 outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); in ws16c48_gpio_set_multiple()
234 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_gpio_set_multiple()
246 const unsigned long offset = irqd_to_hwirq(data); in ws16c48_irq_ack() local
247 const unsigned port = offset / 8; in ws16c48_irq_ack()
248 const unsigned mask = BIT(offset % 8); in ws16c48_irq_ack()
256 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_irq_ack()
258 port_state = ws16c48gpio->irq_mask >> (8*port); in ws16c48_irq_ack()
260 outb(0x80, ws16c48gpio->base + 7); in ws16c48_irq_ack()
261 outb(port_state & ~mask, ws16c48gpio->base + 8 + port); in ws16c48_irq_ack()
262 outb(port_state | mask, ws16c48gpio->base + 8 + port); in ws16c48_irq_ack()
263 outb(0xC0, ws16c48gpio->base + 7); in ws16c48_irq_ack()
265 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_irq_ack()
272 const unsigned long offset = irqd_to_hwirq(data); in ws16c48_irq_mask() local
273 const unsigned long mask = BIT(offset); in ws16c48_irq_mask()
274 const unsigned port = offset / 8; in ws16c48_irq_mask()
281 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_irq_mask()
283 ws16c48gpio->irq_mask &= ~mask; in ws16c48_irq_mask()
285 outb(0x80, ws16c48gpio->base + 7); in ws16c48_irq_mask()
286 outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port); in ws16c48_irq_mask()
287 outb(0xC0, ws16c48gpio->base + 7); in ws16c48_irq_mask()
289 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_irq_mask()
296 const unsigned long offset = irqd_to_hwirq(data); in ws16c48_irq_unmask() local
297 const unsigned long mask = BIT(offset); in ws16c48_irq_unmask()
298 const unsigned port = offset / 8; in ws16c48_irq_unmask()
305 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_irq_unmask()
307 ws16c48gpio->irq_mask |= mask; in ws16c48_irq_unmask()
309 outb(0x80, ws16c48gpio->base + 7); in ws16c48_irq_unmask()
310 outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port); in ws16c48_irq_unmask()
311 outb(0xC0, ws16c48gpio->base + 7); in ws16c48_irq_unmask()
313 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_irq_unmask()
320 const unsigned long offset = irqd_to_hwirq(data); in ws16c48_irq_set_type() local
321 const unsigned long mask = BIT(offset); in ws16c48_irq_set_type()
322 const unsigned port = offset / 8; in ws16c48_irq_set_type()
327 return -EINVAL; in ws16c48_irq_set_type()
329 raw_spin_lock_irqsave(&ws16c48gpio->lock, flags); in ws16c48_irq_set_type()
335 ws16c48gpio->flow_mask |= mask; in ws16c48_irq_set_type()
338 ws16c48gpio->flow_mask &= ~mask; in ws16c48_irq_set_type()
341 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_irq_set_type()
342 return -EINVAL; in ws16c48_irq_set_type()
345 outb(0x40, ws16c48gpio->base + 7); in ws16c48_irq_set_type()
346 outb(ws16c48gpio->flow_mask >> (8*port), ws16c48gpio->base + 8 + port); in ws16c48_irq_set_type()
347 outb(0xC0, ws16c48gpio->base + 7); in ws16c48_irq_set_type()
349 raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags); in ws16c48_irq_set_type()
365 struct gpio_chip *const chip = &ws16c48gpio->chip; in ws16c48_irq_handler()
371 int_pending = inb(ws16c48gpio->base + 6) & 0x7; in ws16c48_irq_handler()
378 int_id = inb(ws16c48gpio->base + 8 + port); in ws16c48_irq_handler()
381 chip->irq.domain, gpio + 8*port)); in ws16c48_irq_handler()
384 int_pending = inb(ws16c48gpio->base + 6) & 0x7; in ws16c48_irq_handler()
414 return -ENOMEM; in ws16c48_probe()
417 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", in ws16c48_probe()
419 return -EBUSY; in ws16c48_probe()
422 ws16c48gpio->chip.label = name; in ws16c48_probe()
423 ws16c48gpio->chip.parent = dev; in ws16c48_probe()
424 ws16c48gpio->chip.owner = THIS_MODULE; in ws16c48_probe()
425 ws16c48gpio->chip.base = -1; in ws16c48_probe()
426 ws16c48gpio->chip.ngpio = WS16C48_NGPIO; in ws16c48_probe()
427 ws16c48gpio->chip.names = ws16c48_names; in ws16c48_probe()
428 ws16c48gpio->chip.get_direction = ws16c48_gpio_get_direction; in ws16c48_probe()
429 ws16c48gpio->chip.direction_input = ws16c48_gpio_direction_input; in ws16c48_probe()
430 ws16c48gpio->chip.direction_output = ws16c48_gpio_direction_output; in ws16c48_probe()
431 ws16c48gpio->chip.get = ws16c48_gpio_get; in ws16c48_probe()
432 ws16c48gpio->chip.get_multiple = ws16c48_gpio_get_multiple; in ws16c48_probe()
433 ws16c48gpio->chip.set = ws16c48_gpio_set; in ws16c48_probe()
434 ws16c48gpio->chip.set_multiple = ws16c48_gpio_set_multiple; in ws16c48_probe()
435 ws16c48gpio->base = base[id]; in ws16c48_probe()
437 raw_spin_lock_init(&ws16c48gpio->lock); in ws16c48_probe()
439 err = devm_gpiochip_add_data(dev, &ws16c48gpio->chip, ws16c48gpio); in ws16c48_probe()
452 err = gpiochip_irqchip_add(&ws16c48gpio->chip, &ws16c48_irqchip, 0, in ws16c48_probe()