aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin
diff options
context:
space:
mode:
authorGraf Yang <graf.yang@analog.com>2009-01-07 10:14:38 -0500
committerBryan Wu <cooloney@kernel.org>2009-01-07 10:14:38 -0500
commit9570ff4af6920c5992eb91141d71fc94127d864b (patch)
tree8ab0887035ab00a655eb8f78b39ed0acbb0b3bed /arch/blackfin
parent94106e0fb6b863348a566617ca6bf431c37ddc5e (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')
-rw-r--r--arch/blackfin/include/asm/gpio.h2
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c82
-rw-r--r--arch/blackfin/mach-common/ints-priority.c25
3 files changed, 91 insertions, 18 deletions
diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h
index ec2ab465709e..4ee687f34fee 100644
--- a/arch/blackfin/include/asm/gpio.h
+++ b/arch/blackfin/include/asm/gpio.h
@@ -548,6 +548,8 @@ struct gpio_port_s {
548 548
549int bfin_gpio_request(unsigned gpio, const char *label); 549int bfin_gpio_request(unsigned gpio, const char *label);
550void bfin_gpio_free(unsigned gpio); 550void bfin_gpio_free(unsigned gpio);
551int bfin_gpio_irq_request(unsigned gpio, const char *label);
552void bfin_gpio_irq_free(unsigned gpio);
551int bfin_gpio_direction_input(unsigned gpio); 553int bfin_gpio_direction_input(unsigned gpio);
552int bfin_gpio_direction_output(unsigned gpio, int value); 554int bfin_gpio_direction_output(unsigned gpio, int value);
553int bfin_gpio_get_value(unsigned gpio); 555int bfin_gpio_get_value(unsigned gpio);
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
180static unsigned short reserved_gpio_map[GPIO_BANK_NUM]; 180static unsigned short reserved_gpio_map[GPIO_BANK_NUM];
181static unsigned short reserved_peri_map[gpio_bank(MAX_RESOURCES)]; 181static unsigned short reserved_peri_map[gpio_bank(MAX_RESOURCES)];
182static 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}
1092EXPORT_SYMBOL(bfin_gpio_free); 1096EXPORT_SYMBOL(bfin_gpio_free);
1093 1097
1098int 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
1138void 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
1096int bfin_gpio_direction_input(unsigned gpio) 1163int bfin_gpio_direction_input(unsigned gpio)
@@ -1253,12 +1320,15 @@ void bfin_gpio_irq_prepare(unsigned gpio)
1253static int gpio_proc_read(char *buf, char **start, off_t offset, 1320static 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
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index a0bfca921712..7c1db775751b 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -432,7 +432,7 @@ static void bfin_gpio_irq_shutdown(unsigned int irq)
432 432
433 bfin_gpio_mask_irq(irq); 433 bfin_gpio_mask_irq(irq);
434 __clear_bit(gpionr, gpio_enabled); 434 __clear_bit(gpionr, gpio_enabled);
435 bfin_gpio_free(gpionr); 435 bfin_gpio_irq_free(gpionr);
436} 436}
437 437
438static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) 438static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
@@ -441,11 +441,6 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
441 char buf[16]; 441 char buf[16];
442 u32 gpionr = irq_to_gpio(irq); 442 u32 gpionr = irq_to_gpio(irq);
443 443
444 snprintf(buf, 16, "gpio-irq%d", irq);
445 ret = bfin_gpio_request(gpionr, buf);
446 if (ret)
447 return ret;
448
449 if (type == IRQ_TYPE_PROBE) { 444 if (type == IRQ_TYPE_PROBE) {
450 /* only probe unenabled GPIO interrupt lines */ 445 /* only probe unenabled GPIO interrupt lines */
451 if (__test_bit(gpionr, gpio_enabled)) 446 if (__test_bit(gpionr, gpio_enabled))
@@ -456,6 +451,11 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
456 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | 451 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
457 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { 452 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
458 453
454 snprintf(buf, 16, "gpio-irq%d", irq);
455 ret = bfin_gpio_irq_request(gpionr, buf);
456 if (ret)
457 return ret;
458
459 if (__test_and_set_bit(gpionr, gpio_enabled)) 459 if (__test_and_set_bit(gpionr, gpio_enabled))
460 bfin_gpio_irq_prepare(gpionr); 460 bfin_gpio_irq_prepare(gpionr);
461 461
@@ -740,7 +740,7 @@ static void bfin_gpio_irq_shutdown(unsigned int irq)
740 740
741 bfin_gpio_mask_irq(irq); 741 bfin_gpio_mask_irq(irq);
742 __clear_bit(gpionr, gpio_enabled); 742 __clear_bit(gpionr, gpio_enabled);
743 bfin_gpio_free(gpionr); 743 bfin_gpio_irq_free(gpionr);
744} 744}
745 745
746static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) 746static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
@@ -755,11 +755,6 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
755 if (pint_val == IRQ_NOT_AVAIL) 755 if (pint_val == IRQ_NOT_AVAIL)
756 return -ENODEV; 756 return -ENODEV;
757 757
758 snprintf(buf, 16, "gpio-irq%d", irq);
759 ret = bfin_gpio_request(gpionr, buf);
760 if (ret)
761 return ret;
762
763 if (type == IRQ_TYPE_PROBE) { 758 if (type == IRQ_TYPE_PROBE) {
764 /* only probe unenabled GPIO interrupt lines */ 759 /* only probe unenabled GPIO interrupt lines */
765 if (__test_bit(gpionr, gpio_enabled)) 760 if (__test_bit(gpionr, gpio_enabled))
@@ -769,6 +764,12 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
769 764
770 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | 765 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
771 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { 766 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
767
768 snprintf(buf, 16, "gpio-irq%d", irq);
769 ret = bfin_gpio_irq_request(gpionr, buf);
770 if (ret)
771 return ret;
772
772 if (__test_and_set_bit(gpionr, gpio_enabled)) 773 if (__test_and_set_bit(gpionr, gpio_enabled))
773 bfin_gpio_irq_prepare(gpionr); 774 bfin_gpio_irq_prepare(gpionr);
774 775