hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/gpio/gpio-gpio-mm.c
....@@ -1,15 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * GPIO driver for the Diamond Systems GPIO-MM
34 * Copyright (C) 2016 William Breathitt Gray
4
- *
5
- * This program is free software; you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License, version 2, as
7
- * published by the Free Software Foundation.
8
- *
9
- * This program is distributed in the hope that it will be useful, but
10
- * WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
- * General Public License for more details.
135 *
146 * This driver supports the following Diamond Systems devices: GPIO-MM and
157 * GPIO-MM-12.
....@@ -60,7 +52,10 @@
6052 const unsigned int port = offset / 8;
6153 const unsigned int mask = BIT(offset % 8);
6254
63
- return !!(gpiommgpio->io_state[port] & mask);
55
+ if (gpiommgpio->io_state[port] & mask)
56
+ return GPIO_LINE_DIRECTION_IN;
57
+
58
+ return GPIO_LINE_DIRECTION_OUT;
6459 }
6560
6661 static int gpiomm_gpio_direction_input(struct gpio_chip *chip,
....@@ -172,46 +167,25 @@
172167 return !!(port_state & mask);
173168 }
174169
170
+static const size_t ports[] = { 0, 1, 2, 4, 5, 6 };
171
+
175172 static int gpiomm_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
176173 unsigned long *bits)
177174 {
178175 struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
179
- size_t i;
180
- static const size_t ports[] = { 0, 1, 2, 4, 5, 6 };
181
- const unsigned int gpio_reg_size = 8;
182
- unsigned int bits_offset;
183
- size_t word_index;
184
- unsigned int word_offset;
185
- unsigned long word_mask;
186
- const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
176
+ unsigned long offset;
177
+ unsigned long gpio_mask;
178
+ unsigned int port_addr;
187179 unsigned long port_state;
188180
189181 /* clear bits array to a clean slate */
190182 bitmap_zero(bits, chip->ngpio);
191183
192
- /* get bits are evaluated a gpio port register at a time */
193
- for (i = 0; i < ARRAY_SIZE(ports); i++) {
194
- /* gpio offset in bits array */
195
- bits_offset = i * gpio_reg_size;
184
+ for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
185
+ port_addr = gpiommgpio->base + ports[offset / 8];
186
+ port_state = inb(port_addr) & gpio_mask;
196187
197
- /* word index for bits array */
198
- word_index = BIT_WORD(bits_offset);
199
-
200
- /* gpio offset within current word of bits array */
201
- word_offset = bits_offset % BITS_PER_LONG;
202
-
203
- /* mask of get bits for current gpio within current word */
204
- word_mask = mask[word_index] & (port_mask << word_offset);
205
- if (!word_mask) {
206
- /* no get bits in this port so skip to next one */
207
- continue;
208
- }
209
-
210
- /* read bits from current gpio port */
211
- port_state = inb(gpiommgpio->base + ports[i]);
212
-
213
- /* store acquired bits at respective bits array offset */
214
- bits[word_index] |= port_state << word_offset;
188
+ bitmap_set_value8(bits, port_state, offset);
215189 }
216190
217191 return 0;
....@@ -242,37 +216,27 @@
242216 unsigned long *mask, unsigned long *bits)
243217 {
244218 struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
245
- unsigned int i;
246
- const unsigned int gpio_reg_size = 8;
247
- unsigned int port;
248
- unsigned int out_port;
249
- unsigned int bitmask;
219
+ unsigned long offset;
220
+ unsigned long gpio_mask;
221
+ size_t index;
222
+ unsigned int port_addr;
223
+ unsigned long bitmask;
250224 unsigned long flags;
251225
252
- /* set bits are evaluated a gpio register size at a time */
253
- for (i = 0; i < chip->ngpio; i += gpio_reg_size) {
254
- /* no more set bits in this mask word; skip to the next word */
255
- if (!mask[BIT_WORD(i)]) {
256
- i = (BIT_WORD(i) + 1) * BITS_PER_LONG - gpio_reg_size;
257
- continue;
258
- }
226
+ for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
227
+ index = offset / 8;
228
+ port_addr = gpiommgpio->base + ports[index];
259229
260
- port = i / gpio_reg_size;
261
- out_port = (port > 2) ? port + 1 : port;
262
- bitmask = mask[BIT_WORD(i)] & bits[BIT_WORD(i)];
230
+ bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
263231
264232 spin_lock_irqsave(&gpiommgpio->lock, flags);
265233
266234 /* update output state data and set device gpio register */
267
- gpiommgpio->out_state[port] &= ~mask[BIT_WORD(i)];
268
- gpiommgpio->out_state[port] |= bitmask;
269
- outb(gpiommgpio->out_state[port], gpiommgpio->base + out_port);
235
+ gpiommgpio->out_state[index] &= ~gpio_mask;
236
+ gpiommgpio->out_state[index] |= bitmask;
237
+ outb(gpiommgpio->out_state[index], port_addr);
270238
271239 spin_unlock_irqrestore(&gpiommgpio->lock, flags);
272
-
273
- /* prepare for next gpio register set */
274
- mask[BIT_WORD(i)] >>= gpio_reg_size;
275
- bits[BIT_WORD(i)] >>= gpio_reg_size;
276240 }
277241 }
278242