aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-orion/gpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-orion/gpio.c')
-rw-r--r--arch/arm/plat-orion/gpio.c194
1 files changed, 75 insertions, 119 deletions
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
index 32eb9e33beb..e814803d474 100644
--- a/arch/arm/plat-orion/gpio.c
+++ b/arch/arm/plat-orion/gpio.c
@@ -15,10 +15,9 @@
15#include <linux/spinlock.h> 15#include <linux/spinlock.h>
16#include <linux/bitops.h> 16#include <linux/bitops.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <asm/gpio.h> 18#include <linux/gpio.h>
19 19
20static DEFINE_SPINLOCK(gpio_lock); 20static DEFINE_SPINLOCK(gpio_lock);
21static const char *gpio_label[GPIO_MAX]; /* non null for allocated GPIOs */
22static unsigned long gpio_valid_input[BITS_TO_LONGS(GPIO_MAX)]; 21static unsigned long gpio_valid_input[BITS_TO_LONGS(GPIO_MAX)];
23static unsigned long gpio_valid_output[BITS_TO_LONGS(GPIO_MAX)]; 22static unsigned long gpio_valid_output[BITS_TO_LONGS(GPIO_MAX)];
24 23
@@ -46,82 +45,54 @@ static void __set_level(unsigned pin, int high)
46 writel(u, GPIO_OUT(pin)); 45 writel(u, GPIO_OUT(pin));
47} 46}
48 47
49 48static inline void __set_blinking(unsigned pin, int blink)
50/*
51 * GENERIC_GPIO primitives.
52 */
53int gpio_direction_input(unsigned pin)
54{ 49{
55 unsigned long flags; 50 u32 u;
56
57 if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid_input)) {
58 pr_debug("%s: invalid GPIO %d\n", __func__, pin);
59 return -EINVAL;
60 }
61
62 spin_lock_irqsave(&gpio_lock, flags);
63
64 /*
65 * Some callers might not have used gpio_request(),
66 * so flag this pin as requested now.
67 */
68 if (gpio_label[pin] == NULL)
69 gpio_label[pin] = "?";
70 51
71 /* 52 u = readl(GPIO_BLINK_EN(pin));
72 * Configure GPIO direction. 53 if (blink)
73 */ 54 u |= 1 << (pin & 31);
74 __set_direction(pin, 1); 55 else
56 u &= ~(1 << (pin & 31));
57 writel(u, GPIO_BLINK_EN(pin));
58}
75 59
76 spin_unlock_irqrestore(&gpio_lock, flags); 60static inline int orion_gpio_is_valid(unsigned pin, int mode)
61{
62 if (pin < GPIO_MAX) {
63 if ((mode & GPIO_INPUT_OK) && !test_bit(pin, gpio_valid_input))
64 goto err_out;
65 if ((mode & GPIO_OUTPUT_OK) && !test_bit(pin, gpio_valid_output))
66 goto err_out;
67 return true;
68 }
77 69
78 return 0; 70err_out:
71 pr_debug("%s: invalid GPIO %d\n", __func__, pin);
72 return false;
79} 73}
80EXPORT_SYMBOL(gpio_direction_input);
81 74
82int gpio_direction_output(unsigned pin, int value) 75/*
76 * GENERIC_GPIO primitives.
77 */
78static int orion_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
83{ 79{
84 unsigned long flags; 80 unsigned long flags;
85 u32 u;
86 81
87 if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid_output)) { 82 if (!orion_gpio_is_valid(pin, GPIO_INPUT_OK))
88 pr_debug("%s: invalid GPIO %d\n", __func__, pin);
89 return -EINVAL; 83 return -EINVAL;
90 }
91 84
92 spin_lock_irqsave(&gpio_lock, flags); 85 spin_lock_irqsave(&gpio_lock, flags);
93 86
94 /* 87 /* Configure GPIO direction. */
95 * Some callers might not have used gpio_request(), 88 __set_direction(pin, 1);
96 * so flag this pin as requested now.
97 */
98 if (gpio_label[pin] == NULL)
99 gpio_label[pin] = "?";
100
101 /*
102 * Disable blinking.
103 */
104 u = readl(GPIO_BLINK_EN(pin));
105 u &= ~(1 << (pin & 31));
106 writel(u, GPIO_BLINK_EN(pin));
107
108 /*
109 * Configure GPIO output value.
110 */
111 __set_level(pin, value);
112
113 /*
114 * Configure GPIO direction.
115 */
116 __set_direction(pin, 0);
117 89
118 spin_unlock_irqrestore(&gpio_lock, flags); 90 spin_unlock_irqrestore(&gpio_lock, flags);
119 91
120 return 0; 92 return 0;
121} 93}
122EXPORT_SYMBOL(gpio_direction_output);
123 94
124int gpio_get_value(unsigned pin) 95static int orion_gpio_get_value(struct gpio_chip *chip, unsigned pin)
125{ 96{
126 int val; 97 int val;
127 98
@@ -132,83 +103,75 @@ int gpio_get_value(unsigned pin)
132 103
133 return (val >> (pin & 31)) & 1; 104 return (val >> (pin & 31)) & 1;
134} 105}
135EXPORT_SYMBOL(gpio_get_value);
136 106
137void gpio_set_value(unsigned pin, int value) 107static int orion_gpio_direction_output(struct gpio_chip *chip, unsigned pin,
108 int value)
138{ 109{
139 unsigned long flags; 110 unsigned long flags;
140 u32 u; 111
112 if (!orion_gpio_is_valid(pin, GPIO_OUTPUT_OK))
113 return -EINVAL;
141 114
142 spin_lock_irqsave(&gpio_lock, flags); 115 spin_lock_irqsave(&gpio_lock, flags);
143 116
144 /* 117 /* Disable blinking. */
145 * Disable blinking. 118 __set_blinking(pin, 0);
146 */
147 u = readl(GPIO_BLINK_EN(pin));
148 u &= ~(1 << (pin & 31));
149 writel(u, GPIO_BLINK_EN(pin));
150 119
151 /* 120 /* Configure GPIO output value. */
152 * Configure GPIO output value.
153 */
154 __set_level(pin, value); 121 __set_level(pin, value);
155 122
123 /* Configure GPIO direction. */
124 __set_direction(pin, 0);
125
156 spin_unlock_irqrestore(&gpio_lock, flags); 126 spin_unlock_irqrestore(&gpio_lock, flags);
127
128 return 0;
157} 129}
158EXPORT_SYMBOL(gpio_set_value);
159 130
160int gpio_request(unsigned pin, const char *label) 131static void orion_gpio_set_value(struct gpio_chip *chip, unsigned pin,
132 int value)
161{ 133{
162 unsigned long flags; 134 unsigned long flags;
163 int ret;
164
165 if (pin >= GPIO_MAX ||
166 !(test_bit(pin, gpio_valid_input) ||
167 test_bit(pin, gpio_valid_output))) {
168 pr_debug("%s: invalid GPIO %d\n", __func__, pin);
169 return -EINVAL;
170 }
171 135
172 spin_lock_irqsave(&gpio_lock, flags); 136 spin_lock_irqsave(&gpio_lock, flags);
173 if (gpio_label[pin] == NULL) {
174 gpio_label[pin] = label ? label : "?";
175 ret = 0;
176 } else {
177 pr_debug("%s: GPIO %d already used as %s\n",
178 __func__, pin, gpio_label[pin]);
179 ret = -EBUSY;
180 }
181 spin_unlock_irqrestore(&gpio_lock, flags);
182 137
183 return ret; 138 /* Configure GPIO output value. */
139 __set_level(pin, value);
140
141 spin_unlock_irqrestore(&gpio_lock, flags);
184} 142}
185EXPORT_SYMBOL(gpio_request);
186 143
187void gpio_free(unsigned pin) 144static int orion_gpio_request(struct gpio_chip *chip, unsigned pin)
188{ 145{
189 if (pin >= GPIO_MAX || 146 if (orion_gpio_is_valid(pin, GPIO_INPUT_OK) ||
190 !(test_bit(pin, gpio_valid_input) || 147 orion_gpio_is_valid(pin, GPIO_OUTPUT_OK))
191 test_bit(pin, gpio_valid_output))) { 148 return 0;
192 pr_debug("%s: invalid GPIO %d\n", __func__, pin); 149 return -EINVAL;
193 return;
194 }
195
196 if (gpio_label[pin] == NULL)
197 pr_warning("%s: GPIO %d already freed\n", __func__, pin);
198 else
199 gpio_label[pin] = NULL;
200} 150}
201EXPORT_SYMBOL(gpio_free);
202 151
152static struct gpio_chip orion_gpiochip = {
153 .label = "orion_gpio",
154 .direction_input = orion_gpio_direction_input,
155 .get = orion_gpio_get_value,
156 .direction_output = orion_gpio_direction_output,
157 .set = orion_gpio_set_value,
158 .request = orion_gpio_request,
159 .base = 0,
160 .ngpio = GPIO_MAX,
161 .can_sleep = 0,
162};
163
164void __init orion_gpio_init(void)
165{
166 gpiochip_add(&orion_gpiochip);
167}
203 168
204/* 169/*
205 * Orion-specific GPIO API extensions. 170 * Orion-specific GPIO API extensions.
206 */ 171 */
207void __init orion_gpio_set_unused(unsigned pin) 172void __init orion_gpio_set_unused(unsigned pin)
208{ 173{
209 /* 174 /* Configure as output, drive low. */
210 * Configure as output, drive low.
211 */
212 __set_level(pin, 0); 175 __set_level(pin, 0);
213 __set_direction(pin, 0); 176 __set_direction(pin, 0);
214} 177}
@@ -230,21 +193,14 @@ void __init orion_gpio_set_valid(unsigned pin, int mode)
230void orion_gpio_set_blink(unsigned pin, int blink) 193void orion_gpio_set_blink(unsigned pin, int blink)
231{ 194{
232 unsigned long flags; 195 unsigned long flags;
233 u32 u;
234 196
235 spin_lock_irqsave(&gpio_lock, flags); 197 spin_lock_irqsave(&gpio_lock, flags);
236 198
237 /* 199 /* Set output value to zero. */
238 * Set output value to zero.
239 */
240 __set_level(pin, 0); 200 __set_level(pin, 0);
241 201
242 u = readl(GPIO_BLINK_EN(pin)); 202 /* Set blinking. */
243 if (blink) 203 __set_blinking(pin, blink);
244 u |= 1 << (pin & 31);
245 else
246 u &= ~(1 << (pin & 31));
247 writel(u, GPIO_BLINK_EN(pin));
248 204
249 spin_unlock_irqrestore(&gpio_lock, flags); 205 spin_unlock_irqrestore(&gpio_lock, flags);
250} 206}
@@ -368,7 +324,7 @@ static int gpio_irq_set_type(u32 irq, u32 type)
368} 324}
369 325
370struct irq_chip orion_gpio_irq_chip = { 326struct irq_chip orion_gpio_irq_chip = {
371 .name = "orion_gpio", 327 .name = "orion_gpio_irq",
372 .ack = gpio_irq_ack, 328 .ack = gpio_irq_ack,
373 .mask = gpio_irq_mask, 329 .mask = gpio_irq_mask,
374 .unmask = gpio_irq_unmask, 330 .unmask = gpio_irq_unmask,