diff options
author | Michael Hennerich <michael.hennerich@analog.com> | 2008-04-23 20:10:10 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2008-04-23 20:10:10 -0400 |
commit | affee2b2613ada262eecea354b6c60696ca5d482 (patch) | |
tree | bc8b5b7a11416f565635b0b135a4438e17e64230 /arch | |
parent | a086ee2268abcfcbf80a114f4602e5b26aa80bf0 (diff) |
[Blackfin] arch: Allow concurrent use of GPIO and GPIO IRQ
The irq setup code no longer calls gpio request and free.
This patch also changes the default gpio_free behavior on Blackfin.
A freed GPIO keeps it's last state, and is not defaulted back to
an input. This is also what all other architectures do.
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 45 | ||||
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 52 |
2 files changed, 30 insertions, 67 deletions
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index fcb2f6cf430b..7e8eaf4a31bb 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c | |||
@@ -395,32 +395,6 @@ inline void portmux_setup(unsigned short portno, unsigned short function) | |||
395 | # define portmux_setup(...) do { } while (0) | 395 | # define portmux_setup(...) do { } while (0) |
396 | #endif | 396 | #endif |
397 | 397 | ||
398 | #ifndef BF548_FAMILY | ||
399 | static void default_gpio(unsigned gpio) | ||
400 | { | ||
401 | unsigned short bank, bitmask; | ||
402 | unsigned long flags; | ||
403 | |||
404 | bank = gpio_bank(gpio); | ||
405 | bitmask = gpio_bit(gpio); | ||
406 | |||
407 | local_irq_save(flags); | ||
408 | |||
409 | gpio_bankb[bank]->maska_clear = bitmask; | ||
410 | gpio_bankb[bank]->maskb_clear = bitmask; | ||
411 | SSYNC(); | ||
412 | gpio_bankb[bank]->inen &= ~bitmask; | ||
413 | gpio_bankb[bank]->dir &= ~bitmask; | ||
414 | gpio_bankb[bank]->polar &= ~bitmask; | ||
415 | gpio_bankb[bank]->both &= ~bitmask; | ||
416 | gpio_bankb[bank]->edge &= ~bitmask; | ||
417 | AWA_DUMMY_READ(edge); | ||
418 | local_irq_restore(flags); | ||
419 | } | ||
420 | #else | ||
421 | # define default_gpio(...) do { } while (0) | ||
422 | #endif | ||
423 | |||
424 | static int __init bfin_gpio_init(void) | 398 | static int __init bfin_gpio_init(void) |
425 | { | 399 | { |
426 | printk(KERN_INFO "Blackfin GPIO Controller\n"); | 400 | printk(KERN_INFO "Blackfin GPIO Controller\n"); |
@@ -1080,8 +1054,6 @@ void gpio_free(unsigned gpio) | |||
1080 | return; | 1054 | return; |
1081 | } | 1055 | } |
1082 | 1056 | ||
1083 | default_gpio(gpio); | ||
1084 | |||
1085 | reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); | 1057 | reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); |
1086 | 1058 | ||
1087 | set_label(gpio, "free"); | 1059 | set_label(gpio, "free"); |
@@ -1144,6 +1116,18 @@ int gpio_get_value(unsigned gpio) | |||
1144 | } | 1116 | } |
1145 | EXPORT_SYMBOL(gpio_get_value); | 1117 | EXPORT_SYMBOL(gpio_get_value); |
1146 | 1118 | ||
1119 | void bfin_gpio_irq_prepare(unsigned gpio) | ||
1120 | { | ||
1121 | unsigned long flags; | ||
1122 | |||
1123 | port_setup(gpio, GPIO_USAGE); | ||
1124 | |||
1125 | local_irq_save(flags); | ||
1126 | gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio); | ||
1127 | gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio); | ||
1128 | local_irq_restore(flags); | ||
1129 | } | ||
1130 | |||
1147 | #else | 1131 | #else |
1148 | 1132 | ||
1149 | int gpio_direction_input(unsigned gpio) | 1133 | int gpio_direction_input(unsigned gpio) |
@@ -1210,6 +1194,11 @@ void bfin_gpio_reset_spi0_ssel1(void) | |||
1210 | udelay(1); | 1194 | udelay(1); |
1211 | } | 1195 | } |
1212 | 1196 | ||
1197 | void bfin_gpio_irq_prepare(unsigned gpio) | ||
1198 | { | ||
1199 | port_setup(gpio, GPIO_USAGE); | ||
1200 | } | ||
1201 | |||
1213 | #endif /*BF548_FAMILY */ | 1202 | #endif /*BF548_FAMILY */ |
1214 | 1203 | ||
1215 | #if defined(CONFIG_PROC_FS) | 1204 | #if defined(CONFIG_PROC_FS) |
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index a2a11717bf66..5448230c0e95 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c | |||
@@ -326,6 +326,7 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, | |||
326 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 326 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
327 | static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 327 | static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
328 | 328 | ||
329 | extern void bfin_gpio_irq_prepare(unsigned gpio); | ||
329 | 330 | ||
330 | static void bfin_gpio_ack_irq(unsigned int irq) | 331 | static void bfin_gpio_ack_irq(unsigned int irq) |
331 | { | 332 | { |
@@ -364,35 +365,25 @@ static void bfin_gpio_unmask_irq(unsigned int irq) | |||
364 | 365 | ||
365 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) | 366 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) |
366 | { | 367 | { |
367 | unsigned int ret; | ||
368 | u16 gpionr = irq - IRQ_PF0; | 368 | u16 gpionr = irq - IRQ_PF0; |
369 | char buf[8]; | ||
370 | 369 | ||
371 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 370 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) |
372 | snprintf(buf, sizeof buf, "IRQ %d", irq); | 371 | bfin_gpio_irq_prepare(gpionr); |
373 | ret = gpio_request(gpionr, buf); | ||
374 | if (ret) | ||
375 | return ret; | ||
376 | } | ||
377 | 372 | ||
378 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | 373 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); |
379 | bfin_gpio_unmask_irq(irq); | 374 | bfin_gpio_unmask_irq(irq); |
380 | 375 | ||
381 | return ret; | 376 | return 0; |
382 | } | 377 | } |
383 | 378 | ||
384 | static void bfin_gpio_irq_shutdown(unsigned int irq) | 379 | static void bfin_gpio_irq_shutdown(unsigned int irq) |
385 | { | 380 | { |
386 | bfin_gpio_mask_irq(irq); | 381 | bfin_gpio_mask_irq(irq); |
387 | gpio_free(irq - IRQ_PF0); | ||
388 | gpio_enabled[gpio_bank(irq - IRQ_PF0)] &= ~gpio_bit(irq - IRQ_PF0); | 382 | gpio_enabled[gpio_bank(irq - IRQ_PF0)] &= ~gpio_bit(irq - IRQ_PF0); |
389 | } | 383 | } |
390 | 384 | ||
391 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | 385 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) |
392 | { | 386 | { |
393 | |||
394 | unsigned int ret; | ||
395 | char buf[8]; | ||
396 | u16 gpionr = irq - IRQ_PF0; | 387 | u16 gpionr = irq - IRQ_PF0; |
397 | 388 | ||
398 | if (type == IRQ_TYPE_PROBE) { | 389 | if (type == IRQ_TYPE_PROBE) { |
@@ -404,12 +395,8 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
404 | 395 | ||
405 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | 396 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | |
406 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | 397 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { |
407 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 398 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) |
408 | snprintf(buf, sizeof buf, "IRQ %d", irq); | 399 | bfin_gpio_irq_prepare(gpionr); |
409 | ret = gpio_request(gpionr, buf); | ||
410 | if (ret) | ||
411 | return ret; | ||
412 | } | ||
413 | 400 | ||
414 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | 401 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); |
415 | } else { | 402 | } else { |
@@ -595,6 +582,8 @@ static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = { | |||
595 | (struct pin_int_t *)PINT3_MASK_SET, | 582 | (struct pin_int_t *)PINT3_MASK_SET, |
596 | }; | 583 | }; |
597 | 584 | ||
585 | extern void bfin_gpio_irq_prepare(unsigned gpio); | ||
586 | |||
598 | inline unsigned short get_irq_base(u8 bank, u8 bmap) | 587 | inline unsigned short get_irq_base(u8 bank, u8 bmap) |
599 | { | 588 | { |
600 | 589 | ||
@@ -697,8 +686,6 @@ static void bfin_gpio_unmask_irq(unsigned int irq) | |||
697 | 686 | ||
698 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) | 687 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) |
699 | { | 688 | { |
700 | unsigned int ret; | ||
701 | char buf[8]; | ||
702 | u16 gpionr = irq_to_gpio(irq); | 689 | u16 gpionr = irq_to_gpio(irq); |
703 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 690 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
704 | 691 | ||
@@ -709,17 +696,13 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq) | |||
709 | return -ENODEV; | 696 | return -ENODEV; |
710 | } | 697 | } |
711 | 698 | ||
712 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 699 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) |
713 | snprintf(buf, sizeof buf, "IRQ %d", irq); | 700 | bfin_gpio_irq_prepare(gpionr); |
714 | ret = gpio_request(gpionr, buf); | ||
715 | if (ret) | ||
716 | return ret; | ||
717 | } | ||
718 | 701 | ||
719 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | 702 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); |
720 | bfin_gpio_unmask_irq(irq); | 703 | bfin_gpio_unmask_irq(irq); |
721 | 704 | ||
722 | return ret; | 705 | return 0; |
723 | } | 706 | } |
724 | 707 | ||
725 | static void bfin_gpio_irq_shutdown(unsigned int irq) | 708 | static void bfin_gpio_irq_shutdown(unsigned int irq) |
@@ -727,15 +710,12 @@ static void bfin_gpio_irq_shutdown(unsigned int irq) | |||
727 | u16 gpionr = irq_to_gpio(irq); | 710 | u16 gpionr = irq_to_gpio(irq); |
728 | 711 | ||
729 | bfin_gpio_mask_irq(irq); | 712 | bfin_gpio_mask_irq(irq); |
730 | gpio_free(gpionr); | ||
731 | gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); | 713 | gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); |
732 | } | 714 | } |
733 | 715 | ||
734 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | 716 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) |
735 | { | 717 | { |
736 | 718 | ||
737 | unsigned int ret; | ||
738 | char buf[8]; | ||
739 | u16 gpionr = irq_to_gpio(irq); | 719 | u16 gpionr = irq_to_gpio(irq); |
740 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 720 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
741 | u32 pintbit = PINT_BIT(pint_val); | 721 | u32 pintbit = PINT_BIT(pint_val); |
@@ -753,12 +733,8 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
753 | 733 | ||
754 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | 734 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | |
755 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | 735 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { |
756 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 736 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) |
757 | snprintf(buf, sizeof buf, "IRQ %d", irq); | 737 | bfin_gpio_irq_prepare(gpionr); |
758 | ret = gpio_request(gpionr, buf); | ||
759 | if (ret) | ||
760 | return ret; | ||
761 | } | ||
762 | 738 | ||
763 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | 739 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); |
764 | } else { | 740 | } else { |
@@ -766,8 +742,6 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
766 | return 0; | 742 | return 0; |
767 | } | 743 | } |
768 | 744 | ||
769 | gpio_direction_input(gpionr); | ||
770 | |||
771 | if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) | 745 | if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) |
772 | pint[bank]->invert_set = pintbit; /* low or falling edge denoted by one */ | 746 | pint[bank]->invert_set = pintbit; /* low or falling edge denoted by one */ |
773 | else | 747 | else |