hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/drivers/gpio/gpio-mmio.c
....@@ -1,13 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0+
12 /*
23 * Generic driver for memory-mapped GPIO controllers.
34 *
45 * Copyright 2008 MontaVista Software, Inc.
56 * Copyright 2008,2010 Anton Vorontsov <cbouatmailru@gmail.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify it
8
- * under the terms of the GNU General Public License as published by the
9
- * Free Software Foundation; either version 2 of the License, or (at your
10
- * option) any later version.
117 *
128 * ....``.```~~~~````.`.`.`.`.```````'',,,.........`````......`.......
139 * ...`` ```````..
....@@ -138,17 +134,6 @@
138134 unsigned long pinmask = bgpio_line2mask(gc, gpio);
139135 bool dir = !!(gc->bgpio_dir & pinmask);
140136
141
- /*
142
- * If the direction is OUT we read the value from the SET
143
- * register, and if the direction is IN we read the value
144
- * from the DAT register.
145
- *
146
- * If the direction bits are inverted, naturally this gets
147
- * inverted too.
148
- */
149
- if (gc->bgpio_dir_inverted)
150
- dir = !dir;
151
-
152137 if (dir)
153138 return !!(gc->read_reg(gc->reg_set) & pinmask);
154139 else
....@@ -168,14 +153,8 @@
168153 /* Make sure we first clear any bits that are zero when we read the register */
169154 *bits &= ~*mask;
170155
171
- /* Exploit the fact that we know which directions are set */
172
- if (gc->bgpio_dir_inverted) {
173
- set_mask = *mask & ~gc->bgpio_dir;
174
- get_mask = *mask & gc->bgpio_dir;
175
- } else {
176
- set_mask = *mask & gc->bgpio_dir;
177
- get_mask = *mask & ~gc->bgpio_dir;
178
- }
156
+ set_mask = *mask & gc->bgpio_dir;
157
+ get_mask = *mask & ~gc->bgpio_dir;
179158
180159 if (set_mask)
181160 *bits |= gc->read_reg(gc->reg_set) & set_mask;
....@@ -216,8 +195,7 @@
216195 *bits &= ~*mask;
217196
218197 /* Create a mirrored mask */
219
- bit = -1;
220
- while ((bit = find_next_bit(mask, gc->ngpio, bit + 1)) < gc->ngpio)
198
+ for_each_set_bit(bit, mask, gc->ngpio)
221199 readmask |= bgpio_line2mask(gc, bit);
222200
223201 /* Read the register */
....@@ -227,8 +205,7 @@
227205 * Mirror the result into the "bits" result, this will give line 0
228206 * in bit 0 ... line 31 in bit 31 for a 32bit register.
229207 */
230
- bit = -1;
231
- while ((bit = find_next_bit(&val, gc->ngpio, bit + 1)) < gc->ngpio)
208
+ for_each_set_bit(bit, &val, gc->ngpio)
232209 *bits |= bgpio_line2mask(gc, bit);
233210
234211 return 0;
....@@ -293,15 +270,11 @@
293270 *set_mask = 0;
294271 *clear_mask = 0;
295272
296
- for (i = 0; i < gc->bgpio_bits; i++) {
297
- if (*mask == 0)
298
- break;
299
- if (__test_and_clear_bit(i, mask)) {
300
- if (test_bit(i, bits))
301
- *set_mask |= bgpio_line2mask(gc, i);
302
- else
303
- *clear_mask |= bgpio_line2mask(gc, i);
304
- }
273
+ for_each_set_bit(i, mask, gc->bgpio_bits) {
274
+ if (test_bit(i, bits))
275
+ *set_mask |= bgpio_line2mask(gc, i);
276
+ else
277
+ *clear_mask |= bgpio_line2mask(gc, i);
305278 }
306279 }
307280
....@@ -376,11 +349,12 @@
376349
377350 spin_lock_irqsave(&gc->bgpio_lock, flags);
378351
379
- if (gc->bgpio_dir_inverted)
380
- gc->bgpio_dir |= bgpio_line2mask(gc, gpio);
381
- else
382
- gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio);
383
- gc->write_reg(gc->reg_dir, gc->bgpio_dir);
352
+ gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio);
353
+
354
+ if (gc->reg_dir_in)
355
+ gc->write_reg(gc->reg_dir_in, ~gc->bgpio_dir);
356
+ if (gc->reg_dir_out)
357
+ gc->write_reg(gc->reg_dir_out, gc->bgpio_dir);
384358
385359 spin_unlock_irqrestore(&gc->bgpio_lock, flags);
386360
....@@ -389,29 +363,55 @@
389363
390364 static int bgpio_get_dir(struct gpio_chip *gc, unsigned int gpio)
391365 {
392
- /* Return 0 if output, 1 of input */
393
- if (gc->bgpio_dir_inverted)
394
- return !!(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio));
395
- else
396
- return !(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio));
366
+ /* Return 0 if output, 1 if input */
367
+ if (gc->bgpio_dir_unreadable) {
368
+ if (gc->bgpio_dir & bgpio_line2mask(gc, gpio))
369
+ return GPIO_LINE_DIRECTION_OUT;
370
+ return GPIO_LINE_DIRECTION_IN;
371
+ }
372
+
373
+ if (gc->reg_dir_out) {
374
+ if (gc->read_reg(gc->reg_dir_out) & bgpio_line2mask(gc, gpio))
375
+ return GPIO_LINE_DIRECTION_OUT;
376
+ return GPIO_LINE_DIRECTION_IN;
377
+ }
378
+
379
+ if (gc->reg_dir_in)
380
+ if (!(gc->read_reg(gc->reg_dir_in) & bgpio_line2mask(gc, gpio)))
381
+ return GPIO_LINE_DIRECTION_OUT;
382
+
383
+ return GPIO_LINE_DIRECTION_IN;
397384 }
398385
399
-static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
386
+static void bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
400387 {
401388 unsigned long flags;
402389
403
- gc->set(gc, gpio, val);
404
-
405390 spin_lock_irqsave(&gc->bgpio_lock, flags);
406391
407
- if (gc->bgpio_dir_inverted)
408
- gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio);
409
- else
410
- gc->bgpio_dir |= bgpio_line2mask(gc, gpio);
411
- gc->write_reg(gc->reg_dir, gc->bgpio_dir);
392
+ gc->bgpio_dir |= bgpio_line2mask(gc, gpio);
393
+
394
+ if (gc->reg_dir_in)
395
+ gc->write_reg(gc->reg_dir_in, ~gc->bgpio_dir);
396
+ if (gc->reg_dir_out)
397
+ gc->write_reg(gc->reg_dir_out, gc->bgpio_dir);
412398
413399 spin_unlock_irqrestore(&gc->bgpio_lock, flags);
400
+}
414401
402
+static int bgpio_dir_out_dir_first(struct gpio_chip *gc, unsigned int gpio,
403
+ int val)
404
+{
405
+ bgpio_dir_out(gc, gpio, val);
406
+ gc->set(gc, gpio, val);
407
+ return 0;
408
+}
409
+
410
+static int bgpio_dir_out_val_first(struct gpio_chip *gc, unsigned int gpio,
411
+ int val)
412
+{
413
+ gc->set(gc, gpio, val);
414
+ bgpio_dir_out(gc, gpio, val);
415415 return 0;
416416 }
417417
....@@ -541,19 +541,15 @@
541541 void __iomem *dirin,
542542 unsigned long flags)
543543 {
544
- if (dirout && dirin) {
545
- return -EINVAL;
546
- } else if (dirout) {
547
- gc->reg_dir = dirout;
548
- gc->direction_output = bgpio_dir_out;
544
+ if (dirout || dirin) {
545
+ gc->reg_dir_out = dirout;
546
+ gc->reg_dir_in = dirin;
547
+ if (flags & BGPIOF_NO_SET_ON_INPUT)
548
+ gc->direction_output = bgpio_dir_out_dir_first;
549
+ else
550
+ gc->direction_output = bgpio_dir_out_val_first;
549551 gc->direction_input = bgpio_dir_in;
550552 gc->get_direction = bgpio_get_dir;
551
- } else if (dirin) {
552
- gc->reg_dir = dirin;
553
- gc->direction_output = bgpio_dir_out;
554
- gc->direction_input = bgpio_dir_in;
555
- gc->get_direction = bgpio_get_dir;
556
- gc->bgpio_dir_inverted = true;
557553 } else {
558554 if (flags & BGPIOF_NO_OUTPUT)
559555 gc->direction_output = bgpio_dir_out_err;
....@@ -592,11 +588,11 @@
592588 * @dirout: MMIO address for the register to set the line as OUTPUT. It is assumed
593589 * that setting a line to 1 in this register will turn that line into an
594590 * output line. Conversely, setting the line to 0 will turn that line into
595
- * an input. Either this or @dirin can be defined, but never both.
591
+ * an input.
596592 * @dirin: MMIO address for the register to set this line as INPUT. It is assumed
597593 * that setting a line to 1 in this register will turn that line into an
598594 * input line. Conversely, setting the line to 0 will turn that line into
599
- * an output. Either this or @dirout can be defined, but never both.
595
+ * an output.
600596 * @flags: Different flags that will affect the behaviour of the device, such as
601597 * endianness etc.
602598 */
....@@ -638,8 +634,28 @@
638634 if (gc->set == bgpio_set_set &&
639635 !(flags & BGPIOF_UNREADABLE_REG_SET))
640636 gc->bgpio_data = gc->read_reg(gc->reg_set);
641
- if (gc->reg_dir && !(flags & BGPIOF_UNREADABLE_REG_DIR))
642
- gc->bgpio_dir = gc->read_reg(gc->reg_dir);
637
+
638
+ if (flags & BGPIOF_UNREADABLE_REG_DIR)
639
+ gc->bgpio_dir_unreadable = true;
640
+
641
+ /*
642
+ * Inspect hardware to find initial direction setting.
643
+ */
644
+ if ((gc->reg_dir_out || gc->reg_dir_in) &&
645
+ !(flags & BGPIOF_UNREADABLE_REG_DIR)) {
646
+ if (gc->reg_dir_out)
647
+ gc->bgpio_dir = gc->read_reg(gc->reg_dir_out);
648
+ else if (gc->reg_dir_in)
649
+ gc->bgpio_dir = ~gc->read_reg(gc->reg_dir_in);
650
+ /*
651
+ * If we have two direction registers, synchronise
652
+ * input setting to output setting, the library
653
+ * can not handle a line being input and output at
654
+ * the same time.
655
+ */
656
+ if (gc->reg_dir_out && gc->reg_dir_in)
657
+ gc->write_reg(gc->reg_dir_in, ~gc->bgpio_dir);
658
+ }
643659
644660 return ret;
645661 }