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

1 // SPDX-License-Identifier: GPL-2.0-only
3 * GPIO driver for the Diamond Systems GPIO-MM
6 * This driver supports the following Diamond Systems devices: GPIO-MM and
7 * GPIO-MM-12.
28 MODULE_PARM_DESC(base, "Diamond Systems GPIO-MM base addresses");
31 * struct gpiomm_gpio - GPIO device private data structure
36 * @lock: synchronization lock to prevent I/O race conditions
44 spinlock_t lock; member
49 unsigned int offset) in gpiomm_gpio_get_direction() argument
52 const unsigned int port = offset / 8; in gpiomm_gpio_get_direction()
53 const unsigned int mask = BIT(offset % 8); in gpiomm_gpio_get_direction()
55 if (gpiommgpio->io_state[port] & mask) in gpiomm_gpio_get_direction()
62 unsigned int offset) in gpiomm_gpio_direction_input() argument
65 const unsigned int io_port = offset / 8; in gpiomm_gpio_direction_input()
67 const unsigned int control_addr = gpiommgpio->base + 3 + control_port*4; in gpiomm_gpio_direction_input()
71 spin_lock_irqsave(&gpiommgpio->lock, flags); in gpiomm_gpio_direction_input()
76 if (offset % 8 > 3) { in gpiomm_gpio_direction_input()
77 gpiommgpio->io_state[io_port] |= 0xF0; in gpiomm_gpio_direction_input()
78 gpiommgpio->control[control_port] |= BIT(3); in gpiomm_gpio_direction_input()
80 gpiommgpio->io_state[io_port] |= 0x0F; in gpiomm_gpio_direction_input()
81 gpiommgpio->control[control_port] |= BIT(0); in gpiomm_gpio_direction_input()
84 gpiommgpio->io_state[io_port] |= 0xFF; in gpiomm_gpio_direction_input()
86 gpiommgpio->control[control_port] |= BIT(4); in gpiomm_gpio_direction_input()
88 gpiommgpio->control[control_port] |= BIT(1); in gpiomm_gpio_direction_input()
91 control = BIT(7) | gpiommgpio->control[control_port]; in gpiomm_gpio_direction_input()
94 spin_unlock_irqrestore(&gpiommgpio->lock, flags); in gpiomm_gpio_direction_input()
100 unsigned int offset, int value) in gpiomm_gpio_direction_output() argument
103 const unsigned int io_port = offset / 8; in gpiomm_gpio_direction_output()
105 const unsigned int mask = BIT(offset % 8); in gpiomm_gpio_direction_output()
106 const unsigned int control_addr = gpiommgpio->base + 3 + control_port*4; in gpiomm_gpio_direction_output()
111 spin_lock_irqsave(&gpiommgpio->lock, flags); in gpiomm_gpio_direction_output()
116 if (offset % 8 > 3) { in gpiomm_gpio_direction_output()
117 gpiommgpio->io_state[io_port] &= 0x0F; in gpiomm_gpio_direction_output()
118 gpiommgpio->control[control_port] &= ~BIT(3); in gpiomm_gpio_direction_output()
120 gpiommgpio->io_state[io_port] &= 0xF0; in gpiomm_gpio_direction_output()
121 gpiommgpio->control[control_port] &= ~BIT(0); in gpiomm_gpio_direction_output()
124 gpiommgpio->io_state[io_port] &= 0x00; in gpiomm_gpio_direction_output()
126 gpiommgpio->control[control_port] &= ~BIT(4); in gpiomm_gpio_direction_output()
128 gpiommgpio->control[control_port] &= ~BIT(1); in gpiomm_gpio_direction_output()
132 gpiommgpio->out_state[io_port] |= mask; in gpiomm_gpio_direction_output()
134 gpiommgpio->out_state[io_port] &= ~mask; in gpiomm_gpio_direction_output()
136 control = BIT(7) | gpiommgpio->control[control_port]; in gpiomm_gpio_direction_output()
139 outb(gpiommgpio->out_state[io_port], gpiommgpio->base + out_port); in gpiomm_gpio_direction_output()
141 spin_unlock_irqrestore(&gpiommgpio->lock, flags); in gpiomm_gpio_direction_output()
146 static int gpiomm_gpio_get(struct gpio_chip *chip, unsigned int offset) in gpiomm_gpio_get() argument
149 const unsigned int port = offset / 8; in gpiomm_gpio_get()
150 const unsigned int mask = BIT(offset % 8); in gpiomm_gpio_get()
155 spin_lock_irqsave(&gpiommgpio->lock, flags); in gpiomm_gpio_get()
158 if (!(gpiommgpio->io_state[port] & mask)) { in gpiomm_gpio_get()
159 spin_unlock_irqrestore(&gpiommgpio->lock, flags); in gpiomm_gpio_get()
160 return -EINVAL; in gpiomm_gpio_get()
163 port_state = inb(gpiommgpio->base + in_port); in gpiomm_gpio_get()
165 spin_unlock_irqrestore(&gpiommgpio->lock, flags); in gpiomm_gpio_get()
176 unsigned long offset; in gpiomm_gpio_get_multiple() local
182 bitmap_zero(bits, chip->ngpio); in gpiomm_gpio_get_multiple()
184 for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) { in gpiomm_gpio_get_multiple()
185 port_addr = gpiommgpio->base + ports[offset / 8]; in gpiomm_gpio_get_multiple()
188 bitmap_set_value8(bits, port_state, offset); in gpiomm_gpio_get_multiple()
194 static void gpiomm_gpio_set(struct gpio_chip *chip, unsigned int offset, in gpiomm_gpio_set() argument
198 const unsigned int port = offset / 8; in gpiomm_gpio_set()
199 const unsigned int mask = BIT(offset % 8); in gpiomm_gpio_set()
203 spin_lock_irqsave(&gpiommgpio->lock, flags); in gpiomm_gpio_set()
206 gpiommgpio->out_state[port] |= mask; in gpiomm_gpio_set()
208 gpiommgpio->out_state[port] &= ~mask; in gpiomm_gpio_set()
210 outb(gpiommgpio->out_state[port], gpiommgpio->base + out_port); in gpiomm_gpio_set()
212 spin_unlock_irqrestore(&gpiommgpio->lock, flags); in gpiomm_gpio_set()
219 unsigned long offset; in gpiomm_gpio_set_multiple() local
226 for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) { in gpiomm_gpio_set_multiple()
227 index = offset / 8; in gpiomm_gpio_set_multiple()
228 port_addr = gpiommgpio->base + ports[index]; in gpiomm_gpio_set_multiple()
230 bitmask = bitmap_get_value8(bits, offset) & gpio_mask; in gpiomm_gpio_set_multiple()
232 spin_lock_irqsave(&gpiommgpio->lock, flags); in gpiomm_gpio_set_multiple()
235 gpiommgpio->out_state[index] &= ~gpio_mask; in gpiomm_gpio_set_multiple()
236 gpiommgpio->out_state[index] |= bitmask; in gpiomm_gpio_set_multiple()
237 outb(gpiommgpio->out_state[index], port_addr); in gpiomm_gpio_set_multiple()
239 spin_unlock_irqrestore(&gpiommgpio->lock, flags); in gpiomm_gpio_set_multiple()
263 return -ENOMEM; in gpiomm_probe()
266 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", in gpiomm_probe()
268 return -EBUSY; in gpiomm_probe()
271 gpiommgpio->chip.label = name; in gpiomm_probe()
272 gpiommgpio->chip.parent = dev; in gpiomm_probe()
273 gpiommgpio->chip.owner = THIS_MODULE; in gpiomm_probe()
274 gpiommgpio->chip.base = -1; in gpiomm_probe()
275 gpiommgpio->chip.ngpio = GPIOMM_NGPIO; in gpiomm_probe()
276 gpiommgpio->chip.names = gpiomm_names; in gpiomm_probe()
277 gpiommgpio->chip.get_direction = gpiomm_gpio_get_direction; in gpiomm_probe()
278 gpiommgpio->chip.direction_input = gpiomm_gpio_direction_input; in gpiomm_probe()
279 gpiommgpio->chip.direction_output = gpiomm_gpio_direction_output; in gpiomm_probe()
280 gpiommgpio->chip.get = gpiomm_gpio_get; in gpiomm_probe()
281 gpiommgpio->chip.get_multiple = gpiomm_gpio_get_multiple; in gpiomm_probe()
282 gpiommgpio->chip.set = gpiomm_gpio_set; in gpiomm_probe()
283 gpiommgpio->chip.set_multiple = gpiomm_gpio_set_multiple; in gpiomm_probe()
284 gpiommgpio->base = base[id]; in gpiomm_probe()
286 spin_lock_init(&gpiommgpio->lock); in gpiomm_probe()
288 err = devm_gpiochip_add_data(dev, &gpiommgpio->chip, gpiommgpio); in gpiomm_probe()
310 .name = "gpio-mm"
317 MODULE_DESCRIPTION("Diamond Systems GPIO-MM GPIO driver");