diff options
author | Graf Yang <graf.yang@analog.com> | 2009-01-07 10:14:38 -0500 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2009-01-07 10:14:38 -0500 |
commit | 9570ff4af6920c5992eb91141d71fc94127d864b (patch) | |
tree | 8ab0887035ab00a655eb8f78b39ed0acbb0b3bed /arch/blackfin/kernel/bfin_gpio.c | |
parent | 94106e0fb6b863348a566617ca6bf431c37ddc5e (diff) |
Blackfin arch: Allow a gpio pin be requested both as gpio and irq.
[Mike Frysinger <vapier.adi@gmail.com>:
- use KERN_NOTICE when using gpios as both irq and non
rather than KERN_ERR
- embedded newlines in printk() does not fly]
Signed-off-by: Graf Yang <graf.yang@analog.com>
Signed-off-by: Mike Frysinger <vapier.adi@gmail.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch/blackfin/kernel/bfin_gpio.c')
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 82 |
1 files changed, 76 insertions, 6 deletions
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index de235b8f37a8..2c72b15b71b0 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c | |||
@@ -179,6 +179,7 @@ static struct gpio_port_t *gpio_array[] = { | |||
179 | 179 | ||
180 | static unsigned short reserved_gpio_map[GPIO_BANK_NUM]; | 180 | static unsigned short reserved_gpio_map[GPIO_BANK_NUM]; |
181 | static unsigned short reserved_peri_map[gpio_bank(MAX_RESOURCES)]; | 181 | static unsigned short reserved_peri_map[gpio_bank(MAX_RESOURCES)]; |
182 | static unsigned short reserved_gpio_irq_map[GPIO_BANK_NUM]; | ||
182 | 183 | ||
183 | #define RESOURCE_LABEL_SIZE 16 | 184 | #define RESOURCE_LABEL_SIZE 16 |
184 | 185 | ||
@@ -1043,7 +1044,7 @@ int bfin_gpio_request(unsigned gpio, const char *label) | |||
1043 | if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | 1044 | if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { |
1044 | dump_stack(); | 1045 | dump_stack(); |
1045 | printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n", | 1046 | printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n", |
1046 | gpio, get_label(gpio)); | 1047 | gpio, get_label(gpio)); |
1047 | local_irq_restore(flags); | 1048 | local_irq_restore(flags); |
1048 | return -EBUSY; | 1049 | return -EBUSY; |
1049 | } | 1050 | } |
@@ -1055,13 +1056,16 @@ int bfin_gpio_request(unsigned gpio, const char *label) | |||
1055 | local_irq_restore(flags); | 1056 | local_irq_restore(flags); |
1056 | return -EBUSY; | 1057 | return -EBUSY; |
1057 | } | 1058 | } |
1059 | if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) | ||
1060 | printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!" | ||
1061 | " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio); | ||
1058 | 1062 | ||
1059 | reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); | 1063 | reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); |
1064 | set_label(gpio, label); | ||
1060 | 1065 | ||
1061 | local_irq_restore(flags); | 1066 | local_irq_restore(flags); |
1062 | 1067 | ||
1063 | port_setup(gpio, GPIO_USAGE); | 1068 | port_setup(gpio, GPIO_USAGE); |
1064 | set_label(gpio, label); | ||
1065 | 1069 | ||
1066 | return 0; | 1070 | return 0; |
1067 | } | 1071 | } |
@@ -1091,6 +1095,69 @@ void bfin_gpio_free(unsigned gpio) | |||
1091 | } | 1095 | } |
1092 | EXPORT_SYMBOL(bfin_gpio_free); | 1096 | EXPORT_SYMBOL(bfin_gpio_free); |
1093 | 1097 | ||
1098 | int bfin_gpio_irq_request(unsigned gpio, const char *label) | ||
1099 | { | ||
1100 | unsigned long flags; | ||
1101 | |||
1102 | if (check_gpio(gpio) < 0) | ||
1103 | return -EINVAL; | ||
1104 | |||
1105 | local_irq_save(flags); | ||
1106 | |||
1107 | if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | ||
1108 | dump_stack(); | ||
1109 | printk(KERN_ERR | ||
1110 | "bfin-gpio: GPIO %d is already reserved as gpio-irq !\n", | ||
1111 | gpio); | ||
1112 | local_irq_restore(flags); | ||
1113 | return -EBUSY; | ||
1114 | } | ||
1115 | if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | ||
1116 | dump_stack(); | ||
1117 | printk(KERN_ERR | ||
1118 | "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n", | ||
1119 | gpio, get_label(gpio)); | ||
1120 | local_irq_restore(flags); | ||
1121 | return -EBUSY; | ||
1122 | } | ||
1123 | if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) | ||
1124 | printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved by %s! " | ||
1125 | "(Documentation/blackfin/bfin-gpio-notes.txt)\n", | ||
1126 | gpio, get_label(gpio)); | ||
1127 | |||
1128 | reserved_gpio_irq_map[gpio_bank(gpio)] |= gpio_bit(gpio); | ||
1129 | set_label(gpio, label); | ||
1130 | |||
1131 | local_irq_restore(flags); | ||
1132 | |||
1133 | port_setup(gpio, GPIO_USAGE); | ||
1134 | |||
1135 | return 0; | ||
1136 | } | ||
1137 | |||
1138 | void bfin_gpio_irq_free(unsigned gpio) | ||
1139 | { | ||
1140 | unsigned long flags; | ||
1141 | |||
1142 | if (check_gpio(gpio) < 0) | ||
1143 | return; | ||
1144 | |||
1145 | local_irq_save(flags); | ||
1146 | |||
1147 | if (unlikely(!(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { | ||
1148 | dump_stack(); | ||
1149 | gpio_error(gpio); | ||
1150 | local_irq_restore(flags); | ||
1151 | return; | ||
1152 | } | ||
1153 | |||
1154 | reserved_gpio_irq_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); | ||
1155 | |||
1156 | set_label(gpio, "free"); | ||
1157 | |||
1158 | local_irq_restore(flags); | ||
1159 | } | ||
1160 | |||
1094 | 1161 | ||
1095 | #ifdef BF548_FAMILY | 1162 | #ifdef BF548_FAMILY |
1096 | int bfin_gpio_direction_input(unsigned gpio) | 1163 | int bfin_gpio_direction_input(unsigned gpio) |
@@ -1253,12 +1320,15 @@ void bfin_gpio_irq_prepare(unsigned gpio) | |||
1253 | static int gpio_proc_read(char *buf, char **start, off_t offset, | 1320 | static int gpio_proc_read(char *buf, char **start, off_t offset, |
1254 | int len, int *unused_i, void *unused_v) | 1321 | int len, int *unused_i, void *unused_v) |
1255 | { | 1322 | { |
1256 | int c, outlen = 0; | 1323 | int c, irq, gpio, outlen = 0; |
1257 | 1324 | ||
1258 | for (c = 0; c < MAX_RESOURCES; c++) { | 1325 | for (c = 0; c < MAX_RESOURCES; c++) { |
1259 | if (!check_gpio(c) && (reserved_gpio_map[gpio_bank(c)] & gpio_bit(c))) | 1326 | irq = reserved_gpio_irq_map[gpio_bank(c)] & gpio_bit(c); |
1260 | len = sprintf(buf, "GPIO_%d: \t%s \t\tGPIO %s\n", c, | 1327 | gpio = reserved_gpio_map[gpio_bank(c)] & gpio_bit(c); |
1261 | get_label(c), get_gpio_dir(c) ? "OUTPUT" : "INPUT"); | 1328 | if (!check_gpio(c) && (gpio || irq)) |
1329 | len = sprintf(buf, "GPIO_%d: \t%s%s \t\tGPIO %s\n", c, | ||
1330 | get_label(c), (gpio && irq) ? " *" : "", | ||
1331 | get_gpio_dir(c) ? "OUTPUT" : "INPUT"); | ||
1262 | else if (reserved_peri_map[gpio_bank(c)] & gpio_bit(c)) | 1332 | else if (reserved_peri_map[gpio_bank(c)] & gpio_bit(c)) |
1263 | len = sprintf(buf, "GPIO_%d: \t%s \t\tPeripheral\n", c, get_label(c)); | 1333 | len = sprintf(buf, "GPIO_%d: \t%s \t\tPeripheral\n", c, get_label(c)); |
1264 | else | 1334 | else |