diff options
Diffstat (limited to 'arch/arm/plat-omap/gpio.c')
-rw-r--r-- | arch/arm/plat-omap/gpio.c | 131 |
1 files changed, 114 insertions, 17 deletions
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index f856a90b264e..17d7afe42b83 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
@@ -81,6 +81,22 @@ | |||
81 | #define OMAP730_GPIO_INT_STATUS 0x14 | 81 | #define OMAP730_GPIO_INT_STATUS 0x14 |
82 | 82 | ||
83 | /* | 83 | /* |
84 | * OMAP850 specific GPIO registers | ||
85 | */ | ||
86 | #define OMAP850_GPIO1_BASE IO_ADDRESS(0xfffbc000) | ||
87 | #define OMAP850_GPIO2_BASE IO_ADDRESS(0xfffbc800) | ||
88 | #define OMAP850_GPIO3_BASE IO_ADDRESS(0xfffbd000) | ||
89 | #define OMAP850_GPIO4_BASE IO_ADDRESS(0xfffbd800) | ||
90 | #define OMAP850_GPIO5_BASE IO_ADDRESS(0xfffbe000) | ||
91 | #define OMAP850_GPIO6_BASE IO_ADDRESS(0xfffbe800) | ||
92 | #define OMAP850_GPIO_DATA_INPUT 0x00 | ||
93 | #define OMAP850_GPIO_DATA_OUTPUT 0x04 | ||
94 | #define OMAP850_GPIO_DIR_CONTROL 0x08 | ||
95 | #define OMAP850_GPIO_INT_CONTROL 0x0c | ||
96 | #define OMAP850_GPIO_INT_MASK 0x10 | ||
97 | #define OMAP850_GPIO_INT_STATUS 0x14 | ||
98 | |||
99 | /* | ||
84 | * omap24xx specific GPIO registers | 100 | * omap24xx specific GPIO registers |
85 | */ | 101 | */ |
86 | #define OMAP242X_GPIO1_BASE IO_ADDRESS(0x48018000) | 102 | #define OMAP242X_GPIO1_BASE IO_ADDRESS(0x48018000) |
@@ -159,7 +175,8 @@ struct gpio_bank { | |||
159 | #define METHOD_GPIO_1510 1 | 175 | #define METHOD_GPIO_1510 1 |
160 | #define METHOD_GPIO_1610 2 | 176 | #define METHOD_GPIO_1610 2 |
161 | #define METHOD_GPIO_730 3 | 177 | #define METHOD_GPIO_730 3 |
162 | #define METHOD_GPIO_24XX 4 | 178 | #define METHOD_GPIO_850 4 |
179 | #define METHOD_GPIO_24XX 5 | ||
163 | 180 | ||
164 | #ifdef CONFIG_ARCH_OMAP16XX | 181 | #ifdef CONFIG_ARCH_OMAP16XX |
165 | static struct gpio_bank gpio_bank_1610[5] = { | 182 | static struct gpio_bank gpio_bank_1610[5] = { |
@@ -190,6 +207,19 @@ static struct gpio_bank gpio_bank_730[7] = { | |||
190 | }; | 207 | }; |
191 | #endif | 208 | #endif |
192 | 209 | ||
210 | #ifdef CONFIG_ARCH_OMAP850 | ||
211 | static struct gpio_bank gpio_bank_850[7] = { | ||
212 | { OMAP_MPUIO_BASE, INT_850_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO }, | ||
213 | { OMAP850_GPIO1_BASE, INT_850_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_850 }, | ||
214 | { OMAP850_GPIO2_BASE, INT_850_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_850 }, | ||
215 | { OMAP850_GPIO3_BASE, INT_850_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_850 }, | ||
216 | { OMAP850_GPIO4_BASE, INT_850_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_850 }, | ||
217 | { OMAP850_GPIO5_BASE, INT_850_GPIO_BANK5, IH_GPIO_BASE + 128, METHOD_GPIO_850 }, | ||
218 | { OMAP850_GPIO6_BASE, INT_850_GPIO_BANK6, IH_GPIO_BASE + 160, METHOD_GPIO_850 }, | ||
219 | }; | ||
220 | #endif | ||
221 | |||
222 | |||
193 | #ifdef CONFIG_ARCH_OMAP24XX | 223 | #ifdef CONFIG_ARCH_OMAP24XX |
194 | 224 | ||
195 | static struct gpio_bank gpio_bank_242x[4] = { | 225 | static struct gpio_bank gpio_bank_242x[4] = { |
@@ -236,7 +266,7 @@ static inline struct gpio_bank *get_gpio_bank(int gpio) | |||
236 | return &gpio_bank[0]; | 266 | return &gpio_bank[0]; |
237 | return &gpio_bank[1 + (gpio >> 4)]; | 267 | return &gpio_bank[1 + (gpio >> 4)]; |
238 | } | 268 | } |
239 | if (cpu_is_omap730()) { | 269 | if (cpu_is_omap7xx()) { |
240 | if (OMAP_GPIO_IS_MPUIO(gpio)) | 270 | if (OMAP_GPIO_IS_MPUIO(gpio)) |
241 | return &gpio_bank[0]; | 271 | return &gpio_bank[0]; |
242 | return &gpio_bank[1 + (gpio >> 5)]; | 272 | return &gpio_bank[1 + (gpio >> 5)]; |
@@ -251,7 +281,7 @@ static inline struct gpio_bank *get_gpio_bank(int gpio) | |||
251 | 281 | ||
252 | static inline int get_gpio_index(int gpio) | 282 | static inline int get_gpio_index(int gpio) |
253 | { | 283 | { |
254 | if (cpu_is_omap730()) | 284 | if (cpu_is_omap7xx()) |
255 | return gpio & 0x1f; | 285 | return gpio & 0x1f; |
256 | if (cpu_is_omap24xx()) | 286 | if (cpu_is_omap24xx()) |
257 | return gpio & 0x1f; | 287 | return gpio & 0x1f; |
@@ -273,7 +303,7 @@ static inline int gpio_valid(int gpio) | |||
273 | return 0; | 303 | return 0; |
274 | if ((cpu_is_omap16xx()) && gpio < 64) | 304 | if ((cpu_is_omap16xx()) && gpio < 64) |
275 | return 0; | 305 | return 0; |
276 | if (cpu_is_omap730() && gpio < 192) | 306 | if (cpu_is_omap7xx() && gpio < 192) |
277 | return 0; | 307 | return 0; |
278 | if (cpu_is_omap24xx() && gpio < 128) | 308 | if (cpu_is_omap24xx() && gpio < 128) |
279 | return 0; | 309 | return 0; |
@@ -318,6 +348,11 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) | |||
318 | reg += OMAP730_GPIO_DIR_CONTROL; | 348 | reg += OMAP730_GPIO_DIR_CONTROL; |
319 | break; | 349 | break; |
320 | #endif | 350 | #endif |
351 | #ifdef CONFIG_ARCH_OMAP850 | ||
352 | case METHOD_GPIO_850: | ||
353 | reg += OMAP850_GPIO_DIR_CONTROL; | ||
354 | break; | ||
355 | #endif | ||
321 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 356 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
322 | case METHOD_GPIO_24XX: | 357 | case METHOD_GPIO_24XX: |
323 | reg += OMAP24XX_GPIO_OE; | 358 | reg += OMAP24XX_GPIO_OE; |
@@ -380,6 +415,16 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) | |||
380 | l &= ~(1 << gpio); | 415 | l &= ~(1 << gpio); |
381 | break; | 416 | break; |
382 | #endif | 417 | #endif |
418 | #ifdef CONFIG_ARCH_OMAP850 | ||
419 | case METHOD_GPIO_850: | ||
420 | reg += OMAP850_GPIO_DATA_OUTPUT; | ||
421 | l = __raw_readl(reg); | ||
422 | if (enable) | ||
423 | l |= 1 << gpio; | ||
424 | else | ||
425 | l &= ~(1 << gpio); | ||
426 | break; | ||
427 | #endif | ||
383 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 428 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
384 | case METHOD_GPIO_24XX: | 429 | case METHOD_GPIO_24XX: |
385 | if (enable) | 430 | if (enable) |
@@ -426,6 +471,11 @@ static int __omap_get_gpio_datain(int gpio) | |||
426 | reg += OMAP730_GPIO_DATA_INPUT; | 471 | reg += OMAP730_GPIO_DATA_INPUT; |
427 | break; | 472 | break; |
428 | #endif | 473 | #endif |
474 | #ifdef CONFIG_ARCH_OMAP850 | ||
475 | case METHOD_GPIO_850: | ||
476 | reg += OMAP850_GPIO_DATA_INPUT; | ||
477 | break; | ||
478 | #endif | ||
429 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 479 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
430 | case METHOD_GPIO_24XX: | 480 | case METHOD_GPIO_24XX: |
431 | reg += OMAP24XX_GPIO_DATAIN; | 481 | reg += OMAP24XX_GPIO_DATAIN; |
@@ -598,6 +648,18 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) | |||
598 | goto bad; | 648 | goto bad; |
599 | break; | 649 | break; |
600 | #endif | 650 | #endif |
651 | #ifdef CONFIG_ARCH_OMAP850 | ||
652 | case METHOD_GPIO_850: | ||
653 | reg += OMAP850_GPIO_INT_CONTROL; | ||
654 | l = __raw_readl(reg); | ||
655 | if (trigger & IRQ_TYPE_EDGE_RISING) | ||
656 | l |= 1 << gpio; | ||
657 | else if (trigger & IRQ_TYPE_EDGE_FALLING) | ||
658 | l &= ~(1 << gpio); | ||
659 | else | ||
660 | goto bad; | ||
661 | break; | ||
662 | #endif | ||
601 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 663 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
602 | case METHOD_GPIO_24XX: | 664 | case METHOD_GPIO_24XX: |
603 | set_24xx_gpio_triggering(bank, gpio, trigger); | 665 | set_24xx_gpio_triggering(bank, gpio, trigger); |
@@ -678,6 +740,11 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) | |||
678 | reg += OMAP730_GPIO_INT_STATUS; | 740 | reg += OMAP730_GPIO_INT_STATUS; |
679 | break; | 741 | break; |
680 | #endif | 742 | #endif |
743 | #ifdef CONFIG_ARCH_OMAP850 | ||
744 | case METHOD_GPIO_850: | ||
745 | reg += OMAP850_GPIO_INT_STATUS; | ||
746 | break; | ||
747 | #endif | ||
681 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 748 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
682 | case METHOD_GPIO_24XX: | 749 | case METHOD_GPIO_24XX: |
683 | reg += OMAP24XX_GPIO_IRQSTATUS1; | 750 | reg += OMAP24XX_GPIO_IRQSTATUS1; |
@@ -691,8 +758,12 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) | |||
691 | 758 | ||
692 | /* Workaround for clearing DSP GPIO interrupts to allow retention */ | 759 | /* Workaround for clearing DSP GPIO interrupts to allow retention */ |
693 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 760 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
761 | reg = bank->base + OMAP24XX_GPIO_IRQSTATUS2; | ||
694 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) | 762 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) |
695 | __raw_writel(gpio_mask, bank->base + OMAP24XX_GPIO_IRQSTATUS2); | 763 | __raw_writel(gpio_mask, reg); |
764 | |||
765 | /* Flush posted write for the irq status to avoid spurious interrupts */ | ||
766 | __raw_readl(reg); | ||
696 | #endif | 767 | #endif |
697 | } | 768 | } |
698 | 769 | ||
@@ -736,6 +807,13 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) | |||
736 | inv = 1; | 807 | inv = 1; |
737 | break; | 808 | break; |
738 | #endif | 809 | #endif |
810 | #ifdef CONFIG_ARCH_OMAP850 | ||
811 | case METHOD_GPIO_850: | ||
812 | reg += OMAP850_GPIO_INT_MASK; | ||
813 | mask = 0xffffffff; | ||
814 | inv = 1; | ||
815 | break; | ||
816 | #endif | ||
739 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 817 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
740 | case METHOD_GPIO_24XX: | 818 | case METHOD_GPIO_24XX: |
741 | reg += OMAP24XX_GPIO_IRQENABLE1; | 819 | reg += OMAP24XX_GPIO_IRQENABLE1; |
@@ -799,6 +877,16 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab | |||
799 | l |= gpio_mask; | 877 | l |= gpio_mask; |
800 | break; | 878 | break; |
801 | #endif | 879 | #endif |
880 | #ifdef CONFIG_ARCH_OMAP850 | ||
881 | case METHOD_GPIO_850: | ||
882 | reg += OMAP850_GPIO_INT_MASK; | ||
883 | l = __raw_readl(reg); | ||
884 | if (enable) | ||
885 | l &= ~(gpio_mask); | ||
886 | else | ||
887 | l |= gpio_mask; | ||
888 | break; | ||
889 | #endif | ||
802 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 890 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
803 | case METHOD_GPIO_24XX: | 891 | case METHOD_GPIO_24XX: |
804 | if (enable) | 892 | if (enable) |
@@ -837,13 +925,10 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) | |||
837 | case METHOD_MPUIO: | 925 | case METHOD_MPUIO: |
838 | case METHOD_GPIO_1610: | 926 | case METHOD_GPIO_1610: |
839 | spin_lock_irqsave(&bank->lock, flags); | 927 | spin_lock_irqsave(&bank->lock, flags); |
840 | if (enable) { | 928 | if (enable) |
841 | bank->suspend_wakeup |= (1 << gpio); | 929 | bank->suspend_wakeup |= (1 << gpio); |
842 | enable_irq_wake(bank->irq); | 930 | else |
843 | } else { | ||
844 | disable_irq_wake(bank->irq); | ||
845 | bank->suspend_wakeup &= ~(1 << gpio); | 931 | bank->suspend_wakeup &= ~(1 << gpio); |
846 | } | ||
847 | spin_unlock_irqrestore(&bank->lock, flags); | 932 | spin_unlock_irqrestore(&bank->lock, flags); |
848 | return 0; | 933 | return 0; |
849 | #endif | 934 | #endif |
@@ -856,13 +941,10 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) | |||
856 | return -EINVAL; | 941 | return -EINVAL; |
857 | } | 942 | } |
858 | spin_lock_irqsave(&bank->lock, flags); | 943 | spin_lock_irqsave(&bank->lock, flags); |
859 | if (enable) { | 944 | if (enable) |
860 | bank->suspend_wakeup |= (1 << gpio); | 945 | bank->suspend_wakeup |= (1 << gpio); |
861 | enable_irq_wake(bank->irq); | 946 | else |
862 | } else { | ||
863 | disable_irq_wake(bank->irq); | ||
864 | bank->suspend_wakeup &= ~(1 << gpio); | 947 | bank->suspend_wakeup &= ~(1 << gpio); |
865 | } | ||
866 | spin_unlock_irqrestore(&bank->lock, flags); | 948 | spin_unlock_irqrestore(&bank->lock, flags); |
867 | return 0; | 949 | return 0; |
868 | #endif | 950 | #endif |
@@ -983,6 +1065,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
983 | if (bank->method == METHOD_GPIO_730) | 1065 | if (bank->method == METHOD_GPIO_730) |
984 | isr_reg = bank->base + OMAP730_GPIO_INT_STATUS; | 1066 | isr_reg = bank->base + OMAP730_GPIO_INT_STATUS; |
985 | #endif | 1067 | #endif |
1068 | #ifdef CONFIG_ARCH_OMAP850 | ||
1069 | if (bank->method == METHOD_GPIO_850) | ||
1070 | isr_reg = bank->base + OMAP850_GPIO_INT_STATUS; | ||
1071 | #endif | ||
986 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 1072 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
987 | if (bank->method == METHOD_GPIO_24XX) | 1073 | if (bank->method == METHOD_GPIO_24XX) |
988 | isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; | 1074 | isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; |
@@ -1372,6 +1458,13 @@ static int __init _omap_gpio_init(void) | |||
1372 | gpio_bank = gpio_bank_730; | 1458 | gpio_bank = gpio_bank_730; |
1373 | } | 1459 | } |
1374 | #endif | 1460 | #endif |
1461 | #ifdef CONFIG_ARCH_OMAP850 | ||
1462 | if (cpu_is_omap850()) { | ||
1463 | printk(KERN_INFO "OMAP850 GPIO hardware\n"); | ||
1464 | gpio_bank_count = 7; | ||
1465 | gpio_bank = gpio_bank_850; | ||
1466 | } | ||
1467 | #endif | ||
1375 | 1468 | ||
1376 | #ifdef CONFIG_ARCH_OMAP24XX | 1469 | #ifdef CONFIG_ARCH_OMAP24XX |
1377 | if (cpu_is_omap242x()) { | 1470 | if (cpu_is_omap242x()) { |
@@ -1420,7 +1513,7 @@ static int __init _omap_gpio_init(void) | |||
1420 | __raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1); | 1513 | __raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1); |
1421 | __raw_writew(0x0014, bank->base + OMAP1610_GPIO_SYSCONFIG); | 1514 | __raw_writew(0x0014, bank->base + OMAP1610_GPIO_SYSCONFIG); |
1422 | } | 1515 | } |
1423 | if (cpu_is_omap730() && bank->method == METHOD_GPIO_730) { | 1516 | if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_730) { |
1424 | __raw_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK); | 1517 | __raw_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK); |
1425 | __raw_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS); | 1518 | __raw_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS); |
1426 | 1519 | ||
@@ -1743,6 +1836,9 @@ static int gpio_is_input(struct gpio_bank *bank, int mask) | |||
1743 | case METHOD_GPIO_730: | 1836 | case METHOD_GPIO_730: |
1744 | reg += OMAP730_GPIO_DIR_CONTROL; | 1837 | reg += OMAP730_GPIO_DIR_CONTROL; |
1745 | break; | 1838 | break; |
1839 | case METHOD_GPIO_850: | ||
1840 | reg += OMAP850_GPIO_DIR_CONTROL; | ||
1841 | break; | ||
1746 | case METHOD_GPIO_24XX: | 1842 | case METHOD_GPIO_24XX: |
1747 | reg += OMAP24XX_GPIO_OE; | 1843 | reg += OMAP24XX_GPIO_OE; |
1748 | break; | 1844 | break; |
@@ -1762,7 +1858,8 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) | |||
1762 | 1858 | ||
1763 | if (bank_is_mpuio(bank)) | 1859 | if (bank_is_mpuio(bank)) |
1764 | gpio = OMAP_MPUIO(0); | 1860 | gpio = OMAP_MPUIO(0); |
1765 | else if (cpu_class_is_omap2() || cpu_is_omap730()) | 1861 | else if (cpu_class_is_omap2() || cpu_is_omap730() || |
1862 | cpu_is_omap850()) | ||
1766 | bankwidth = 32; | 1863 | bankwidth = 32; |
1767 | 1864 | ||
1768 | for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) { | 1865 | for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) { |