[ARM] 3429/1: ARM: OMAP: 4/8 Update GPIO

Patch from Tony Lindgren

Update OMAP GPIO code from linux-omap tree:

- Fix omap16xx edge control by Juha Yrjola
- Support for additional omap16xx trigger modes by Dirk Behme
- Fix edge detection by Tony Lindgren et al.
- Better support for omap15xx and omap310 by Andrej Zaborowski
- Fix omap15xx interrupt bug by Petukhov Nikolay

Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by Tony Lindgren and committed by Russell King 6e60e79a 8d7f9f50

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