Commit | Line | Data |
---|---|---|
1394f032 BW |
1 | /* |
2 | * File: arch/blackfin/kernel/bfin_gpio.c | |
3 | * Based on: | |
4 | * Author: Michael Hennerich (hennerich@blackfin.uclinux.org) | |
5 | * | |
6 | * Created: | |
7 | * Description: GPIO Abstraction Layer | |
8 | * | |
9 | * Modified: | |
10 | * Copyright 2006 Analog Devices Inc. | |
11 | * | |
12 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | |
13 | * | |
14 | * This program is free software; you can redistribute it and/or modify | |
15 | * it under the terms of the GNU General Public License as published by | |
16 | * the Free Software Foundation; either version 2 of the License, or | |
17 | * (at your option) any later version. | |
18 | * | |
19 | * This program is distributed in the hope that it will be useful, | |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 | * GNU General Public License for more details. | |
23 | * | |
24 | * You should have received a copy of the GNU General Public License | |
25 | * along with this program; if not, see the file COPYING, or write | |
26 | * to the Free Software Foundation, Inc., | |
27 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
28 | */ | |
29 | ||
30 | /* | |
31 | * Number BF537/6/4 BF561 BF533/2/1 | |
32 | * | |
33 | * GPIO_0 PF0 PF0 PF0 | |
34 | * GPIO_1 PF1 PF1 PF1 | |
35 | * GPIO_2 PF2 PF2 PF2 | |
36 | * GPIO_3 PF3 PF3 PF3 | |
37 | * GPIO_4 PF4 PF4 PF4 | |
38 | * GPIO_5 PF5 PF5 PF5 | |
39 | * GPIO_6 PF6 PF6 PF6 | |
40 | * GPIO_7 PF7 PF7 PF7 | |
41 | * GPIO_8 PF8 PF8 PF8 | |
42 | * GPIO_9 PF9 PF9 PF9 | |
43 | * GPIO_10 PF10 PF10 PF10 | |
44 | * GPIO_11 PF11 PF11 PF11 | |
45 | * GPIO_12 PF12 PF12 PF12 | |
46 | * GPIO_13 PF13 PF13 PF13 | |
47 | * GPIO_14 PF14 PF14 PF14 | |
48 | * GPIO_15 PF15 PF15 PF15 | |
49 | * GPIO_16 PG0 PF16 | |
50 | * GPIO_17 PG1 PF17 | |
51 | * GPIO_18 PG2 PF18 | |
52 | * GPIO_19 PG3 PF19 | |
53 | * GPIO_20 PG4 PF20 | |
54 | * GPIO_21 PG5 PF21 | |
55 | * GPIO_22 PG6 PF22 | |
56 | * GPIO_23 PG7 PF23 | |
57 | * GPIO_24 PG8 PF24 | |
58 | * GPIO_25 PG9 PF25 | |
59 | * GPIO_26 PG10 PF26 | |
60 | * GPIO_27 PG11 PF27 | |
61 | * GPIO_28 PG12 PF28 | |
62 | * GPIO_29 PG13 PF29 | |
63 | * GPIO_30 PG14 PF30 | |
64 | * GPIO_31 PG15 PF31 | |
65 | * GPIO_32 PH0 PF32 | |
66 | * GPIO_33 PH1 PF33 | |
67 | * GPIO_34 PH2 PF34 | |
68 | * GPIO_35 PH3 PF35 | |
69 | * GPIO_36 PH4 PF36 | |
70 | * GPIO_37 PH5 PF37 | |
71 | * GPIO_38 PH6 PF38 | |
72 | * GPIO_39 PH7 PF39 | |
73 | * GPIO_40 PH8 PF40 | |
74 | * GPIO_41 PH9 PF41 | |
75 | * GPIO_42 PH10 PF42 | |
76 | * GPIO_43 PH11 PF43 | |
77 | * GPIO_44 PH12 PF44 | |
78 | * GPIO_45 PH13 PF45 | |
79 | * GPIO_46 PH14 PF46 | |
80 | * GPIO_47 PH15 PF47 | |
81 | */ | |
82 | ||
83 | #include <linux/module.h> | |
84 | #include <linux/err.h> | |
85 | #include <asm/blackfin.h> | |
86 | #include <asm/gpio.h> | |
87 | #include <linux/irq.h> | |
88 | ||
89 | #ifdef BF533_FAMILY | |
90 | static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = { | |
91 | (struct gpio_port_t *) FIO_FLAG_D, | |
92 | }; | |
93 | #endif | |
94 | ||
95 | #ifdef BF537_FAMILY | |
96 | static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = { | |
97 | (struct gpio_port_t *) PORTFIO, | |
98 | (struct gpio_port_t *) PORTGIO, | |
99 | (struct gpio_port_t *) PORTHIO, | |
100 | }; | |
101 | ||
102 | static unsigned short *port_fer[gpio_bank(MAX_BLACKFIN_GPIOS)] = { | |
103 | (unsigned short *) PORTF_FER, | |
104 | (unsigned short *) PORTG_FER, | |
105 | (unsigned short *) PORTH_FER, | |
106 | }; | |
107 | ||
108 | #endif | |
109 | ||
110 | #ifdef BF561_FAMILY | |
111 | static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = { | |
112 | (struct gpio_port_t *) FIO0_FLAG_D, | |
113 | (struct gpio_port_t *) FIO1_FLAG_D, | |
114 | (struct gpio_port_t *) FIO2_FLAG_D, | |
115 | }; | |
116 | #endif | |
117 | ||
118 | static unsigned short reserved_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; | |
119 | ||
120 | #ifdef CONFIG_PM | |
121 | static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; | |
122 | static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; | |
123 | static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; | |
124 | ||
125 | #ifdef BF533_FAMILY | |
126 | static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB}; | |
127 | #endif | |
128 | ||
129 | #ifdef BF537_FAMILY | |
130 | static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX}; | |
131 | #endif | |
132 | ||
133 | #ifdef BF561_FAMILY | |
134 | static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB}; | |
135 | #endif | |
136 | ||
137 | #endif /* CONFIG_PM */ | |
138 | ||
139 | inline int check_gpio(unsigned short gpio) | |
140 | { | |
e7613aab | 141 | if (gpio >= MAX_BLACKFIN_GPIOS) |
1394f032 BW |
142 | return -EINVAL; |
143 | return 0; | |
144 | } | |
145 | ||
146 | #ifdef BF537_FAMILY | |
a161bb05 | 147 | static void port_setup(unsigned short gpio, unsigned short usage) |
1394f032 BW |
148 | { |
149 | if (usage == GPIO_USAGE) { | |
150 | if (*port_fer[gpio_bank(gpio)] & gpio_bit(gpio)) | |
151 | printk(KERN_WARNING "bfin-gpio: Possible Conflict with Peripheral " | |
152 | "usage and GPIO %d detected!\n", gpio); | |
153 | *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio); | |
154 | } else | |
155 | *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); | |
156 | SSYNC(); | |
157 | } | |
158 | #else | |
159 | # define port_setup(...) do { } while (0) | |
160 | #endif | |
161 | ||
162 | ||
a161bb05 | 163 | static void default_gpio(unsigned short gpio) |
1394f032 | 164 | { |
1f83b8f1 | 165 | unsigned short bank, bitmask; |
1394f032 BW |
166 | |
167 | bank = gpio_bank(gpio); | |
168 | bitmask = gpio_bit(gpio); | |
169 | ||
170 | gpio_bankb[bank]->maska_clear = bitmask; | |
171 | gpio_bankb[bank]->maskb_clear = bitmask; | |
172 | SSYNC(); | |
173 | gpio_bankb[bank]->inen &= ~bitmask; | |
174 | gpio_bankb[bank]->dir &= ~bitmask; | |
175 | gpio_bankb[bank]->polar &= ~bitmask; | |
176 | gpio_bankb[bank]->both &= ~bitmask; | |
177 | gpio_bankb[bank]->edge &= ~bitmask; | |
178 | } | |
179 | ||
a161bb05 | 180 | static int __init bfin_gpio_init(void) |
1394f032 BW |
181 | { |
182 | int i; | |
183 | ||
184 | printk(KERN_INFO "Blackfin GPIO Controller\n"); | |
185 | ||
1f83b8f1 | 186 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) |
1394f032 BW |
187 | reserved_map[gpio_bank(i)] = 0; |
188 | ||
189 | #if defined(BF537_FAMILY) && (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) | |
190 | # if defined(CONFIG_BFIN_MAC_RMII) | |
9ae246cd | 191 | reserved_map[gpio_bank(PORT_H)] = 0xC373; |
1394f032 | 192 | # else |
9ae246cd | 193 | reserved_map[gpio_bank(PORT_H)] = 0xFFFF; |
1394f032 BW |
194 | # endif |
195 | #endif | |
196 | ||
197 | return 0; | |
198 | } | |
199 | ||
200 | arch_initcall(bfin_gpio_init); | |
201 | ||
202 | ||
203 | /*********************************************************** | |
204 | * | |
205 | * FUNCTIONS: Blackfin General Purpose Ports Access Functions | |
206 | * | |
207 | * INPUTS/OUTPUTS: | |
208 | * gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS | |
209 | * | |
210 | * | |
211 | * DESCRIPTION: These functions abstract direct register access | |
212 | * to Blackfin processor General Purpose | |
213 | * Ports Regsiters | |
214 | * | |
215 | * CAUTION: These functions do not belong to the GPIO Driver API | |
216 | ************************************************************* | |
217 | * MODIFICATION HISTORY : | |
218 | **************************************************************/ | |
219 | ||
220 | /* Set a specific bit */ | |
221 | ||
222 | #define SET_GPIO(name) \ | |
223 | void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ | |
224 | { \ | |
225 | unsigned long flags; \ | |
226 | BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \ | |
227 | local_irq_save(flags); \ | |
228 | if (arg) \ | |
229 | gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ | |
230 | else \ | |
231 | gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ | |
232 | local_irq_restore(flags); \ | |
233 | } \ | |
234 | EXPORT_SYMBOL(set_gpio_ ## name); | |
235 | ||
236 | SET_GPIO(dir) | |
237 | SET_GPIO(inen) | |
238 | SET_GPIO(polar) | |
239 | SET_GPIO(edge) | |
240 | SET_GPIO(both) | |
241 | ||
242 | ||
243 | #define SET_GPIO_SC(name) \ | |
244 | void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ | |
245 | { \ | |
246 | BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \ | |
247 | if (arg) \ | |
248 | gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ | |
249 | else \ | |
250 | gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ | |
251 | } \ | |
252 | EXPORT_SYMBOL(set_gpio_ ## name); | |
253 | ||
254 | SET_GPIO_SC(maska) | |
255 | SET_GPIO_SC(maskb) | |
256 | ||
257 | #if defined(ANOMALY_05000311) | |
258 | void set_gpio_data(unsigned short gpio, unsigned short arg) | |
259 | { | |
260 | unsigned long flags; | |
261 | BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); | |
262 | local_irq_save(flags); | |
263 | if (arg) | |
264 | gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); | |
265 | else | |
266 | gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); | |
267 | bfin_read_CHIPID(); | |
268 | local_irq_restore(flags); | |
269 | } | |
270 | EXPORT_SYMBOL(set_gpio_data); | |
271 | #else | |
272 | SET_GPIO_SC(data) | |
273 | #endif | |
274 | ||
275 | ||
276 | #if defined(ANOMALY_05000311) | |
277 | void set_gpio_toggle(unsigned short gpio) | |
278 | { | |
279 | unsigned long flags; | |
280 | BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); | |
281 | local_irq_save(flags); | |
282 | gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); | |
283 | bfin_read_CHIPID(); | |
284 | local_irq_restore(flags); | |
285 | } | |
286 | #else | |
287 | void set_gpio_toggle(unsigned short gpio) | |
288 | { | |
289 | BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); | |
290 | gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); | |
291 | } | |
292 | #endif | |
293 | EXPORT_SYMBOL(set_gpio_toggle); | |
294 | ||
295 | ||
296 | /*Set current PORT date (16-bit word)*/ | |
297 | ||
298 | #define SET_GPIO_P(name) \ | |
299 | void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ | |
300 | { \ | |
301 | gpio_bankb[gpio_bank(gpio)]->name = arg; \ | |
302 | } \ | |
303 | EXPORT_SYMBOL(set_gpiop_ ## name); | |
304 | ||
305 | SET_GPIO_P(dir) | |
306 | SET_GPIO_P(inen) | |
307 | SET_GPIO_P(polar) | |
308 | SET_GPIO_P(edge) | |
309 | SET_GPIO_P(both) | |
310 | SET_GPIO_P(maska) | |
311 | SET_GPIO_P(maskb) | |
312 | ||
313 | ||
314 | #if defined(ANOMALY_05000311) | |
315 | void set_gpiop_data(unsigned short gpio, unsigned short arg) | |
316 | { | |
317 | unsigned long flags; | |
318 | local_irq_save(flags); | |
319 | gpio_bankb[gpio_bank(gpio)]->data = arg; | |
320 | bfin_read_CHIPID(); | |
321 | local_irq_restore(flags); | |
322 | } | |
323 | EXPORT_SYMBOL(set_gpiop_data); | |
324 | #else | |
325 | SET_GPIO_P(data) | |
326 | #endif | |
327 | ||
328 | ||
329 | ||
330 | /* Get a specific bit */ | |
331 | ||
332 | #define GET_GPIO(name) \ | |
333 | unsigned short get_gpio_ ## name(unsigned short gpio) \ | |
334 | { \ | |
335 | return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ | |
336 | } \ | |
337 | EXPORT_SYMBOL(get_gpio_ ## name); | |
338 | ||
339 | GET_GPIO(dir) | |
340 | GET_GPIO(inen) | |
341 | GET_GPIO(polar) | |
342 | GET_GPIO(edge) | |
343 | GET_GPIO(both) | |
344 | GET_GPIO(maska) | |
345 | GET_GPIO(maskb) | |
346 | ||
347 | ||
348 | #if defined(ANOMALY_05000311) | |
349 | unsigned short get_gpio_data(unsigned short gpio) | |
350 | { | |
351 | unsigned long flags; | |
352 | unsigned short ret; | |
353 | BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); | |
354 | local_irq_save(flags); | |
355 | ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)); | |
356 | bfin_read_CHIPID(); | |
357 | local_irq_restore(flags); | |
358 | return ret; | |
359 | } | |
360 | EXPORT_SYMBOL(get_gpio_data); | |
361 | #else | |
362 | GET_GPIO(data) | |
363 | #endif | |
364 | ||
365 | /*Get current PORT date (16-bit word)*/ | |
366 | ||
367 | #define GET_GPIO_P(name) \ | |
368 | unsigned short get_gpiop_ ## name(unsigned short gpio) \ | |
369 | { \ | |
370 | return (gpio_bankb[gpio_bank(gpio)]->name);\ | |
371 | } \ | |
372 | EXPORT_SYMBOL(get_gpiop_ ## name); | |
373 | ||
374 | GET_GPIO_P(dir) | |
375 | GET_GPIO_P(inen) | |
376 | GET_GPIO_P(polar) | |
377 | GET_GPIO_P(edge) | |
378 | GET_GPIO_P(both) | |
379 | GET_GPIO_P(maska) | |
380 | GET_GPIO_P(maskb) | |
381 | ||
382 | #if defined(ANOMALY_05000311) | |
383 | unsigned short get_gpiop_data(unsigned short gpio) | |
384 | { | |
385 | unsigned long flags; | |
386 | unsigned short ret; | |
387 | local_irq_save(flags); | |
388 | ret = gpio_bankb[gpio_bank(gpio)]->data; | |
389 | bfin_read_CHIPID(); | |
390 | local_irq_restore(flags); | |
391 | return ret; | |
392 | } | |
393 | EXPORT_SYMBOL(get_gpiop_data); | |
394 | #else | |
395 | GET_GPIO_P(data) | |
396 | #endif | |
397 | ||
398 | #ifdef CONFIG_PM | |
399 | /*********************************************************** | |
400 | * | |
401 | * FUNCTIONS: Blackfin PM Setup API | |
402 | * | |
403 | * INPUTS/OUTPUTS: | |
404 | * gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS | |
405 | * type - | |
406 | * PM_WAKE_RISING | |
407 | * PM_WAKE_FALLING | |
408 | * PM_WAKE_HIGH | |
409 | * PM_WAKE_LOW | |
410 | * PM_WAKE_BOTH_EDGES | |
411 | * | |
412 | * DESCRIPTION: Blackfin PM Driver API | |
413 | * | |
414 | * CAUTION: | |
415 | ************************************************************* | |
416 | * MODIFICATION HISTORY : | |
417 | **************************************************************/ | |
418 | int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type) | |
419 | { | |
420 | unsigned long flags; | |
421 | ||
422 | if ((check_gpio(gpio) < 0) || !type) | |
423 | return -EINVAL; | |
424 | ||
425 | local_irq_save(flags); | |
426 | ||
427 | wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); | |
428 | wakeup_flags_map[gpio] = type; | |
429 | local_irq_restore(flags); | |
430 | ||
431 | return 0; | |
432 | } | |
433 | EXPORT_SYMBOL(gpio_pm_wakeup_request); | |
434 | ||
435 | void gpio_pm_wakeup_free(unsigned short gpio) | |
436 | { | |
437 | unsigned long flags; | |
438 | ||
439 | if (check_gpio(gpio) < 0) | |
440 | return; | |
441 | ||
442 | local_irq_save(flags); | |
443 | ||
444 | wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); | |
445 | ||
446 | local_irq_restore(flags); | |
447 | } | |
448 | EXPORT_SYMBOL(gpio_pm_wakeup_free); | |
449 | ||
450 | static int bfin_gpio_wakeup_type(unsigned short gpio, unsigned char type) | |
451 | { | |
452 | port_setup(gpio, GPIO_USAGE); | |
453 | set_gpio_dir(gpio, 0); | |
454 | set_gpio_inen(gpio, 1); | |
455 | ||
456 | if (type & (PM_WAKE_RISING | PM_WAKE_FALLING)) | |
457 | set_gpio_edge(gpio, 1); | |
458 | else | |
459 | set_gpio_edge(gpio, 0); | |
460 | ||
461 | if ((type & (PM_WAKE_BOTH_EDGES)) == (PM_WAKE_BOTH_EDGES)) | |
462 | set_gpio_both(gpio, 1); | |
463 | else | |
464 | set_gpio_both(gpio, 0); | |
465 | ||
466 | if ((type & (PM_WAKE_FALLING | PM_WAKE_LOW))) | |
467 | set_gpio_polar(gpio, 1); | |
468 | else | |
469 | set_gpio_polar(gpio, 0); | |
470 | ||
471 | SSYNC(); | |
472 | ||
473 | return 0; | |
474 | } | |
475 | ||
476 | u32 gpio_pm_setup(void) | |
477 | { | |
478 | u32 sic_iwr = 0; | |
479 | u16 bank, mask, i, gpio; | |
480 | ||
1f83b8f1 | 481 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { |
1394f032 BW |
482 | mask = wakeup_map[gpio_bank(i)]; |
483 | bank = gpio_bank(i); | |
484 | ||
485 | gpio_bank_saved[bank].maskb = gpio_bankb[bank]->maskb; | |
486 | gpio_bankb[bank]->maskb = 0; | |
487 | ||
488 | if (mask) { | |
489 | #ifdef BF537_FAMILY | |
490 | gpio_bank_saved[bank].fer = *port_fer[bank]; | |
491 | #endif | |
492 | gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; | |
493 | gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; | |
494 | gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; | |
495 | gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; | |
496 | gpio_bank_saved[bank].both = gpio_bankb[bank]->both; | |
581d62ab | 497 | gpio_bank_saved[bank].reserved = reserved_map[bank]; |
1394f032 BW |
498 | |
499 | gpio = i; | |
500 | ||
501 | while (mask) { | |
502 | if (mask & 1) { | |
581d62ab MH |
503 | reserved_map[gpio_bank(gpio)] |= |
504 | gpio_bit(gpio); | |
505 | bfin_gpio_wakeup_type(gpio, | |
506 | wakeup_flags_map[gpio]); | |
1394f032 BW |
507 | set_gpio_data(gpio, 0); /*Clear*/ |
508 | } | |
509 | gpio++; | |
510 | mask >>= 1; | |
511 | } | |
512 | ||
581d62ab MH |
513 | sic_iwr |= 1 << |
514 | (sic_iwr_irqs[bank] - (IRQ_CORETMR + 1)); | |
1394f032 BW |
515 | gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)]; |
516 | } | |
517 | } | |
518 | ||
519 | if (sic_iwr) | |
520 | return sic_iwr; | |
521 | else | |
522 | return IWR_ENABLE_ALL; | |
523 | } | |
524 | ||
1394f032 BW |
525 | void gpio_pm_restore(void) |
526 | { | |
527 | u16 bank, mask, i; | |
528 | ||
1f83b8f1 | 529 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { |
1394f032 BW |
530 | mask = wakeup_map[gpio_bank(i)]; |
531 | bank = gpio_bank(i); | |
532 | ||
533 | if (mask) { | |
534 | #ifdef BF537_FAMILY | |
535 | *port_fer[bank] = gpio_bank_saved[bank].fer; | |
536 | #endif | |
537 | gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; | |
538 | gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; | |
539 | gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; | |
540 | gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; | |
541 | gpio_bankb[bank]->both = gpio_bank_saved[bank].both; | |
581d62ab MH |
542 | |
543 | reserved_map[bank] = gpio_bank_saved[bank].reserved; | |
544 | ||
1394f032 BW |
545 | } |
546 | ||
547 | gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb; | |
548 | } | |
549 | } | |
550 | ||
551 | #endif | |
552 | ||
553 | /*********************************************************** | |
554 | * | |
555 | * FUNCTIONS: Blackfin GPIO Driver | |
556 | * | |
557 | * INPUTS/OUTPUTS: | |
558 | * gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS | |
559 | * | |
560 | * | |
561 | * DESCRIPTION: Blackfin GPIO Driver API | |
562 | * | |
563 | * CAUTION: | |
564 | ************************************************************* | |
565 | * MODIFICATION HISTORY : | |
566 | **************************************************************/ | |
567 | ||
568 | int gpio_request(unsigned short gpio, const char *label) | |
569 | { | |
570 | unsigned long flags; | |
571 | ||
572 | if (check_gpio(gpio) < 0) | |
573 | return -EINVAL; | |
574 | ||
575 | local_irq_save(flags); | |
576 | ||
577 | if (unlikely(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | |
578 | printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio); | |
579 | dump_stack(); | |
580 | local_irq_restore(flags); | |
581 | return -EBUSY; | |
582 | } | |
583 | reserved_map[gpio_bank(gpio)] |= gpio_bit(gpio); | |
584 | ||
585 | local_irq_restore(flags); | |
586 | ||
587 | port_setup(gpio, GPIO_USAGE); | |
588 | ||
589 | return 0; | |
590 | } | |
591 | EXPORT_SYMBOL(gpio_request); | |
592 | ||
1394f032 BW |
593 | void gpio_free(unsigned short gpio) |
594 | { | |
595 | unsigned long flags; | |
596 | ||
597 | if (check_gpio(gpio) < 0) | |
598 | return; | |
599 | ||
600 | local_irq_save(flags); | |
601 | ||
602 | if (unlikely(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { | |
603 | printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio); | |
604 | dump_stack(); | |
605 | local_irq_restore(flags); | |
606 | return; | |
607 | } | |
608 | ||
609 | default_gpio(gpio); | |
610 | ||
611 | reserved_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); | |
612 | ||
613 | local_irq_restore(flags); | |
614 | } | |
615 | EXPORT_SYMBOL(gpio_free); | |
616 | ||
1394f032 BW |
617 | void gpio_direction_input(unsigned short gpio) |
618 | { | |
619 | unsigned long flags; | |
620 | ||
621 | BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); | |
622 | ||
623 | local_irq_save(flags); | |
624 | gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); | |
625 | gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); | |
626 | local_irq_restore(flags); | |
627 | } | |
628 | EXPORT_SYMBOL(gpio_direction_input); | |
629 | ||
630 | void gpio_direction_output(unsigned short gpio) | |
631 | { | |
632 | unsigned long flags; | |
633 | ||
634 | BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); | |
635 | ||
636 | local_irq_save(flags); | |
637 | gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); | |
638 | gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); | |
639 | local_irq_restore(flags); | |
640 | } | |
641 | EXPORT_SYMBOL(gpio_direction_output); |