1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
From: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Date: Mon, 28 Apr 2008 09:14:46 +0000 (-0700)
Subject: gpio: define gpio_is_valid()
X-Git-Tag: v2.6.26-rc1~849
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=e6de1808f8ebfeb7e49f3c5a30cb8f2032beb287
gpio: define gpio_is_valid()
Introduce a gpio_is_valid() predicate; use it in gpiolib.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
[ use inline function; follow the gpio_* naming convention;
work without gpiolib; all programming interfaces need docs ]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
--- a/Documentation/gpio.txt
+++ b/Documentation/gpio.txt
@@ -107,6 +107,16 @@
The numbers need not be contiguous; either of those platforms could also
use numbers 2000-2063 to identify GPIOs in a bank of I2C GPIO expanders.
+If you want to initialize a structure with an invalid GPIO number, use
+some negative number (perhaps "-EINVAL"); that will never be valid. To
+test if a number could reference a GPIO, you may use this predicate:
+
+ int gpio_is_valid(int number);
+
+A number that's not valid will be rejected by calls which may request
+or free GPIOs (see below). Other numbers may also be rejected; for
+example, a number might be valid but unused on a given board.
+
Whether a platform supports multiple GPIO controllers is currently a
platform-specific implementation issue.
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -99,7 +99,7 @@
* dynamic allocation. We don't currently support that.
*/
- if (chip->base < 0 || (chip->base + chip->ngpio) >= ARCH_NR_GPIOS) {
+ if (chip->base < 0 || !gpio_is_valid(chip->base + chip->ngpio)) {
status = -EINVAL;
goto fail;
}
@@ -174,7 +174,7 @@
spin_lock_irqsave(&gpio_lock, flags);
- if (gpio >= ARCH_NR_GPIOS)
+ if (!gpio_is_valid(gpio))
goto done;
desc = &gpio_desc[gpio];
if (desc->chip == NULL)
@@ -209,7 +209,7 @@
unsigned long flags;
struct gpio_desc *desc;
- if (gpio >= ARCH_NR_GPIOS) {
+ if (!gpio_is_valid(gpio)) {
WARN_ON(extra_checks);
return;
}
@@ -245,7 +245,7 @@
{
unsigned gpio = chip->base + offset;
- if (gpio >= ARCH_NR_GPIOS || gpio_desc[gpio].chip != chip)
+ if (!gpio_is_valid(gpio) || gpio_desc[gpio].chip != chip)
return NULL;
if (test_bit(FLAG_REQUESTED, &gpio_desc[gpio].flags) == 0)
return NULL;
@@ -276,7 +276,7 @@
spin_lock_irqsave(&gpio_lock, flags);
- if (gpio >= ARCH_NR_GPIOS)
+ if (!gpio_is_valid(gpio))
goto fail;
chip = desc->chip;
if (!chip || !chip->get || !chip->direction_input)
@@ -314,7 +314,7 @@
spin_lock_irqsave(&gpio_lock, flags);
- if (gpio >= ARCH_NR_GPIOS)
+ if (!gpio_is_valid(gpio))
goto fail;
chip = desc->chip;
if (!chip || !chip->set || !chip->direction_output)
@@ -531,7 +531,7 @@
/* REVISIT this isn't locked against gpio_chip removal ... */
- for (gpio = 0; gpio < ARCH_NR_GPIOS; gpio++) {
+ for (gpio = 0; gpio_is_valid(gpio); gpio++) {
if (chip == gpio_desc[gpio].chip)
continue;
chip = gpio_desc[gpio].chip;
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -16,6 +16,12 @@
#define ARCH_NR_GPIOS 256
#endif
+static inline int gpio_is_valid(int number)
+{
+ /* only some non-negative numbers are valid */
+ return ((unsigned)number) < ARCH_NR_GPIOS;
+}
+
struct seq_file;
struct module;
@@ -99,6 +105,16 @@
#else
+static inline int __gpio_is_valid(int number)
+{
+ /* only non-negative numbers are valid */
+ return number >= 0;
+}
+
+#ifndef gpio_is_valid
+#define gpio_is_valid __gpio_is_valid
+#endif
+
/* platforms that don't directly support access to GPIOs through I2C, SPI,
* or other blocking infrastructure can use these wrappers.
*/
|