aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/bfin_gpio.c
diff options
context:
space:
mode:
authorBryan Wu <bryan.wu@analog.com>2007-05-06 17:50:22 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-07 15:12:58 -0400
commit1394f03221790a988afc3e4b3cb79f2e477246a9 (patch)
tree2c1963c9a4f2d84a5e021307fde240c5d567cf70 /arch/blackfin/kernel/bfin_gpio.c
parent73243284463a761e04d69d22c7516b2be7de096c (diff)
blackfin architecture
This adds support for the Analog Devices Blackfin processor architecture, and currently supports the BF533, BF532, BF531, BF537, BF536, BF534, and BF561 (Dual Core) devices, with a variety of development platforms including those avaliable from Analog Devices (BF533-EZKit, BF533-STAMP, BF537-STAMP, BF561-EZKIT), and Bluetechnix! Tinyboards. The Blackfin architecture was jointly developed by Intel and Analog Devices Inc. (ADI) as the Micro Signal Architecture (MSA) core and introduced it in December of 2000. Since then ADI has put this core into its Blackfin processor family of devices. The Blackfin core has the advantages of a clean, orthogonal,RISC-like microprocessor instruction set. It combines a dual-MAC (Multiply/Accumulate), state-of-the-art signal processing engine and single-instruction, multiple-data (SIMD) multimedia capabilities into a single instruction-set architecture. The Blackfin architecture, including the instruction set, is described by the ADSP-BF53x/BF56x Blackfin Processor Programming Reference http://blackfin.uclinux.org/gf/download/frsrelease/29/2549/Blackfin_PRM.pdf The Blackfin processor is already supported by major releases of gcc, and there are binary and source rpms/tarballs for many architectures at: http://blackfin.uclinux.org/gf/project/toolchain/frs There is complete documentation, including "getting started" guides available at: http://docs.blackfin.uclinux.org/ which provides links to the sources and patches you will need in order to set up a cross-compiling environment for bfin-linux-uclibc This patch, as well as the other patches (toolchain, distribution, uClibc) are actively supported by Analog Devices Inc, at: http://blackfin.uclinux.org/ We have tested this on LTP, and our test plan (including pass/fails) can be found at: http://docs.blackfin.uclinux.org/doku.php?id=testing_the_linux_kernel [m.kozlowski@tuxland.pl: balance parenthesis in blackfin header files] Signed-off-by: Bryan Wu <bryan.wu@analog.com> Signed-off-by: Mariusz Kozlowski <m.kozlowski@tuxland.pl> Signed-off-by: Aubrey Li <aubrey.li@analog.com> Signed-off-by: Jie Zhang <jie.zhang@analog.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/blackfin/kernel/bfin_gpio.c')
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c637
1 files changed, 637 insertions, 0 deletions
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
new file mode 100644
index 00000000000..e9f24a9a46b
--- /dev/null
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -0,0 +1,637 @@
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
90static 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
96static 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
102static 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
111static 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
118static unsigned short reserved_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
119
120#ifdef CONFIG_PM
121static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
122static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS];
123static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)];
124
125#ifdef BF533_FAMILY
126static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB};
127#endif
128
129#ifdef BF537_FAMILY
130static 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
134static 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
139inline int check_gpio(unsigned short gpio)
140{
141 if (gpio > MAX_BLACKFIN_GPIOS)
142 return -EINVAL;
143 return 0;
144}
145
146#ifdef BF537_FAMILY
147void port_setup(unsigned short gpio, unsigned short usage)
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
163void default_gpio(unsigned short gpio)
164{
165 unsigned short bank,bitmask;
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
180
181int __init bfin_gpio_init(void)
182{
183 int i;
184
185 printk(KERN_INFO "Blackfin GPIO Controller\n");
186
187 for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE)
188 reserved_map[gpio_bank(i)] = 0;
189
190#if defined(BF537_FAMILY) && (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
191# if defined(CONFIG_BFIN_MAC_RMII)
192 reserved_map[PORT_H] = 0xC373;
193# else
194 reserved_map[PORT_H] = 0xFFFF;
195# endif
196#endif
197
198 return 0;
199}
200
201arch_initcall(bfin_gpio_init);
202
203
204/***********************************************************
205*
206* FUNCTIONS: Blackfin General Purpose Ports Access Functions
207*
208* INPUTS/OUTPUTS:
209* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
210*
211*
212* DESCRIPTION: These functions abstract direct register access
213* to Blackfin processor General Purpose
214* Ports Regsiters
215*
216* CAUTION: These functions do not belong to the GPIO Driver API
217*************************************************************
218* MODIFICATION HISTORY :
219**************************************************************/
220
221/* Set a specific bit */
222
223#define SET_GPIO(name) \
224void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
225{ \
226 unsigned long flags; \
227 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
228 local_irq_save(flags); \
229 if (arg) \
230 gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
231 else \
232 gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \
233 local_irq_restore(flags); \
234} \
235EXPORT_SYMBOL(set_gpio_ ## name);
236
237SET_GPIO(dir)
238SET_GPIO(inen)
239SET_GPIO(polar)
240SET_GPIO(edge)
241SET_GPIO(both)
242
243
244#define SET_GPIO_SC(name) \
245void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
246{ \
247 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
248 if (arg) \
249 gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
250 else \
251 gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
252} \
253EXPORT_SYMBOL(set_gpio_ ## name);
254
255SET_GPIO_SC(maska)
256SET_GPIO_SC(maskb)
257
258#if defined(ANOMALY_05000311)
259void set_gpio_data(unsigned short gpio, unsigned short arg)
260{
261 unsigned long flags;
262 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
263 local_irq_save(flags);
264 if (arg)
265 gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
266 else
267 gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
268 bfin_read_CHIPID();
269 local_irq_restore(flags);
270}
271EXPORT_SYMBOL(set_gpio_data);
272#else
273SET_GPIO_SC(data)
274#endif
275
276
277#if defined(ANOMALY_05000311)
278void set_gpio_toggle(unsigned short gpio)
279{
280 unsigned long flags;
281 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
282 local_irq_save(flags);
283 gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
284 bfin_read_CHIPID();
285 local_irq_restore(flags);
286}
287#else
288void set_gpio_toggle(unsigned short gpio)
289{
290 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
291 gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
292}
293#endif
294EXPORT_SYMBOL(set_gpio_toggle);
295
296
297/*Set current PORT date (16-bit word)*/
298
299#define SET_GPIO_P(name) \
300void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \
301{ \
302 gpio_bankb[gpio_bank(gpio)]->name = arg; \
303} \
304EXPORT_SYMBOL(set_gpiop_ ## name);
305
306SET_GPIO_P(dir)
307SET_GPIO_P(inen)
308SET_GPIO_P(polar)
309SET_GPIO_P(edge)
310SET_GPIO_P(both)
311SET_GPIO_P(maska)
312SET_GPIO_P(maskb)
313
314
315#if defined(ANOMALY_05000311)
316void set_gpiop_data(unsigned short gpio, unsigned short arg)
317{
318 unsigned long flags;
319 local_irq_save(flags);
320 gpio_bankb[gpio_bank(gpio)]->data = arg;
321 bfin_read_CHIPID();
322 local_irq_restore(flags);
323}
324EXPORT_SYMBOL(set_gpiop_data);
325#else
326SET_GPIO_P(data)
327#endif
328
329
330
331/* Get a specific bit */
332
333#define GET_GPIO(name) \
334unsigned short get_gpio_ ## name(unsigned short gpio) \
335{ \
336 return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \
337} \
338EXPORT_SYMBOL(get_gpio_ ## name);
339
340GET_GPIO(dir)
341GET_GPIO(inen)
342GET_GPIO(polar)
343GET_GPIO(edge)
344GET_GPIO(both)
345GET_GPIO(maska)
346GET_GPIO(maskb)
347
348
349#if defined(ANOMALY_05000311)
350unsigned short get_gpio_data(unsigned short gpio)
351{
352 unsigned long flags;
353 unsigned short ret;
354 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
355 local_irq_save(flags);
356 ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->data >> gpio_sub_n(gpio));
357 bfin_read_CHIPID();
358 local_irq_restore(flags);
359 return ret;
360}
361EXPORT_SYMBOL(get_gpio_data);
362#else
363GET_GPIO(data)
364#endif
365
366/*Get current PORT date (16-bit word)*/
367
368#define GET_GPIO_P(name) \
369unsigned short get_gpiop_ ## name(unsigned short gpio) \
370{ \
371 return (gpio_bankb[gpio_bank(gpio)]->name);\
372} \
373EXPORT_SYMBOL(get_gpiop_ ## name);
374
375GET_GPIO_P(dir)
376GET_GPIO_P(inen)
377GET_GPIO_P(polar)
378GET_GPIO_P(edge)
379GET_GPIO_P(both)
380GET_GPIO_P(maska)
381GET_GPIO_P(maskb)
382
383#if defined(ANOMALY_05000311)
384unsigned short get_gpiop_data(unsigned short gpio)
385{
386 unsigned long flags;
387 unsigned short ret;
388 local_irq_save(flags);
389 ret = gpio_bankb[gpio_bank(gpio)]->data;
390 bfin_read_CHIPID();
391 local_irq_restore(flags);
392 return ret;
393}
394EXPORT_SYMBOL(get_gpiop_data);
395#else
396GET_GPIO_P(data)
397#endif
398
399#ifdef CONFIG_PM
400/***********************************************************
401*
402* FUNCTIONS: Blackfin PM Setup API
403*
404* INPUTS/OUTPUTS:
405* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
406* type -
407* PM_WAKE_RISING
408* PM_WAKE_FALLING
409* PM_WAKE_HIGH
410* PM_WAKE_LOW
411* PM_WAKE_BOTH_EDGES
412*
413* DESCRIPTION: Blackfin PM Driver API
414*
415* CAUTION:
416*************************************************************
417* MODIFICATION HISTORY :
418**************************************************************/
419int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type)
420{
421 unsigned long flags;
422
423 if ((check_gpio(gpio) < 0) || !type)
424 return -EINVAL;
425
426 local_irq_save(flags);
427
428 wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio);
429 wakeup_flags_map[gpio] = type;
430 local_irq_restore(flags);
431
432 return 0;
433}
434EXPORT_SYMBOL(gpio_pm_wakeup_request);
435
436void gpio_pm_wakeup_free(unsigned short gpio)
437{
438 unsigned long flags;
439
440 if (check_gpio(gpio) < 0)
441 return;
442
443 local_irq_save(flags);
444
445 wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
446
447 local_irq_restore(flags);
448}
449EXPORT_SYMBOL(gpio_pm_wakeup_free);
450
451static int bfin_gpio_wakeup_type(unsigned short gpio, unsigned char type)
452{
453 port_setup(gpio, GPIO_USAGE);
454 set_gpio_dir(gpio, 0);
455 set_gpio_inen(gpio, 1);
456
457 if (type & (PM_WAKE_RISING | PM_WAKE_FALLING))
458 set_gpio_edge(gpio, 1);
459 else
460 set_gpio_edge(gpio, 0);
461
462 if ((type & (PM_WAKE_BOTH_EDGES)) == (PM_WAKE_BOTH_EDGES))
463 set_gpio_both(gpio, 1);
464 else
465 set_gpio_both(gpio, 0);
466
467 if ((type & (PM_WAKE_FALLING | PM_WAKE_LOW)))
468 set_gpio_polar(gpio, 1);
469 else
470 set_gpio_polar(gpio, 0);
471
472 SSYNC();
473
474 return 0;
475}
476
477u32 gpio_pm_setup(void)
478{
479 u32 sic_iwr = 0;
480 u16 bank, mask, i, gpio;
481
482 for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) {
483 mask = wakeup_map[gpio_bank(i)];
484 bank = gpio_bank(i);
485
486 gpio_bank_saved[bank].maskb = gpio_bankb[bank]->maskb;
487 gpio_bankb[bank]->maskb = 0;
488
489 if (mask) {
490#ifdef BF537_FAMILY
491 gpio_bank_saved[bank].fer = *port_fer[bank];
492#endif
493 gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen;
494 gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar;
495 gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir;
496 gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge;
497 gpio_bank_saved[bank].both = gpio_bankb[bank]->both;
498
499 gpio = i;
500
501 while (mask) {
502 if (mask & 1) {
503 bfin_gpio_wakeup_type(gpio, wakeup_flags_map[gpio]);
504 set_gpio_data(gpio, 0); /*Clear*/
505 }
506 gpio++;
507 mask >>= 1;
508 }
509
510 sic_iwr |= 1 << (sic_iwr_irqs[bank] - (IRQ_CORETMR + 1));
511 gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)];
512 }
513 }
514
515 if (sic_iwr)
516 return sic_iwr;
517 else
518 return IWR_ENABLE_ALL;
519}
520
521
522void gpio_pm_restore(void)
523{
524 u16 bank, mask, i;
525
526 for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) {
527 mask = wakeup_map[gpio_bank(i)];
528 bank = gpio_bank(i);
529
530 if (mask) {
531#ifdef BF537_FAMILY
532 *port_fer[bank] = gpio_bank_saved[bank].fer;
533#endif
534 gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen;
535 gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir;
536 gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar;
537 gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge;
538 gpio_bankb[bank]->both = gpio_bank_saved[bank].both;
539 }
540
541 gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb;
542 }
543}
544
545#endif
546
547/***********************************************************
548*
549* FUNCTIONS: Blackfin GPIO Driver
550*
551* INPUTS/OUTPUTS:
552* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
553*
554*
555* DESCRIPTION: Blackfin GPIO Driver API
556*
557* CAUTION:
558*************************************************************
559* MODIFICATION HISTORY :
560**************************************************************/
561
562int gpio_request(unsigned short gpio, const char *label)
563{
564 unsigned long flags;
565
566 if (check_gpio(gpio) < 0)
567 return -EINVAL;
568
569 local_irq_save(flags);
570
571 if (unlikely(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
572 printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio);
573 dump_stack();
574 local_irq_restore(flags);
575 return -EBUSY;
576 }
577 reserved_map[gpio_bank(gpio)] |= gpio_bit(gpio);
578
579 local_irq_restore(flags);
580
581 port_setup(gpio, GPIO_USAGE);
582
583 return 0;
584}
585EXPORT_SYMBOL(gpio_request);
586
587
588void gpio_free(unsigned short gpio)
589{
590 unsigned long flags;
591
592 if (check_gpio(gpio) < 0)
593 return;
594
595 local_irq_save(flags);
596
597 if (unlikely(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
598 printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio);
599 dump_stack();
600 local_irq_restore(flags);
601 return;
602 }
603
604 default_gpio(gpio);
605
606 reserved_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
607
608 local_irq_restore(flags);
609}
610EXPORT_SYMBOL(gpio_free);
611
612
613void gpio_direction_input(unsigned short gpio)
614{
615 unsigned long flags;
616
617 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
618
619 local_irq_save(flags);
620 gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
621 gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
622 local_irq_restore(flags);
623}
624EXPORT_SYMBOL(gpio_direction_input);
625
626void gpio_direction_output(unsigned short gpio)
627{
628 unsigned long flags;
629
630 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
631
632 local_irq_save(flags);
633 gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
634 gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
635 local_irq_restore(flags);
636}
637EXPORT_SYMBOL(gpio_direction_output);