diff options
Diffstat (limited to 'arch/arm/plat-omap/gpio.c')
-rw-r--r-- | arch/arm/plat-omap/gpio.c | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index cd7f973fb286..f55f99ae58ae 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
@@ -94,6 +94,8 @@ | |||
94 | #define OMAP24XX_GPIO_SYSCONFIG 0x0010 | 94 | #define OMAP24XX_GPIO_SYSCONFIG 0x0010 |
95 | #define OMAP24XX_GPIO_SYSSTATUS 0x0014 | 95 | #define OMAP24XX_GPIO_SYSSTATUS 0x0014 |
96 | #define OMAP24XX_GPIO_IRQSTATUS1 0x0018 | 96 | #define OMAP24XX_GPIO_IRQSTATUS1 0x0018 |
97 | #define OMAP24XX_GPIO_IRQSTATUS2 0x0028 | ||
98 | #define OMAP24XX_GPIO_IRQENABLE2 0x002c | ||
97 | #define OMAP24XX_GPIO_IRQENABLE1 0x001c | 99 | #define OMAP24XX_GPIO_IRQENABLE1 0x001c |
98 | #define OMAP24XX_GPIO_CTRL 0x0030 | 100 | #define OMAP24XX_GPIO_CTRL 0x0030 |
99 | #define OMAP24XX_GPIO_OE 0x0034 | 101 | #define OMAP24XX_GPIO_OE 0x0034 |
@@ -110,8 +112,6 @@ | |||
110 | #define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 | 112 | #define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 |
111 | #define OMAP24XX_GPIO_SETDATAOUT 0x0094 | 113 | #define OMAP24XX_GPIO_SETDATAOUT 0x0094 |
112 | 114 | ||
113 | #define OMAP_MPUIO_MASK (~OMAP_MAX_GPIO_LINES & 0xff) | ||
114 | |||
115 | struct gpio_bank { | 115 | struct gpio_bank { |
116 | void __iomem *base; | 116 | void __iomem *base; |
117 | u16 irq; | 117 | u16 irq; |
@@ -216,11 +216,13 @@ static inline int gpio_valid(int gpio) | |||
216 | { | 216 | { |
217 | if (gpio < 0) | 217 | if (gpio < 0) |
218 | return -1; | 218 | return -1; |
219 | #ifndef CONFIG_ARCH_OMAP24XX | ||
219 | if (OMAP_GPIO_IS_MPUIO(gpio)) { | 220 | if (OMAP_GPIO_IS_MPUIO(gpio)) { |
220 | if ((gpio & OMAP_MPUIO_MASK) > 16) | 221 | if (gpio >= OMAP_MAX_GPIO_LINES + 16) |
221 | return -1; | 222 | return -1; |
222 | return 0; | 223 | return 0; |
223 | } | 224 | } |
225 | #endif | ||
224 | #ifdef CONFIG_ARCH_OMAP15XX | 226 | #ifdef CONFIG_ARCH_OMAP15XX |
225 | if (cpu_is_omap15xx() && gpio < 16) | 227 | if (cpu_is_omap15xx() && gpio < 16) |
226 | return 0; | 228 | return 0; |
@@ -529,6 +531,10 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) | |||
529 | return; | 531 | return; |
530 | } | 532 | } |
531 | __raw_writel(gpio_mask, reg); | 533 | __raw_writel(gpio_mask, reg); |
534 | |||
535 | /* Workaround for clearing DSP GPIO interrupts to allow retention */ | ||
536 | if (cpu_is_omap2420()) | ||
537 | __raw_writel(gpio_mask, bank->base + OMAP24XX_GPIO_IRQSTATUS2); | ||
532 | } | 538 | } |
533 | 539 | ||
534 | static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) | 540 | static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) |
@@ -662,6 +668,14 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) | |||
662 | } | 668 | } |
663 | } | 669 | } |
664 | 670 | ||
671 | static void _reset_gpio(struct gpio_bank *bank, int gpio) | ||
672 | { | ||
673 | _set_gpio_direction(bank, get_gpio_index(gpio), 1); | ||
674 | _set_gpio_irqenable(bank, gpio, 0); | ||
675 | _clear_gpio_irqstatus(bank, gpio); | ||
676 | _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); | ||
677 | } | ||
678 | |||
665 | /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ | 679 | /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ |
666 | static int gpio_wake_enable(unsigned int irq, unsigned int enable) | 680 | static int gpio_wake_enable(unsigned int irq, unsigned int enable) |
667 | { | 681 | { |
@@ -672,9 +686,7 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable) | |||
672 | if (check_gpio(gpio) < 0) | 686 | if (check_gpio(gpio) < 0) |
673 | return -ENODEV; | 687 | return -ENODEV; |
674 | bank = get_gpio_bank(gpio); | 688 | bank = get_gpio_bank(gpio); |
675 | spin_lock(&bank->lock); | ||
676 | retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable); | 689 | retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable); |
677 | spin_unlock(&bank->lock); | ||
678 | 690 | ||
679 | return retval; | 691 | return retval; |
680 | } | 692 | } |
@@ -696,7 +708,9 @@ int omap_request_gpio(int gpio) | |||
696 | } | 708 | } |
697 | bank->reserved_map |= (1 << get_gpio_index(gpio)); | 709 | bank->reserved_map |= (1 << get_gpio_index(gpio)); |
698 | 710 | ||
699 | /* Set trigger to none. You need to enable the trigger after request_irq */ | 711 | /* Set trigger to none. You need to enable the desired trigger with |
712 | * request_irq() or set_irq_type(). | ||
713 | */ | ||
700 | _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); | 714 | _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); |
701 | 715 | ||
702 | #ifdef CONFIG_ARCH_OMAP15XX | 716 | #ifdef CONFIG_ARCH_OMAP15XX |
@@ -756,9 +770,7 @@ void omap_free_gpio(int gpio) | |||
756 | } | 770 | } |
757 | #endif | 771 | #endif |
758 | bank->reserved_map &= ~(1 << get_gpio_index(gpio)); | 772 | bank->reserved_map &= ~(1 << get_gpio_index(gpio)); |
759 | _set_gpio_direction(bank, get_gpio_index(gpio), 1); | 773 | _reset_gpio(bank, gpio); |
760 | _set_gpio_irqenable(bank, gpio, 0); | ||
761 | _clear_gpio_irqstatus(bank, gpio); | ||
762 | spin_unlock(&bank->lock); | 774 | spin_unlock(&bank->lock); |
763 | } | 775 | } |
764 | 776 | ||
@@ -898,6 +910,14 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, | |||
898 | 910 | ||
899 | } | 911 | } |
900 | 912 | ||
913 | static void gpio_irq_shutdown(unsigned int irq) | ||
914 | { | ||
915 | unsigned int gpio = irq - IH_GPIO_BASE; | ||
916 | struct gpio_bank *bank = get_gpio_bank(gpio); | ||
917 | |||
918 | _reset_gpio(bank, gpio); | ||
919 | } | ||
920 | |||
901 | static void gpio_ack_irq(unsigned int irq) | 921 | static void gpio_ack_irq(unsigned int irq) |
902 | { | 922 | { |
903 | unsigned int gpio = irq - IH_GPIO_BASE; | 923 | unsigned int gpio = irq - IH_GPIO_BASE; |
@@ -946,6 +966,7 @@ static void mpuio_unmask_irq(unsigned int irq) | |||
946 | 966 | ||
947 | static struct irq_chip gpio_irq_chip = { | 967 | static struct irq_chip gpio_irq_chip = { |
948 | .name = "GPIO", | 968 | .name = "GPIO", |
969 | .shutdown = gpio_irq_shutdown, | ||
949 | .ack = gpio_ack_irq, | 970 | .ack = gpio_ack_irq, |
950 | .mask = gpio_mask_irq, | 971 | .mask = gpio_mask_irq, |
951 | .unmask = gpio_unmask_irq, | 972 | .unmask = gpio_unmask_irq, |
@@ -985,7 +1006,7 @@ static int __init _omap_gpio_init(void) | |||
985 | else | 1006 | else |
986 | clk_enable(gpio_ick); | 1007 | clk_enable(gpio_ick); |
987 | gpio_fck = clk_get(NULL, "gpios_fck"); | 1008 | gpio_fck = clk_get(NULL, "gpios_fck"); |
988 | if (IS_ERR(gpio_ick)) | 1009 | if (IS_ERR(gpio_fck)) |
989 | printk("Could not get gpios_fck\n"); | 1010 | printk("Could not get gpios_fck\n"); |
990 | else | 1011 | else |
991 | clk_enable(gpio_fck); | 1012 | clk_enable(gpio_fck); |
@@ -1144,8 +1165,8 @@ static int omap_gpio_resume(struct sys_device *dev) | |||
1144 | wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; | 1165 | wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; |
1145 | break; | 1166 | break; |
1146 | case METHOD_GPIO_24XX: | 1167 | case METHOD_GPIO_24XX: |
1147 | wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; | 1168 | wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; |
1148 | wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; | 1169 | wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; |
1149 | break; | 1170 | break; |
1150 | default: | 1171 | default: |
1151 | continue; | 1172 | continue; |