diff options
Diffstat (limited to 'arch/blackfin/kernel/bfin_gpio.c')
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 171 |
1 files changed, 116 insertions, 55 deletions
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index ce85d4bf34ca..6bbe0a2fccb8 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Description: GPIO Abstraction Layer | 7 | * Description: GPIO Abstraction Layer |
8 | * | 8 | * |
9 | * Modified: | 9 | * Modified: |
10 | * Copyright 2007 Analog Devices Inc. | 10 | * Copyright 2008 Analog Devices Inc. |
11 | * | 11 | * |
12 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 12 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
13 | * | 13 | * |
@@ -83,6 +83,7 @@ | |||
83 | #include <linux/delay.h> | 83 | #include <linux/delay.h> |
84 | #include <linux/module.h> | 84 | #include <linux/module.h> |
85 | #include <linux/err.h> | 85 | #include <linux/err.h> |
86 | #include <linux/proc_fs.h> | ||
86 | #include <asm/blackfin.h> | 87 | #include <asm/blackfin.h> |
87 | #include <asm/gpio.h> | 88 | #include <asm/gpio.h> |
88 | #include <asm/portmux.h> | 89 | #include <asm/portmux.h> |
@@ -136,7 +137,6 @@ static unsigned short *port_fer[gpio_bank(MAX_BLACKFIN_GPIOS)] = { | |||
136 | (unsigned short *) PORTG_FER, | 137 | (unsigned short *) PORTG_FER, |
137 | (unsigned short *) PORTH_FER, | 138 | (unsigned short *) PORTH_FER, |
138 | }; | 139 | }; |
139 | |||
140 | #endif | 140 | #endif |
141 | 141 | ||
142 | #ifdef BF527_FAMILY | 142 | #ifdef BF527_FAMILY |
@@ -178,15 +178,13 @@ static struct gpio_port_t *gpio_array[gpio_bank(MAX_BLACKFIN_GPIOS)] = { | |||
178 | #endif | 178 | #endif |
179 | 179 | ||
180 | static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 180 | static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
181 | static unsigned short reserved_peri_map[gpio_bank(MAX_BLACKFIN_GPIOS + 16)]; | 181 | static unsigned short reserved_peri_map[gpio_bank(MAX_RESOURCES)]; |
182 | 182 | ||
183 | #define MAX_RESOURCES 256 | ||
184 | #define RESOURCE_LABEL_SIZE 16 | 183 | #define RESOURCE_LABEL_SIZE 16 |
185 | 184 | ||
186 | struct str_ident { | 185 | static struct str_ident { |
187 | char name[RESOURCE_LABEL_SIZE]; | 186 | char name[RESOURCE_LABEL_SIZE]; |
188 | } *str_ident; | 187 | } str_ident[MAX_RESOURCES]; |
189 | |||
190 | 188 | ||
191 | #ifdef CONFIG_PM | 189 | #ifdef CONFIG_PM |
192 | static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 190 | static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
@@ -212,7 +210,7 @@ static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INT | |||
212 | #endif /* CONFIG_PM */ | 210 | #endif /* CONFIG_PM */ |
213 | 211 | ||
214 | #if defined(BF548_FAMILY) | 212 | #if defined(BF548_FAMILY) |
215 | inline int check_gpio(unsigned short gpio) | 213 | inline int check_gpio(unsigned gpio) |
216 | { | 214 | { |
217 | if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 | 215 | if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 |
218 | || gpio == GPIO_PH14 || gpio == GPIO_PH15 | 216 | || gpio == GPIO_PH14 || gpio == GPIO_PH15 |
@@ -222,7 +220,7 @@ inline int check_gpio(unsigned short gpio) | |||
222 | return 0; | 220 | return 0; |
223 | } | 221 | } |
224 | #else | 222 | #else |
225 | inline int check_gpio(unsigned short gpio) | 223 | inline int check_gpio(unsigned gpio) |
226 | { | 224 | { |
227 | if (gpio >= MAX_BLACKFIN_GPIOS) | 225 | if (gpio >= MAX_BLACKFIN_GPIOS) |
228 | return -EINVAL; | 226 | return -EINVAL; |
@@ -230,9 +228,13 @@ inline int check_gpio(unsigned short gpio) | |||
230 | } | 228 | } |
231 | #endif | 229 | #endif |
232 | 230 | ||
233 | static void set_label(unsigned short ident, const char *label) | 231 | void gpio_error(unsigned gpio) |
234 | { | 232 | { |
233 | printk(KERN_ERR "bfin-gpio: GPIO %d wasn't requested!\n", gpio); | ||
234 | } | ||
235 | 235 | ||
236 | static void set_label(unsigned short ident, const char *label) | ||
237 | { | ||
236 | if (label && str_ident) { | 238 | if (label && str_ident) { |
237 | strncpy(str_ident[ident].name, label, | 239 | strncpy(str_ident[ident].name, label, |
238 | RESOURCE_LABEL_SIZE); | 240 | RESOURCE_LABEL_SIZE); |
@@ -250,6 +252,11 @@ static char *get_label(unsigned short ident) | |||
250 | 252 | ||
251 | static int cmp_label(unsigned short ident, const char *label) | 253 | static int cmp_label(unsigned short ident, const char *label) |
252 | { | 254 | { |
255 | if (label == NULL) { | ||
256 | dump_stack(); | ||
257 | printk(KERN_ERR "Please provide none-null label\n"); | ||
258 | } | ||
259 | |||
253 | if (label && str_ident) | 260 | if (label && str_ident) |
254 | return strncmp(str_ident[ident].name, | 261 | return strncmp(str_ident[ident].name, |
255 | label, strlen(label)); | 262 | label, strlen(label)); |
@@ -258,7 +265,7 @@ static int cmp_label(unsigned short ident, const char *label) | |||
258 | } | 265 | } |
259 | 266 | ||
260 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) | 267 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) |
261 | static void port_setup(unsigned short gpio, unsigned short usage) | 268 | static void port_setup(unsigned gpio, unsigned short usage) |
262 | { | 269 | { |
263 | if (!check_gpio(gpio)) { | 270 | if (!check_gpio(gpio)) { |
264 | if (usage == GPIO_USAGE) | 271 | if (usage == GPIO_USAGE) |
@@ -269,7 +276,7 @@ static void port_setup(unsigned short gpio, unsigned short usage) | |||
269 | } | 276 | } |
270 | } | 277 | } |
271 | #elif defined(BF548_FAMILY) | 278 | #elif defined(BF548_FAMILY) |
272 | static void port_setup(unsigned short gpio, unsigned short usage) | 279 | static void port_setup(unsigned gpio, unsigned short usage) |
273 | { | 280 | { |
274 | if (usage == GPIO_USAGE) | 281 | if (usage == GPIO_USAGE) |
275 | gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio); | 282 | gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio); |
@@ -390,7 +397,7 @@ inline void portmux_setup(unsigned short portno, unsigned short function) | |||
390 | #endif | 397 | #endif |
391 | 398 | ||
392 | #ifndef BF548_FAMILY | 399 | #ifndef BF548_FAMILY |
393 | static void default_gpio(unsigned short gpio) | 400 | static void default_gpio(unsigned gpio) |
394 | { | 401 | { |
395 | unsigned short bank, bitmask; | 402 | unsigned short bank, bitmask; |
396 | unsigned long flags; | 403 | unsigned long flags; |
@@ -410,7 +417,6 @@ static void default_gpio(unsigned short gpio) | |||
410 | gpio_bankb[bank]->edge &= ~bitmask; | 417 | gpio_bankb[bank]->edge &= ~bitmask; |
411 | AWA_DUMMY_READ(edge); | 418 | AWA_DUMMY_READ(edge); |
412 | local_irq_restore(flags); | 419 | local_irq_restore(flags); |
413 | |||
414 | } | 420 | } |
415 | #else | 421 | #else |
416 | # define default_gpio(...) do { } while (0) | 422 | # define default_gpio(...) do { } while (0) |
@@ -418,12 +424,6 @@ static void default_gpio(unsigned short gpio) | |||
418 | 424 | ||
419 | static int __init bfin_gpio_init(void) | 425 | static int __init bfin_gpio_init(void) |
420 | { | 426 | { |
421 | str_ident = kcalloc(MAX_RESOURCES, | ||
422 | sizeof(struct str_ident), GFP_KERNEL); | ||
423 | if (str_ident == NULL) | ||
424 | return -ENOMEM; | ||
425 | |||
426 | memset(str_ident, 0, MAX_RESOURCES * sizeof(struct str_ident)); | ||
427 | 427 | ||
428 | printk(KERN_INFO "Blackfin GPIO Controller\n"); | 428 | printk(KERN_INFO "Blackfin GPIO Controller\n"); |
429 | 429 | ||
@@ -454,10 +454,9 @@ arch_initcall(bfin_gpio_init); | |||
454 | /* Set a specific bit */ | 454 | /* Set a specific bit */ |
455 | 455 | ||
456 | #define SET_GPIO(name) \ | 456 | #define SET_GPIO(name) \ |
457 | void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ | 457 | void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ |
458 | { \ | 458 | { \ |
459 | unsigned long flags; \ | 459 | unsigned long flags; \ |
460 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \ | ||
461 | local_irq_save(flags); \ | 460 | local_irq_save(flags); \ |
462 | if (arg) \ | 461 | if (arg) \ |
463 | gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ | 462 | gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ |
@@ -477,10 +476,9 @@ SET_GPIO(both) | |||
477 | 476 | ||
478 | #if ANOMALY_05000311 || ANOMALY_05000323 | 477 | #if ANOMALY_05000311 || ANOMALY_05000323 |
479 | #define SET_GPIO_SC(name) \ | 478 | #define SET_GPIO_SC(name) \ |
480 | void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ | 479 | void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ |
481 | { \ | 480 | { \ |
482 | unsigned long flags; \ | 481 | unsigned long flags; \ |
483 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \ | ||
484 | local_irq_save(flags); \ | 482 | local_irq_save(flags); \ |
485 | if (arg) \ | 483 | if (arg) \ |
486 | gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ | 484 | gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ |
@@ -492,9 +490,8 @@ void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ | |||
492 | EXPORT_SYMBOL(set_gpio_ ## name); | 490 | EXPORT_SYMBOL(set_gpio_ ## name); |
493 | #else | 491 | #else |
494 | #define SET_GPIO_SC(name) \ | 492 | #define SET_GPIO_SC(name) \ |
495 | void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ | 493 | void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ |
496 | { \ | 494 | { \ |
497 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \ | ||
498 | if (arg) \ | 495 | if (arg) \ |
499 | gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ | 496 | gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ |
500 | else \ | 497 | else \ |
@@ -508,19 +505,17 @@ SET_GPIO_SC(maskb) | |||
508 | SET_GPIO_SC(data) | 505 | SET_GPIO_SC(data) |
509 | 506 | ||
510 | #if ANOMALY_05000311 || ANOMALY_05000323 | 507 | #if ANOMALY_05000311 || ANOMALY_05000323 |
511 | void set_gpio_toggle(unsigned short gpio) | 508 | void set_gpio_toggle(unsigned gpio) |
512 | { | 509 | { |
513 | unsigned long flags; | 510 | unsigned long flags; |
514 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); | ||
515 | local_irq_save(flags); | 511 | local_irq_save(flags); |
516 | gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); | 512 | gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); |
517 | AWA_DUMMY_READ(toggle); | 513 | AWA_DUMMY_READ(toggle); |
518 | local_irq_restore(flags); | 514 | local_irq_restore(flags); |
519 | } | 515 | } |
520 | #else | 516 | #else |
521 | void set_gpio_toggle(unsigned short gpio) | 517 | void set_gpio_toggle(unsigned gpio) |
522 | { | 518 | { |
523 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); | ||
524 | gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); | 519 | gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); |
525 | } | 520 | } |
526 | #endif | 521 | #endif |
@@ -531,7 +526,7 @@ EXPORT_SYMBOL(set_gpio_toggle); | |||
531 | 526 | ||
532 | #if ANOMALY_05000311 || ANOMALY_05000323 | 527 | #if ANOMALY_05000311 || ANOMALY_05000323 |
533 | #define SET_GPIO_P(name) \ | 528 | #define SET_GPIO_P(name) \ |
534 | void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ | 529 | void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \ |
535 | { \ | 530 | { \ |
536 | unsigned long flags; \ | 531 | unsigned long flags; \ |
537 | local_irq_save(flags); \ | 532 | local_irq_save(flags); \ |
@@ -542,7 +537,7 @@ void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ | |||
542 | EXPORT_SYMBOL(set_gpiop_ ## name); | 537 | EXPORT_SYMBOL(set_gpiop_ ## name); |
543 | #else | 538 | #else |
544 | #define SET_GPIO_P(name) \ | 539 | #define SET_GPIO_P(name) \ |
545 | void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ | 540 | void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \ |
546 | { \ | 541 | { \ |
547 | gpio_bankb[gpio_bank(gpio)]->name = arg; \ | 542 | gpio_bankb[gpio_bank(gpio)]->name = arg; \ |
548 | } \ | 543 | } \ |
@@ -558,11 +553,10 @@ SET_GPIO_P(both) | |||
558 | SET_GPIO_P(maska) | 553 | SET_GPIO_P(maska) |
559 | SET_GPIO_P(maskb) | 554 | SET_GPIO_P(maskb) |
560 | 555 | ||
561 | |||
562 | /* Get a specific bit */ | 556 | /* Get a specific bit */ |
563 | #if ANOMALY_05000311 || ANOMALY_05000323 | 557 | #if ANOMALY_05000311 || ANOMALY_05000323 |
564 | #define GET_GPIO(name) \ | 558 | #define GET_GPIO(name) \ |
565 | unsigned short get_gpio_ ## name(unsigned short gpio) \ | 559 | unsigned short get_gpio_ ## name(unsigned gpio) \ |
566 | { \ | 560 | { \ |
567 | unsigned long flags; \ | 561 | unsigned long flags; \ |
568 | unsigned short ret; \ | 562 | unsigned short ret; \ |
@@ -575,7 +569,7 @@ unsigned short get_gpio_ ## name(unsigned short gpio) \ | |||
575 | EXPORT_SYMBOL(get_gpio_ ## name); | 569 | EXPORT_SYMBOL(get_gpio_ ## name); |
576 | #else | 570 | #else |
577 | #define GET_GPIO(name) \ | 571 | #define GET_GPIO(name) \ |
578 | unsigned short get_gpio_ ## name(unsigned short gpio) \ | 572 | unsigned short get_gpio_ ## name(unsigned gpio) \ |
579 | { \ | 573 | { \ |
580 | return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ | 574 | return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ |
581 | } \ | 575 | } \ |
@@ -595,7 +589,7 @@ GET_GPIO(maskb) | |||
595 | 589 | ||
596 | #if ANOMALY_05000311 || ANOMALY_05000323 | 590 | #if ANOMALY_05000311 || ANOMALY_05000323 |
597 | #define GET_GPIO_P(name) \ | 591 | #define GET_GPIO_P(name) \ |
598 | unsigned short get_gpiop_ ## name(unsigned short gpio) \ | 592 | unsigned short get_gpiop_ ## name(unsigned gpio) \ |
599 | { \ | 593 | { \ |
600 | unsigned long flags; \ | 594 | unsigned long flags; \ |
601 | unsigned short ret; \ | 595 | unsigned short ret; \ |
@@ -608,7 +602,7 @@ unsigned short get_gpiop_ ## name(unsigned short gpio) \ | |||
608 | EXPORT_SYMBOL(get_gpiop_ ## name); | 602 | EXPORT_SYMBOL(get_gpiop_ ## name); |
609 | #else | 603 | #else |
610 | #define GET_GPIO_P(name) \ | 604 | #define GET_GPIO_P(name) \ |
611 | unsigned short get_gpiop_ ## name(unsigned short gpio) \ | 605 | unsigned short get_gpiop_ ## name(unsigned gpio) \ |
612 | { \ | 606 | { \ |
613 | return (gpio_bankb[gpio_bank(gpio)]->name);\ | 607 | return (gpio_bankb[gpio_bank(gpio)]->name);\ |
614 | } \ | 608 | } \ |
@@ -645,7 +639,7 @@ GET_GPIO_P(maskb) | |||
645 | ************************************************************* | 639 | ************************************************************* |
646 | * MODIFICATION HISTORY : | 640 | * MODIFICATION HISTORY : |
647 | **************************************************************/ | 641 | **************************************************************/ |
648 | int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type) | 642 | int gpio_pm_wakeup_request(unsigned gpio, unsigned char type) |
649 | { | 643 | { |
650 | unsigned long flags; | 644 | unsigned long flags; |
651 | 645 | ||
@@ -653,7 +647,6 @@ int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type) | |||
653 | return -EINVAL; | 647 | return -EINVAL; |
654 | 648 | ||
655 | local_irq_save(flags); | 649 | local_irq_save(flags); |
656 | |||
657 | wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); | 650 | wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); |
658 | wakeup_flags_map[gpio] = type; | 651 | wakeup_flags_map[gpio] = type; |
659 | local_irq_restore(flags); | 652 | local_irq_restore(flags); |
@@ -662,7 +655,7 @@ int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type) | |||
662 | } | 655 | } |
663 | EXPORT_SYMBOL(gpio_pm_wakeup_request); | 656 | EXPORT_SYMBOL(gpio_pm_wakeup_request); |
664 | 657 | ||
665 | void gpio_pm_wakeup_free(unsigned short gpio) | 658 | void gpio_pm_wakeup_free(unsigned gpio) |
666 | { | 659 | { |
667 | unsigned long flags; | 660 | unsigned long flags; |
668 | 661 | ||
@@ -677,7 +670,7 @@ void gpio_pm_wakeup_free(unsigned short gpio) | |||
677 | } | 670 | } |
678 | EXPORT_SYMBOL(gpio_pm_wakeup_free); | 671 | EXPORT_SYMBOL(gpio_pm_wakeup_free); |
679 | 672 | ||
680 | static int bfin_gpio_wakeup_type(unsigned short gpio, unsigned char type) | 673 | static int bfin_gpio_wakeup_type(unsigned gpio, unsigned char type) |
681 | { | 674 | { |
682 | port_setup(gpio, GPIO_USAGE); | 675 | port_setup(gpio, GPIO_USAGE); |
683 | set_gpio_dir(gpio, 0); | 676 | set_gpio_dir(gpio, 0); |
@@ -784,6 +777,14 @@ void gpio_pm_restore(void) | |||
784 | } | 777 | } |
785 | 778 | ||
786 | #endif | 779 | #endif |
780 | #else /* BF548_FAMILY */ | ||
781 | |||
782 | unsigned short get_gpio_dir(unsigned gpio) | ||
783 | { | ||
784 | return (0x01 & (gpio_array[gpio_bank(gpio)]->port_dir_clear >> gpio_sub_n(gpio))); | ||
785 | } | ||
786 | EXPORT_SYMBOL(get_gpio_dir); | ||
787 | |||
787 | #endif /* BF548_FAMILY */ | 788 | #endif /* BF548_FAMILY */ |
788 | 789 | ||
789 | /*********************************************************** | 790 | /*********************************************************** |
@@ -1028,7 +1029,7 @@ EXPORT_SYMBOL(peripheral_free_list); | |||
1028 | * MODIFICATION HISTORY : | 1029 | * MODIFICATION HISTORY : |
1029 | **************************************************************/ | 1030 | **************************************************************/ |
1030 | 1031 | ||
1031 | int gpio_request(unsigned short gpio, const char *label) | 1032 | int gpio_request(unsigned gpio, const char *label) |
1032 | { | 1033 | { |
1033 | unsigned long flags; | 1034 | unsigned long flags; |
1034 | 1035 | ||
@@ -1075,7 +1076,7 @@ int gpio_request(unsigned short gpio, const char *label) | |||
1075 | } | 1076 | } |
1076 | EXPORT_SYMBOL(gpio_request); | 1077 | EXPORT_SYMBOL(gpio_request); |
1077 | 1078 | ||
1078 | void gpio_free(unsigned short gpio) | 1079 | void gpio_free(unsigned gpio) |
1079 | { | 1080 | { |
1080 | unsigned long flags; | 1081 | unsigned long flags; |
1081 | 1082 | ||
@@ -1085,7 +1086,7 @@ void gpio_free(unsigned short gpio) | |||
1085 | local_irq_save(flags); | 1086 | local_irq_save(flags); |
1086 | 1087 | ||
1087 | if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { | 1088 | if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { |
1088 | printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio); | 1089 | gpio_error(gpio); |
1089 | dump_stack(); | 1090 | dump_stack(); |
1090 | local_irq_restore(flags); | 1091 | local_irq_restore(flags); |
1091 | return; | 1092 | return; |
@@ -1101,44 +1102,55 @@ void gpio_free(unsigned short gpio) | |||
1101 | } | 1102 | } |
1102 | EXPORT_SYMBOL(gpio_free); | 1103 | EXPORT_SYMBOL(gpio_free); |
1103 | 1104 | ||
1105 | |||
1104 | #ifdef BF548_FAMILY | 1106 | #ifdef BF548_FAMILY |
1105 | void gpio_direction_input(unsigned short gpio) | 1107 | int gpio_direction_input(unsigned gpio) |
1106 | { | 1108 | { |
1107 | unsigned long flags; | 1109 | unsigned long flags; |
1108 | 1110 | ||
1109 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); | 1111 | if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { |
1112 | gpio_error(gpio); | ||
1113 | return -EINVAL; | ||
1114 | } | ||
1110 | 1115 | ||
1111 | local_irq_save(flags); | 1116 | local_irq_save(flags); |
1112 | gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio); | 1117 | gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio); |
1113 | gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio); | 1118 | gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio); |
1114 | local_irq_restore(flags); | 1119 | local_irq_restore(flags); |
1120 | |||
1121 | return 0; | ||
1115 | } | 1122 | } |
1116 | EXPORT_SYMBOL(gpio_direction_input); | 1123 | EXPORT_SYMBOL(gpio_direction_input); |
1117 | 1124 | ||
1118 | void gpio_direction_output(unsigned short gpio) | 1125 | int gpio_direction_output(unsigned gpio, int value) |
1119 | { | 1126 | { |
1120 | unsigned long flags; | 1127 | unsigned long flags; |
1121 | 1128 | ||
1122 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); | 1129 | if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { |
1130 | gpio_error(gpio); | ||
1131 | return -EINVAL; | ||
1132 | } | ||
1123 | 1133 | ||
1124 | local_irq_save(flags); | 1134 | local_irq_save(flags); |
1125 | gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio); | 1135 | gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio); |
1136 | gpio_set_value(gpio, value); | ||
1126 | gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio); | 1137 | gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio); |
1127 | local_irq_restore(flags); | 1138 | local_irq_restore(flags); |
1139 | |||
1140 | return 0; | ||
1128 | } | 1141 | } |
1129 | EXPORT_SYMBOL(gpio_direction_output); | 1142 | EXPORT_SYMBOL(gpio_direction_output); |
1130 | 1143 | ||
1131 | void gpio_set_value(unsigned short gpio, unsigned short arg) | 1144 | void gpio_set_value(unsigned gpio, int arg) |
1132 | { | 1145 | { |
1133 | if (arg) | 1146 | if (arg) |
1134 | gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio); | 1147 | gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio); |
1135 | else | 1148 | else |
1136 | gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio); | 1149 | gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio); |
1137 | |||
1138 | } | 1150 | } |
1139 | EXPORT_SYMBOL(gpio_set_value); | 1151 | EXPORT_SYMBOL(gpio_set_value); |
1140 | 1152 | ||
1141 | unsigned short gpio_get_value(unsigned short gpio) | 1153 | int gpio_get_value(unsigned gpio) |
1142 | { | 1154 | { |
1143 | return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio))); | 1155 | return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio))); |
1144 | } | 1156 | } |
@@ -1146,31 +1158,47 @@ EXPORT_SYMBOL(gpio_get_value); | |||
1146 | 1158 | ||
1147 | #else | 1159 | #else |
1148 | 1160 | ||
1149 | void gpio_direction_input(unsigned short gpio) | 1161 | int gpio_direction_input(unsigned gpio) |
1150 | { | 1162 | { |
1151 | unsigned long flags; | 1163 | unsigned long flags; |
1152 | 1164 | ||
1153 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); | 1165 | if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { |
1166 | gpio_error(gpio); | ||
1167 | return -EINVAL; | ||
1168 | } | ||
1154 | 1169 | ||
1155 | local_irq_save(flags); | 1170 | local_irq_save(flags); |
1156 | gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); | 1171 | gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); |
1157 | gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); | 1172 | gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); |
1158 | AWA_DUMMY_READ(inen); | 1173 | AWA_DUMMY_READ(inen); |
1159 | local_irq_restore(flags); | 1174 | local_irq_restore(flags); |
1175 | |||
1176 | return 0; | ||
1160 | } | 1177 | } |
1161 | EXPORT_SYMBOL(gpio_direction_input); | 1178 | EXPORT_SYMBOL(gpio_direction_input); |
1162 | 1179 | ||
1163 | void gpio_direction_output(unsigned short gpio) | 1180 | int gpio_direction_output(unsigned gpio, int value) |
1164 | { | 1181 | { |
1165 | unsigned long flags; | 1182 | unsigned long flags; |
1166 | 1183 | ||
1167 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); | 1184 | if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { |
1185 | gpio_error(gpio); | ||
1186 | return -EINVAL; | ||
1187 | } | ||
1168 | 1188 | ||
1169 | local_irq_save(flags); | 1189 | local_irq_save(flags); |
1170 | gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); | 1190 | gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); |
1191 | |||
1192 | if (value) | ||
1193 | gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); | ||
1194 | else | ||
1195 | gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); | ||
1196 | |||
1171 | gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); | 1197 | gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); |
1172 | AWA_DUMMY_READ(dir); | 1198 | AWA_DUMMY_READ(dir); |
1173 | local_irq_restore(flags); | 1199 | local_irq_restore(flags); |
1200 | |||
1201 | return 0; | ||
1174 | } | 1202 | } |
1175 | EXPORT_SYMBOL(gpio_direction_output); | 1203 | EXPORT_SYMBOL(gpio_direction_output); |
1176 | 1204 | ||
@@ -1190,7 +1218,40 @@ void bfin_gpio_reset_spi0_ssel1(void) | |||
1190 | 1218 | ||
1191 | port_setup(gpio, GPIO_USAGE); | 1219 | port_setup(gpio, GPIO_USAGE); |
1192 | gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); | 1220 | gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); |
1221 | AWA_DUMMY_READ(data_set); | ||
1193 | udelay(1); | 1222 | udelay(1); |
1194 | } | 1223 | } |
1195 | 1224 | ||
1196 | #endif /*BF548_FAMILY */ | 1225 | #endif /*BF548_FAMILY */ |
1226 | |||
1227 | #if defined(CONFIG_PROC_FS) | ||
1228 | static int gpio_proc_read(char *buf, char **start, off_t offset, | ||
1229 | int len, int *unused_i, void *unused_v) | ||
1230 | { | ||
1231 | int c, outlen = 0; | ||
1232 | |||
1233 | for (c = 0; c < MAX_RESOURCES; c++) { | ||
1234 | if (!check_gpio(c) && (reserved_gpio_map[gpio_bank(c)] & gpio_bit(c))) | ||
1235 | len = sprintf(buf, "GPIO_%d: %s \t\tGPIO %s\n", c, | ||
1236 | get_label(c), get_gpio_dir(c) ? "OUTPUT" : "INPUT"); | ||
1237 | else if (reserved_peri_map[gpio_bank(c)] & gpio_bit(c)) | ||
1238 | len = sprintf(buf, "GPIO_%d: %s \t\tPeripheral\n", c, get_label(c)); | ||
1239 | else | ||
1240 | continue; | ||
1241 | buf += len; | ||
1242 | outlen += len; | ||
1243 | } | ||
1244 | return outlen; | ||
1245 | } | ||
1246 | |||
1247 | static __init int gpio_register_proc(void) | ||
1248 | { | ||
1249 | struct proc_dir_entry *proc_gpio; | ||
1250 | |||
1251 | proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL); | ||
1252 | if (proc_gpio) | ||
1253 | proc_gpio->read_proc = gpio_proc_read; | ||
1254 | return proc_gpio != NULL; | ||
1255 | } | ||
1256 | __initcall(gpio_register_proc); | ||
1257 | #endif | ||