Commit 332824b8353be3606a7d0bef2451fc85e803cab1
1 parent
74181295fb
Exists in
master
and in
4 other branches
Blackfin: gpio: unify & clean up reserved map handling
The duplicated bit banging logic is getting out of hand, so unify the local API to make management a lot easier. This also makes the code a lot easier to follow. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Showing 1 changed file with 56 additions and 51 deletions Side-by-side Diff
arch/blackfin/kernel/bfin_gpio.c
... | ... | @@ -108,10 +108,6 @@ |
108 | 108 | }; |
109 | 109 | #endif |
110 | 110 | |
111 | -static unsigned short reserved_gpio_map[GPIO_BANK_NUM]; | |
112 | -static unsigned short reserved_peri_map[gpio_bank(MAX_RESOURCES)]; | |
113 | -static unsigned short reserved_gpio_irq_map[GPIO_BANK_NUM]; | |
114 | - | |
115 | 111 | #define RESOURCE_LABEL_SIZE 16 |
116 | 112 | |
117 | 113 | static struct str_ident { |
... | ... | @@ -122,19 +118,6 @@ |
122 | 118 | static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; |
123 | 119 | #endif |
124 | 120 | |
125 | -inline int check_gpio(unsigned gpio) | |
126 | -{ | |
127 | -#if defined(CONFIG_BF54x) | |
128 | - if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 | |
129 | - || gpio == GPIO_PH14 || gpio == GPIO_PH15 | |
130 | - || gpio == GPIO_PJ14 || gpio == GPIO_PJ15) | |
131 | - return -EINVAL; | |
132 | -#endif | |
133 | - if (gpio >= MAX_BLACKFIN_GPIOS) | |
134 | - return -EINVAL; | |
135 | - return 0; | |
136 | -} | |
137 | - | |
138 | 121 | static void gpio_error(unsigned gpio) |
139 | 122 | { |
140 | 123 | printk(KERN_ERR "bfin-gpio: GPIO %d wasn't requested!\n", gpio); |
... | ... | @@ -167,6 +150,29 @@ |
167 | 150 | return -EINVAL; |
168 | 151 | } |
169 | 152 | |
153 | +#define map_entry(m, i) reserved_##m##_map[gpio_bank(i)] | |
154 | +#define is_reserved(m, i, e) (map_entry(m, i) & gpio_bit(i)) | |
155 | +#define reserve(m, i) (map_entry(m, i) |= gpio_bit(i)) | |
156 | +#define unreserve(m, i) (map_entry(m, i) &= ~gpio_bit(i)) | |
157 | +#define DECLARE_RESERVED_MAP(m, c) static unsigned short reserved_##m##_map[c] | |
158 | + | |
159 | +DECLARE_RESERVED_MAP(gpio, GPIO_BANK_NUM); | |
160 | +DECLARE_RESERVED_MAP(peri, gpio_bank(MAX_RESOURCES)); | |
161 | +DECLARE_RESERVED_MAP(gpio_irq, GPIO_BANK_NUM); | |
162 | + | |
163 | +inline int check_gpio(unsigned gpio) | |
164 | +{ | |
165 | +#if defined(CONFIG_BF54x) | |
166 | + if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 | |
167 | + || gpio == GPIO_PH14 || gpio == GPIO_PH15 | |
168 | + || gpio == GPIO_PJ14 || gpio == GPIO_PJ15) | |
169 | + return -EINVAL; | |
170 | +#endif | |
171 | + if (gpio >= MAX_BLACKFIN_GPIOS) | |
172 | + return -EINVAL; | |
173 | + return 0; | |
174 | +} | |
175 | + | |
170 | 176 | static void port_setup(unsigned gpio, unsigned short usage) |
171 | 177 | { |
172 | 178 | #if defined(BF538_FAMILY) |
... | ... | @@ -475,7 +481,7 @@ |
475 | 481 | |
476 | 482 | |
477 | 483 | #ifdef CONFIG_PM |
478 | -static unsigned short wakeup_map[GPIO_BANK_NUM]; | |
484 | +DECLARE_RESERVED_MAP(wakeup, GPIO_BANK_NUM); | |
479 | 485 | |
480 | 486 | static const unsigned int sic_iwr_irqs[] = { |
481 | 487 | #if defined(BF533_FAMILY) |
482 | 488 | |
... | ... | @@ -521,9 +527,9 @@ |
521 | 527 | |
522 | 528 | local_irq_save_hw(flags); |
523 | 529 | if (ctrl) |
524 | - wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); | |
530 | + reserve(wakeup, gpio); | |
525 | 531 | else |
526 | - wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); | |
532 | + unreserve(wakeup, gpio); | |
527 | 533 | |
528 | 534 | set_gpio_maskb(gpio, ctrl); |
529 | 535 | local_irq_restore_hw(flags); |
... | ... | @@ -536,7 +542,7 @@ |
536 | 542 | u16 bank, mask, i; |
537 | 543 | |
538 | 544 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { |
539 | - mask = wakeup_map[gpio_bank(i)]; | |
545 | + mask = map_entry(wakeup, i); | |
540 | 546 | bank = gpio_bank(i); |
541 | 547 | |
542 | 548 | if (mask) |
... | ... | @@ -689,8 +695,7 @@ |
689 | 695 | /* If a pin can be muxed as either GPIO or peripheral, make |
690 | 696 | * sure it is not already a GPIO pin when we request it. |
691 | 697 | */ |
692 | - if (unlikely(!check_gpio(ident) && | |
693 | - reserved_gpio_map[gpio_bank(ident)] & gpio_bit(ident))) { | |
698 | + if (unlikely(!check_gpio(ident) && is_reserved(gpio, ident, 1))) { | |
694 | 699 | if (system_state == SYSTEM_BOOTING) |
695 | 700 | dump_stack(); |
696 | 701 | printk(KERN_ERR |
... | ... | @@ -700,7 +705,7 @@ |
700 | 705 | return -EBUSY; |
701 | 706 | } |
702 | 707 | |
703 | - if (unlikely(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident))) { | |
708 | + if (unlikely(is_reserved(peri, ident, 1))) { | |
704 | 709 | |
705 | 710 | /* |
706 | 711 | * Pin functions like AMC address strobes my |
... | ... | @@ -731,7 +736,7 @@ |
731 | 736 | } |
732 | 737 | |
733 | 738 | anyway: |
734 | - reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident); | |
739 | + reserve(peri, ident); | |
735 | 740 | |
736 | 741 | portmux_setup(per); |
737 | 742 | port_setup(ident, PERIPHERAL_USAGE); |
... | ... | @@ -777,7 +782,7 @@ |
777 | 782 | |
778 | 783 | local_irq_save_hw(flags); |
779 | 784 | |
780 | - if (unlikely(!(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident)))) { | |
785 | + if (unlikely(!is_reserved(peri, ident, 0))) { | |
781 | 786 | local_irq_restore_hw(flags); |
782 | 787 | return; |
783 | 788 | } |
... | ... | @@ -785,7 +790,7 @@ |
785 | 790 | if (!(per & P_MAYSHARE)) |
786 | 791 | port_setup(ident, GPIO_USAGE); |
787 | 792 | |
788 | - reserved_peri_map[gpio_bank(ident)] &= ~gpio_bit(ident); | |
793 | + unreserve(peri, ident); | |
789 | 794 | |
790 | 795 | set_label(ident, "free"); |
791 | 796 | |
... | ... | @@ -836,7 +841,7 @@ |
836 | 841 | return 0; |
837 | 842 | } |
838 | 843 | |
839 | - if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | |
844 | + if (unlikely(is_reserved(gpio, gpio, 1))) { | |
840 | 845 | if (system_state == SYSTEM_BOOTING) |
841 | 846 | dump_stack(); |
842 | 847 | printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n", |
... | ... | @@ -844,7 +849,7 @@ |
844 | 849 | local_irq_restore_hw(flags); |
845 | 850 | return -EBUSY; |
846 | 851 | } |
847 | - if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | |
852 | + if (unlikely(is_reserved(peri, gpio, 1))) { | |
848 | 853 | if (system_state == SYSTEM_BOOTING) |
849 | 854 | dump_stack(); |
850 | 855 | printk(KERN_ERR |
... | ... | @@ -853,7 +858,7 @@ |
853 | 858 | local_irq_restore_hw(flags); |
854 | 859 | return -EBUSY; |
855 | 860 | } |
856 | - if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | |
861 | + if (unlikely(is_reserved(gpio_irq, gpio, 1))) { | |
857 | 862 | printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!" |
858 | 863 | " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio); |
859 | 864 | } |
... | ... | @@ -863,7 +868,7 @@ |
863 | 868 | } |
864 | 869 | #endif |
865 | 870 | |
866 | - reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); | |
871 | + reserve(gpio, gpio); | |
867 | 872 | set_label(gpio, label); |
868 | 873 | |
869 | 874 | local_irq_restore_hw(flags); |
... | ... | @@ -885,7 +890,7 @@ |
885 | 890 | |
886 | 891 | local_irq_save_hw(flags); |
887 | 892 | |
888 | - if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { | |
893 | + if (unlikely(!is_reserved(gpio, gpio, 0))) { | |
889 | 894 | if (system_state == SYSTEM_BOOTING) |
890 | 895 | dump_stack(); |
891 | 896 | gpio_error(gpio); |
... | ... | @@ -893,7 +898,7 @@ |
893 | 898 | return; |
894 | 899 | } |
895 | 900 | |
896 | - reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); | |
901 | + unreserve(gpio, gpio); | |
897 | 902 | |
898 | 903 | set_label(gpio, "free"); |
899 | 904 | |
... | ... | @@ -902,7 +907,7 @@ |
902 | 907 | EXPORT_SYMBOL(bfin_gpio_free); |
903 | 908 | |
904 | 909 | #ifdef BFIN_SPECIAL_GPIO_BANKS |
905 | -static unsigned short reserved_special_gpio_map[gpio_bank(MAX_RESOURCES)]; | |
910 | +DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES)); | |
906 | 911 | |
907 | 912 | int bfin_special_gpio_request(unsigned gpio, const char *label) |
908 | 913 | { |
909 | 914 | |
... | ... | @@ -921,14 +926,14 @@ |
921 | 926 | return 0; |
922 | 927 | } |
923 | 928 | |
924 | - if (unlikely(reserved_special_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | |
929 | + if (unlikely(is_reserved(special_gpio, gpio, 1))) { | |
925 | 930 | local_irq_restore_hw(flags); |
926 | 931 | printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n", |
927 | 932 | gpio, get_label(gpio)); |
928 | 933 | |
929 | 934 | return -EBUSY; |
930 | 935 | } |
931 | - if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | |
936 | + if (unlikely(is_reserved(peri, gpio, 1))) { | |
932 | 937 | local_irq_restore_hw(flags); |
933 | 938 | printk(KERN_ERR |
934 | 939 | "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n", |
... | ... | @@ -937,8 +942,8 @@ |
937 | 942 | return -EBUSY; |
938 | 943 | } |
939 | 944 | |
940 | - reserved_special_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); | |
941 | - reserved_peri_map[gpio_bank(gpio)] |= gpio_bit(gpio); | |
945 | + reserve(special_gpio, gpio); | |
946 | + reserve(peri, gpio); | |
942 | 947 | |
943 | 948 | set_label(gpio, label); |
944 | 949 | local_irq_restore_hw(flags); |
945 | 950 | |
... | ... | @@ -956,14 +961,14 @@ |
956 | 961 | |
957 | 962 | local_irq_save_hw(flags); |
958 | 963 | |
959 | - if (unlikely(!(reserved_special_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { | |
964 | + if (unlikely(!is_reserved(special_gpio, gpio, 0))) { | |
960 | 965 | gpio_error(gpio); |
961 | 966 | local_irq_restore_hw(flags); |
962 | 967 | return; |
963 | 968 | } |
964 | 969 | |
965 | - reserved_special_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); | |
966 | - reserved_peri_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); | |
970 | + unreserve(special_gpio, gpio); | |
971 | + unreserve(peri, gpio); | |
967 | 972 | set_label(gpio, "free"); |
968 | 973 | local_irq_restore_hw(flags); |
969 | 974 | } |
... | ... | @@ -980,7 +985,7 @@ |
980 | 985 | |
981 | 986 | local_irq_save_hw(flags); |
982 | 987 | |
983 | - if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | |
988 | + if (unlikely(is_reserved(peri, gpio, 1))) { | |
984 | 989 | if (system_state == SYSTEM_BOOTING) |
985 | 990 | dump_stack(); |
986 | 991 | printk(KERN_ERR |
987 | 992 | |
... | ... | @@ -989,12 +994,12 @@ |
989 | 994 | local_irq_restore_hw(flags); |
990 | 995 | return -EBUSY; |
991 | 996 | } |
992 | - if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) | |
997 | + if (unlikely(is_reserved(gpio, gpio, 1))) | |
993 | 998 | printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved by %s! " |
994 | 999 | "(Documentation/blackfin/bfin-gpio-notes.txt)\n", |
995 | 1000 | gpio, get_label(gpio)); |
996 | 1001 | |
997 | - reserved_gpio_irq_map[gpio_bank(gpio)] |= gpio_bit(gpio); | |
1002 | + reserve(gpio_irq, gpio); | |
998 | 1003 | set_label(gpio, label); |
999 | 1004 | |
1000 | 1005 | local_irq_restore_hw(flags); |
... | ... | @@ -1013,7 +1018,7 @@ |
1013 | 1018 | |
1014 | 1019 | local_irq_save_hw(flags); |
1015 | 1020 | |
1016 | - if (unlikely(!(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { | |
1021 | + if (unlikely(!is_reserved(gpio_irq, gpio, 0))) { | |
1017 | 1022 | if (system_state == SYSTEM_BOOTING) |
1018 | 1023 | dump_stack(); |
1019 | 1024 | gpio_error(gpio); |
... | ... | @@ -1021,7 +1026,7 @@ |
1021 | 1026 | return; |
1022 | 1027 | } |
1023 | 1028 | |
1024 | - reserved_gpio_irq_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); | |
1029 | + unreserve(gpio_irq, gpio); | |
1025 | 1030 | |
1026 | 1031 | set_label(gpio, "free"); |
1027 | 1032 | |
... | ... | @@ -1042,7 +1047,7 @@ |
1042 | 1047 | { |
1043 | 1048 | unsigned long flags; |
1044 | 1049 | |
1045 | - if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | |
1050 | + if (unlikely(!is_reserved(gpio, gpio, 0))) { | |
1046 | 1051 | gpio_error(gpio); |
1047 | 1052 | return -EINVAL; |
1048 | 1053 | } |
... | ... | @@ -1084,7 +1089,7 @@ |
1084 | 1089 | { |
1085 | 1090 | unsigned long flags; |
1086 | 1091 | |
1087 | - if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | |
1092 | + if (unlikely(!is_reserved(gpio, gpio, 0))) { | |
1088 | 1093 | gpio_error(gpio); |
1089 | 1094 | return -EINVAL; |
1090 | 1095 | } |
1091 | 1096 | |
... | ... | @@ -1153,13 +1158,13 @@ |
1153 | 1158 | int c, irq, gpio, outlen = 0; |
1154 | 1159 | |
1155 | 1160 | for (c = 0; c < MAX_RESOURCES; c++) { |
1156 | - irq = reserved_gpio_irq_map[gpio_bank(c)] & gpio_bit(c); | |
1157 | - gpio = reserved_gpio_map[gpio_bank(c)] & gpio_bit(c); | |
1161 | + irq = is_reserved(gpio_irq, c, 1); | |
1162 | + gpio = is_reserved(gpio, c, 1); | |
1158 | 1163 | if (!check_gpio(c) && (gpio || irq)) |
1159 | 1164 | len = sprintf(buf, "GPIO_%d: \t%s%s \t\tGPIO %s\n", c, |
1160 | 1165 | get_label(c), (gpio && irq) ? " *" : "", |
1161 | 1166 | get_gpio_dir(c) ? "OUTPUT" : "INPUT"); |
1162 | - else if (reserved_peri_map[gpio_bank(c)] & gpio_bit(c)) | |
1167 | + else if (is_reserved(peri, c, 1)) | |
1163 | 1168 | len = sprintf(buf, "GPIO_%d: \t%s \t\tPeripheral\n", c, get_label(c)); |
1164 | 1169 | else |
1165 | 1170 | continue; |