diff options
Diffstat (limited to 'arch/arm/plat-omap/gpio.c')
| -rw-r--r-- | arch/arm/plat-omap/gpio.c | 86 |
1 files changed, 61 insertions, 25 deletions
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index b4d5b9e4bfce..d3c8ea7eecfd 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
| @@ -174,7 +174,7 @@ static int gpio_bank_count; | |||
| 174 | static inline struct gpio_bank *get_gpio_bank(int gpio) | 174 | static inline struct gpio_bank *get_gpio_bank(int gpio) |
| 175 | { | 175 | { |
| 176 | #ifdef CONFIG_ARCH_OMAP15XX | 176 | #ifdef CONFIG_ARCH_OMAP15XX |
| 177 | if (cpu_is_omap1510()) { | 177 | if (cpu_is_omap15xx()) { |
| 178 | if (OMAP_GPIO_IS_MPUIO(gpio)) | 178 | if (OMAP_GPIO_IS_MPUIO(gpio)) |
| 179 | return &gpio_bank[0]; | 179 | return &gpio_bank[0]; |
| 180 | return &gpio_bank[1]; | 180 | return &gpio_bank[1]; |
| @@ -223,7 +223,7 @@ static inline int gpio_valid(int gpio) | |||
| 223 | return 0; | 223 | return 0; |
| 224 | } | 224 | } |
| 225 | #ifdef CONFIG_ARCH_OMAP15XX | 225 | #ifdef CONFIG_ARCH_OMAP15XX |
| 226 | if (cpu_is_omap1510() && gpio < 16) | 226 | if (cpu_is_omap15xx() && gpio < 16) |
| 227 | return 0; | 227 | return 0; |
| 228 | #endif | 228 | #endif |
| 229 | #if defined(CONFIG_ARCH_OMAP16XX) | 229 | #if defined(CONFIG_ARCH_OMAP16XX) |
| @@ -402,13 +402,13 @@ static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int tr | |||
| 402 | u32 gpio_bit = 1 << gpio; | 402 | u32 gpio_bit = 1 << gpio; |
| 403 | 403 | ||
| 404 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, | 404 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, |
| 405 | trigger & IRQT_LOW); | 405 | trigger & __IRQT_LOWLVL); |
| 406 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, | 406 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, |
| 407 | trigger & IRQT_HIGH); | 407 | trigger & __IRQT_HIGHLVL); |
| 408 | MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, | 408 | MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, |
| 409 | trigger & IRQT_RISING); | 409 | trigger & __IRQT_RISEDGE); |
| 410 | MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, | 410 | MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, |
| 411 | trigger & IRQT_FALLING); | 411 | trigger & __IRQT_FALEDGE); |
| 412 | /* FIXME: Possibly do 'set_irq_handler(j, do_level_IRQ)' if only level | 412 | /* FIXME: Possibly do 'set_irq_handler(j, do_level_IRQ)' if only level |
| 413 | * triggering requested. */ | 413 | * triggering requested. */ |
| 414 | } | 414 | } |
| @@ -422,9 +422,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) | |||
| 422 | case METHOD_MPUIO: | 422 | case METHOD_MPUIO: |
| 423 | reg += OMAP_MPUIO_GPIO_INT_EDGE; | 423 | reg += OMAP_MPUIO_GPIO_INT_EDGE; |
| 424 | l = __raw_readl(reg); | 424 | l = __raw_readl(reg); |
| 425 | if (trigger == IRQT_RISING) | 425 | if (trigger & __IRQT_RISEDGE) |
| 426 | l |= 1 << gpio; | 426 | l |= 1 << gpio; |
| 427 | else if (trigger == IRQT_FALLING) | 427 | else if (trigger & __IRQT_FALEDGE) |
| 428 | l &= ~(1 << gpio); | 428 | l &= ~(1 << gpio); |
| 429 | else | 429 | else |
| 430 | goto bad; | 430 | goto bad; |
| @@ -432,9 +432,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) | |||
| 432 | case METHOD_GPIO_1510: | 432 | case METHOD_GPIO_1510: |
| 433 | reg += OMAP1510_GPIO_INT_CONTROL; | 433 | reg += OMAP1510_GPIO_INT_CONTROL; |
| 434 | l = __raw_readl(reg); | 434 | l = __raw_readl(reg); |
| 435 | if (trigger == IRQT_RISING) | 435 | if (trigger & __IRQT_RISEDGE) |
| 436 | l |= 1 << gpio; | 436 | l |= 1 << gpio; |
| 437 | else if (trigger == IRQT_FALLING) | 437 | else if (trigger & __IRQT_FALEDGE) |
| 438 | l &= ~(1 << gpio); | 438 | l &= ~(1 << gpio); |
| 439 | else | 439 | else |
| 440 | goto bad; | 440 | goto bad; |
| @@ -446,20 +446,21 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) | |||
| 446 | reg += OMAP1610_GPIO_EDGE_CTRL1; | 446 | reg += OMAP1610_GPIO_EDGE_CTRL1; |
| 447 | gpio &= 0x07; | 447 | gpio &= 0x07; |
| 448 | /* We allow only edge triggering, i.e. two lowest bits */ | 448 | /* We allow only edge triggering, i.e. two lowest bits */ |
| 449 | if (trigger & ~IRQT_BOTHEDGE) | 449 | if (trigger & (__IRQT_LOWLVL | __IRQT_HIGHLVL)) |
| 450 | BUG(); | 450 | BUG(); |
| 451 | /* NOTE: knows __IRQT_{FAL,RIS}EDGE match OMAP hardware */ | ||
| 452 | trigger &= 0x03; | ||
| 453 | l = __raw_readl(reg); | 451 | l = __raw_readl(reg); |
| 454 | l &= ~(3 << (gpio << 1)); | 452 | l &= ~(3 << (gpio << 1)); |
| 455 | l |= trigger << (gpio << 1); | 453 | if (trigger & __IRQT_RISEDGE) |
| 454 | l |= 2 << (gpio << 1); | ||
| 455 | if (trigger & __IRQT_FALEDGE) | ||
| 456 | l |= 1 << (gpio << 1); | ||
| 456 | break; | 457 | break; |
| 457 | case METHOD_GPIO_730: | 458 | case METHOD_GPIO_730: |
| 458 | reg += OMAP730_GPIO_INT_CONTROL; | 459 | reg += OMAP730_GPIO_INT_CONTROL; |
| 459 | l = __raw_readl(reg); | 460 | l = __raw_readl(reg); |
| 460 | if (trigger == IRQT_RISING) | 461 | if (trigger & __IRQT_RISEDGE) |
| 461 | l |= 1 << gpio; | 462 | l |= 1 << gpio; |
| 462 | else if (trigger == IRQT_FALLING) | 463 | else if (trigger & __IRQT_FALEDGE) |
| 463 | l &= ~(1 << gpio); | 464 | l &= ~(1 << gpio); |
| 464 | else | 465 | else |
| 465 | goto bad; | 466 | goto bad; |
| @@ -491,7 +492,9 @@ static int gpio_irq_type(unsigned irq, unsigned type) | |||
| 491 | if (check_gpio(gpio) < 0) | 492 | if (check_gpio(gpio) < 0) |
| 492 | return -EINVAL; | 493 | return -EINVAL; |
| 493 | 494 | ||
| 494 | if (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL|IRQT_PROBE)) | 495 | if (type & IRQT_PROBE) |
| 496 | return -EINVAL; | ||
| 497 | if (!cpu_is_omap24xx() && (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL))) | ||
| 495 | return -EINVAL; | 498 | return -EINVAL; |
| 496 | 499 | ||
| 497 | bank = get_gpio_bank(gpio); | 500 | bank = get_gpio_bank(gpio); |
| @@ -755,13 +758,32 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, | |||
| 755 | if (bank->method == METHOD_GPIO_24XX) | 758 | if (bank->method == METHOD_GPIO_24XX) |
| 756 | isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; | 759 | isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; |
| 757 | #endif | 760 | #endif |
| 758 | |||
| 759 | while(1) { | 761 | while(1) { |
| 760 | isr = __raw_readl(isr_reg); | 762 | u32 isr_saved, level_mask = 0; |
| 761 | _enable_gpio_irqbank(bank, isr, 0); | 763 | |
| 762 | _clear_gpio_irqbank(bank, isr); | 764 | isr_saved = isr = __raw_readl(isr_reg); |
| 763 | _enable_gpio_irqbank(bank, isr, 1); | 765 | |
| 764 | desc->chip->unmask(irq); | 766 | if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO)) |
| 767 | isr &= 0x0000ffff; | ||
| 768 | |||
| 769 | if (cpu_is_omap24xx()) | ||
| 770 | level_mask = | ||
| 771 | __raw_readl(bank->base + | ||
| 772 | OMAP24XX_GPIO_LEVELDETECT0) | | ||
| 773 | __raw_readl(bank->base + | ||
| 774 | OMAP24XX_GPIO_LEVELDETECT1); | ||
| 775 | |||
| 776 | /* clear edge sensitive interrupts before handler(s) are | ||
| 777 | called so that we don't miss any interrupt occurred while | ||
| 778 | executing them */ | ||
| 779 | _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0); | ||
| 780 | _clear_gpio_irqbank(bank, isr_saved & ~level_mask); | ||
| 781 | _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1); | ||
| 782 | |||
| 783 | /* if there is only edge sensitive GPIO pin interrupts | ||
| 784 | configured, we could unmask GPIO bank interrupt immediately */ | ||
| 785 | if (!level_mask) | ||
| 786 | desc->chip->unmask(irq); | ||
| 765 | 787 | ||
| 766 | if (!isr) | 788 | if (!isr) |
| 767 | break; | 789 | break; |
| @@ -774,6 +796,20 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, | |||
| 774 | d = irq_desc + gpio_irq; | 796 | d = irq_desc + gpio_irq; |
| 775 | desc_handle_irq(gpio_irq, d, regs); | 797 | desc_handle_irq(gpio_irq, d, regs); |
| 776 | } | 798 | } |
| 799 | |||
| 800 | if (cpu_is_omap24xx()) { | ||
| 801 | /* clear level sensitive interrupts after handler(s) */ | ||
| 802 | _enable_gpio_irqbank(bank, isr_saved & level_mask, 0); | ||
| 803 | _clear_gpio_irqbank(bank, isr_saved & level_mask); | ||
| 804 | _enable_gpio_irqbank(bank, isr_saved & level_mask, 1); | ||
| 805 | } | ||
| 806 | |||
| 807 | /* if bank has any level sensitive GPIO pin interrupt | ||
| 808 | configured, we must unmask the bank interrupt only after | ||
| 809 | handler(s) are executed in order to avoid spurious bank | ||
| 810 | interrupt */ | ||
| 811 | if (level_mask) | ||
| 812 | desc->chip->unmask(irq); | ||
| 777 | } | 813 | } |
| 778 | } | 814 | } |
| 779 | 815 | ||
| @@ -848,7 +884,7 @@ static int __init _omap_gpio_init(void) | |||
| 848 | 884 | ||
| 849 | initialized = 1; | 885 | initialized = 1; |
| 850 | 886 | ||
| 851 | if (cpu_is_omap1510()) { | 887 | if (cpu_is_omap15xx()) { |
| 852 | gpio_ick = clk_get(NULL, "arm_gpio_ck"); | 888 | gpio_ick = clk_get(NULL, "arm_gpio_ck"); |
| 853 | if (IS_ERR(gpio_ick)) | 889 | if (IS_ERR(gpio_ick)) |
| 854 | printk("Could not get arm_gpio_ck\n"); | 890 | printk("Could not get arm_gpio_ck\n"); |
| @@ -869,7 +905,7 @@ static int __init _omap_gpio_init(void) | |||
| 869 | } | 905 | } |
| 870 | 906 | ||
| 871 | #ifdef CONFIG_ARCH_OMAP15XX | 907 | #ifdef CONFIG_ARCH_OMAP15XX |
| 872 | if (cpu_is_omap1510()) { | 908 | if (cpu_is_omap15xx()) { |
| 873 | printk(KERN_INFO "OMAP1510 GPIO hardware\n"); | 909 | printk(KERN_INFO "OMAP1510 GPIO hardware\n"); |
| 874 | gpio_bank_count = 2; | 910 | gpio_bank_count = 2; |
| 875 | gpio_bank = gpio_bank_1510; | 911 | gpio_bank = gpio_bank_1510; |
