diff options
-rw-r--r-- | arch/blackfin/Kconfig | 1 | ||||
-rw-r--r-- | arch/blackfin/include/asm/gpio.h | 79 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 90 |
3 files changed, 140 insertions, 30 deletions
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 19b43f37e1a3..004c06ce3198 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig | |||
@@ -26,6 +26,7 @@ config BLACKFIN | |||
26 | default y | 26 | default y |
27 | select HAVE_IDE | 27 | select HAVE_IDE |
28 | select HAVE_OPROFILE | 28 | select HAVE_OPROFILE |
29 | select ARCH_WANT_OPTIONAL_GPIOLIB | ||
29 | 30 | ||
30 | config ZONE_DMA | 31 | config ZONE_DMA |
31 | bool | 32 | bool |
diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h index 2a5e846a5382..f8fe33b8bca6 100644 --- a/arch/blackfin/include/asm/gpio.h +++ b/arch/blackfin/include/asm/gpio.h | |||
@@ -84,13 +84,12 @@ | |||
84 | #ifndef __ARCH_BLACKFIN_GPIO_H__ | 84 | #ifndef __ARCH_BLACKFIN_GPIO_H__ |
85 | #define __ARCH_BLACKFIN_GPIO_H__ | 85 | #define __ARCH_BLACKFIN_GPIO_H__ |
86 | 86 | ||
87 | #define gpio_bank(x) ((x) >> 4) | 87 | #define gpio_bank(x) ((x) >> 4) |
88 | #define gpio_bank_n(x) ((x) & 0xF ? ((x) >> 4) + 1 : (x) >> 4) | 88 | #define gpio_bit(x) (1<<((x) & 0xF)) |
89 | #define gpio_bit(x) (1<<((x) & 0xF)) | 89 | #define gpio_sub_n(x) ((x) & 0xF) |
90 | #define gpio_sub_n(x) ((x) & 0xF) | 90 | #define GPIO_BANK_NUM DIV_ROUND_UP(MAX_BLACKFIN_GPIOS, 16) |
91 | 91 | ||
92 | #define GPIO_BANKSIZE 16 | 92 | #define GPIO_BANKSIZE 16 |
93 | #define GPIO_BANK_NUM gpio_bank_n(MAX_BLACKFIN_GPIOS) | ||
94 | 93 | ||
95 | #define GPIO_0 0 | 94 | #define GPIO_0 0 |
96 | #define GPIO_1 1 | 95 | #define GPIO_1 1 |
@@ -546,20 +545,76 @@ struct gpio_port_s { | |||
546 | * MODIFICATION HISTORY : | 545 | * MODIFICATION HISTORY : |
547 | **************************************************************/ | 546 | **************************************************************/ |
548 | 547 | ||
549 | int gpio_request(unsigned, const char *); | ||
550 | void gpio_free(unsigned); | ||
551 | 548 | ||
552 | void gpio_set_value(unsigned gpio, int arg); | 549 | int bfin_gpio_request(unsigned gpio, const char *label); |
553 | int gpio_get_value(unsigned gpio); | 550 | void bfin_gpio_free(unsigned gpio); |
551 | int bfin_gpio_direction_input(unsigned gpio); | ||
552 | int bfin_gpio_direction_output(unsigned gpio, int value); | ||
553 | int bfin_gpio_get_value(unsigned gpio); | ||
554 | void bfin_gpio_set_value(unsigned gpio, int value); | ||
554 | 555 | ||
555 | #ifndef BF548_FAMILY | 556 | #ifndef BF548_FAMILY |
556 | #define gpio_set_value(gpio, value) set_gpio_data(gpio, value) | 557 | #define bfin_gpio_set_value(gpio, value) set_gpio_data(gpio, value) |
557 | #endif | 558 | #endif |
558 | 559 | ||
559 | int gpio_direction_input(unsigned gpio); | 560 | #ifdef CONFIG_GPIOLIB |
560 | int gpio_direction_output(unsigned gpio, int value); | 561 | #include <asm-generic/gpio.h> /* cansleep wrappers */ |
562 | |||
563 | static inline int gpio_get_value(unsigned int gpio) | ||
564 | { | ||
565 | if (gpio < MAX_BLACKFIN_GPIOS) | ||
566 | return bfin_gpio_get_value(gpio); | ||
567 | else | ||
568 | return __gpio_get_value(gpio); | ||
569 | } | ||
570 | |||
571 | static inline void gpio_set_value(unsigned int gpio, int value) | ||
572 | { | ||
573 | if (gpio < MAX_BLACKFIN_GPIOS) | ||
574 | bfin_gpio_set_value(gpio, value); | ||
575 | else | ||
576 | __gpio_set_value(gpio, value); | ||
577 | } | ||
578 | |||
579 | static inline int gpio_cansleep(unsigned int gpio) | ||
580 | { | ||
581 | return __gpio_cansleep(gpio); | ||
582 | } | ||
583 | |||
584 | #else /* !CONFIG_GPIOLIB */ | ||
585 | |||
586 | static inline int gpio_request(unsigned gpio, const char *label) | ||
587 | { | ||
588 | return bfin_gpio_request(gpio, label); | ||
589 | } | ||
590 | |||
591 | static inline void gpio_free(unsigned gpio) | ||
592 | { | ||
593 | return bfin_gpio_free(gpio); | ||
594 | } | ||
595 | |||
596 | static inline int gpio_direction_input(unsigned gpio) | ||
597 | { | ||
598 | return bfin_gpio_direction_input(gpio); | ||
599 | } | ||
600 | |||
601 | static inline int gpio_direction_output(unsigned gpio, int value) | ||
602 | { | ||
603 | return bfin_gpio_direction_output(gpio, value); | ||
604 | } | ||
605 | |||
606 | static inline int gpio_get_value(unsigned gpio) | ||
607 | { | ||
608 | return bfin_gpio_get_value(gpio); | ||
609 | } | ||
610 | |||
611 | static inline void gpio_set_value(unsigned gpio, int value) | ||
612 | { | ||
613 | return bfin_gpio_set_value(gpio, value); | ||
614 | } | ||
561 | 615 | ||
562 | #include <asm-generic/gpio.h> /* cansleep wrappers */ | 616 | #include <asm-generic/gpio.h> /* cansleep wrappers */ |
617 | #endif /* !CONFIG_GPIOLIB */ | ||
563 | #include <asm/irq.h> | 618 | #include <asm/irq.h> |
564 | 619 | ||
565 | static inline int gpio_to_irq(unsigned gpio) | 620 | static inline int gpio_to_irq(unsigned gpio) |
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 6939272e9ed4..f8d666e6741b 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c | |||
@@ -1020,7 +1020,7 @@ EXPORT_SYMBOL(peripheral_free_list); | |||
1020 | * MODIFICATION HISTORY : | 1020 | * MODIFICATION HISTORY : |
1021 | **************************************************************/ | 1021 | **************************************************************/ |
1022 | 1022 | ||
1023 | int gpio_request(unsigned gpio, const char *label) | 1023 | int bfin_gpio_request(unsigned gpio, const char *label) |
1024 | { | 1024 | { |
1025 | unsigned long flags; | 1025 | unsigned long flags; |
1026 | 1026 | ||
@@ -1065,9 +1065,9 @@ int gpio_request(unsigned gpio, const char *label) | |||
1065 | 1065 | ||
1066 | return 0; | 1066 | return 0; |
1067 | } | 1067 | } |
1068 | EXPORT_SYMBOL(gpio_request); | 1068 | EXPORT_SYMBOL(bfin_gpio_request); |
1069 | 1069 | ||
1070 | void gpio_free(unsigned gpio) | 1070 | void bfin_gpio_free(unsigned gpio) |
1071 | { | 1071 | { |
1072 | unsigned long flags; | 1072 | unsigned long flags; |
1073 | 1073 | ||
@@ -1089,11 +1089,11 @@ void gpio_free(unsigned gpio) | |||
1089 | 1089 | ||
1090 | local_irq_restore(flags); | 1090 | local_irq_restore(flags); |
1091 | } | 1091 | } |
1092 | EXPORT_SYMBOL(gpio_free); | 1092 | EXPORT_SYMBOL(bfin_gpio_free); |
1093 | 1093 | ||
1094 | 1094 | ||
1095 | #ifdef BF548_FAMILY | 1095 | #ifdef BF548_FAMILY |
1096 | int gpio_direction_input(unsigned gpio) | 1096 | int bfin_gpio_direction_input(unsigned gpio) |
1097 | { | 1097 | { |
1098 | unsigned long flags; | 1098 | unsigned long flags; |
1099 | 1099 | ||
@@ -1109,9 +1109,9 @@ int gpio_direction_input(unsigned gpio) | |||
1109 | 1109 | ||
1110 | return 0; | 1110 | return 0; |
1111 | } | 1111 | } |
1112 | EXPORT_SYMBOL(gpio_direction_input); | 1112 | EXPORT_SYMBOL(bfin_gpio_direction_input); |
1113 | 1113 | ||
1114 | int gpio_direction_output(unsigned gpio, int value) | 1114 | int bfin_gpio_direction_output(unsigned gpio, int value) |
1115 | { | 1115 | { |
1116 | unsigned long flags; | 1116 | unsigned long flags; |
1117 | 1117 | ||
@@ -1128,22 +1128,22 @@ int gpio_direction_output(unsigned gpio, int value) | |||
1128 | 1128 | ||
1129 | return 0; | 1129 | return 0; |
1130 | } | 1130 | } |
1131 | EXPORT_SYMBOL(gpio_direction_output); | 1131 | EXPORT_SYMBOL(bfin_gpio_direction_output); |
1132 | 1132 | ||
1133 | void gpio_set_value(unsigned gpio, int arg) | 1133 | void bfin_gpio_set_value(unsigned gpio, int arg) |
1134 | { | 1134 | { |
1135 | if (arg) | 1135 | if (arg) |
1136 | gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio); | 1136 | gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio); |
1137 | else | 1137 | else |
1138 | gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio); | 1138 | gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio); |
1139 | } | 1139 | } |
1140 | EXPORT_SYMBOL(gpio_set_value); | 1140 | EXPORT_SYMBOL(bfin_gpio_set_value); |
1141 | 1141 | ||
1142 | int gpio_get_value(unsigned gpio) | 1142 | int bfin_gpio_get_value(unsigned gpio) |
1143 | { | 1143 | { |
1144 | return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio))); | 1144 | return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio))); |
1145 | } | 1145 | } |
1146 | EXPORT_SYMBOL(gpio_get_value); | 1146 | EXPORT_SYMBOL(bfin_gpio_get_value); |
1147 | 1147 | ||
1148 | void bfin_gpio_irq_prepare(unsigned gpio) | 1148 | void bfin_gpio_irq_prepare(unsigned gpio) |
1149 | { | 1149 | { |
@@ -1159,7 +1159,7 @@ void bfin_gpio_irq_prepare(unsigned gpio) | |||
1159 | 1159 | ||
1160 | #else | 1160 | #else |
1161 | 1161 | ||
1162 | int gpio_get_value(unsigned gpio) | 1162 | int bfin_gpio_get_value(unsigned gpio) |
1163 | { | 1163 | { |
1164 | unsigned long flags; | 1164 | unsigned long flags; |
1165 | int ret; | 1165 | int ret; |
@@ -1175,10 +1175,10 @@ int gpio_get_value(unsigned gpio) | |||
1175 | } else | 1175 | } else |
1176 | return get_gpio_data(gpio); | 1176 | return get_gpio_data(gpio); |
1177 | } | 1177 | } |
1178 | EXPORT_SYMBOL(gpio_get_value); | 1178 | EXPORT_SYMBOL(bfin_gpio_get_value); |
1179 | 1179 | ||
1180 | 1180 | ||
1181 | int gpio_direction_input(unsigned gpio) | 1181 | int bfin_gpio_direction_input(unsigned gpio) |
1182 | { | 1182 | { |
1183 | unsigned long flags; | 1183 | unsigned long flags; |
1184 | 1184 | ||
@@ -1195,9 +1195,9 @@ int gpio_direction_input(unsigned gpio) | |||
1195 | 1195 | ||
1196 | return 0; | 1196 | return 0; |
1197 | } | 1197 | } |
1198 | EXPORT_SYMBOL(gpio_direction_input); | 1198 | EXPORT_SYMBOL(bfin_gpio_direction_input); |
1199 | 1199 | ||
1200 | int gpio_direction_output(unsigned gpio, int value) | 1200 | int bfin_gpio_direction_output(unsigned gpio, int value) |
1201 | { | 1201 | { |
1202 | unsigned long flags; | 1202 | unsigned long flags; |
1203 | 1203 | ||
@@ -1220,7 +1220,7 @@ int gpio_direction_output(unsigned gpio, int value) | |||
1220 | 1220 | ||
1221 | return 0; | 1221 | return 0; |
1222 | } | 1222 | } |
1223 | EXPORT_SYMBOL(gpio_direction_output); | 1223 | EXPORT_SYMBOL(bfin_gpio_direction_output); |
1224 | 1224 | ||
1225 | /* If we are booting from SPI and our board lacks a strong enough pull up, | 1225 | /* If we are booting from SPI and our board lacks a strong enough pull up, |
1226 | * the core can reset and execute the bootrom faster than the resistor can | 1226 | * the core can reset and execute the bootrom faster than the resistor can |
@@ -1280,3 +1280,57 @@ static __init int gpio_register_proc(void) | |||
1280 | } | 1280 | } |
1281 | __initcall(gpio_register_proc); | 1281 | __initcall(gpio_register_proc); |
1282 | #endif | 1282 | #endif |
1283 | |||
1284 | #ifdef CONFIG_GPIOLIB | ||
1285 | int bfin_gpiolib_direction_input(struct gpio_chip *chip, unsigned gpio) | ||
1286 | { | ||
1287 | return bfin_gpio_direction_input(gpio); | ||
1288 | } | ||
1289 | |||
1290 | int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio, int level) | ||
1291 | { | ||
1292 | return bfin_gpio_direction_output(gpio, level); | ||
1293 | } | ||
1294 | |||
1295 | int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio) | ||
1296 | { | ||
1297 | return bfin_gpio_get_value(gpio); | ||
1298 | } | ||
1299 | |||
1300 | void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value) | ||
1301 | { | ||
1302 | #ifdef BF548_FAMILY | ||
1303 | return bfin_gpio_set_value(gpio, value); | ||
1304 | #else | ||
1305 | return set_gpio_data(gpio, value); | ||
1306 | #endif | ||
1307 | } | ||
1308 | |||
1309 | int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio) | ||
1310 | { | ||
1311 | return bfin_gpio_request(gpio, chip->label); | ||
1312 | } | ||
1313 | |||
1314 | void bfin_gpiolib_gpio_free(struct gpio_chip *chip, unsigned gpio) | ||
1315 | { | ||
1316 | return bfin_gpio_free(gpio); | ||
1317 | } | ||
1318 | |||
1319 | static struct gpio_chip bfin_chip = { | ||
1320 | .label = "Blackfin-GPIOlib", | ||
1321 | .direction_input = bfin_gpiolib_direction_input, | ||
1322 | .get = bfin_gpiolib_get_value, | ||
1323 | .direction_output = bfin_gpiolib_direction_output, | ||
1324 | .set = bfin_gpiolib_set_value, | ||
1325 | .request = bfin_gpiolib_gpio_request, | ||
1326 | .free = bfin_gpiolib_gpio_free, | ||
1327 | .base = 0, | ||
1328 | .ngpio = MAX_BLACKFIN_GPIOS, | ||
1329 | }; | ||
1330 | |||
1331 | static int __init bfin_gpiolib_setup(void) | ||
1332 | { | ||
1333 | return gpiochip_add(&bfin_chip); | ||
1334 | } | ||
1335 | arch_initcall(bfin_gpiolib_setup); | ||
1336 | #endif | ||