Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm

* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (44 commits)
  [ARM] 3541/2: workaround for PXA27x erratum E7
  [ARM] nommu: provide a way for correct control register value selection
  [ARM] 3705/1: add supersection support to ioremap()
  [ARM] 3707/1: iwmmxt: use the generic thread notifier infrastructure
  [ARM] 3706/2: ep93xx: add cirrus logic edb9315a support
  [ARM] 3704/1: format IOP Kconfig with tabs, create more consistency
  [ARM] 3703/1: Add help description for ARCH_EP80219
  [ARM] 3678/1: MMC: Make OMAP MMC work
  [ARM] 3677/1: OMAP: Update H2 defconfig
  [ARM] 3676/1: ARM: OMAP: Fix dmtimers and timer32k to compile on OMAP1
  [ARM] Add section support to ioremap
  [ARM] Fix sa11x0 SDRAM selection
  [ARM] Set bit 4 on section mappings correctly depending on CPU
  [ARM] 3666/1: TRIZEPS4 [1/5] core
  ARM: OMAP: Multiplexing for 24xx GPMC wait pin monitoring
  ARM: OMAP: Fix SRAM to use MT_MEMORY instead of MT_DEVICE
  ARM: OMAP: Update dmtimers
  ARM: OMAP: Make clock variables static
  ARM: OMAP: Fix GPMC compilation when DEBUG is defined
  ARM: OMAP: Mux updates for external DMA and GPIO
  ...
This commit is contained in:
Linus Torvalds
2006-07-02 15:04:12 -07:00
106 changed files with 5705 additions and 951 deletions

View File

@ -536,6 +536,49 @@ static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
_clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio));
}
static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
{
void __iomem *reg = bank->base;
int inv = 0;
u32 l;
u32 mask;
switch (bank->method) {
case METHOD_MPUIO:
reg += OMAP_MPUIO_GPIO_MASKIT;
mask = 0xffff;
inv = 1;
break;
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_INT_MASK;
mask = 0xffff;
inv = 1;
break;
case METHOD_GPIO_1610:
reg += OMAP1610_GPIO_IRQENABLE1;
mask = 0xffff;
break;
case METHOD_GPIO_730:
reg += OMAP730_GPIO_INT_MASK;
mask = 0xffffffff;
inv = 1;
break;
case METHOD_GPIO_24XX:
reg += OMAP24XX_GPIO_IRQENABLE1;
mask = 0xffffffff;
break;
default:
BUG();
return 0;
}
l = __raw_readl(reg);
if (inv)
l = ~l;
l &= mask;
return l;
}
static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
{
void __iomem *reg = bank->base;
@ -735,6 +778,8 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
u32 isr;
unsigned int gpio_irq;
struct gpio_bank *bank;
u32 retrigger = 0;
int unmasked = 0;
desc->chip->ack(irq);
@ -759,18 +804,22 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
#endif
while(1) {
u32 isr_saved, level_mask = 0;
u32 enabled;
isr_saved = isr = __raw_readl(isr_reg);
enabled = _get_gpio_irqbank_mask(bank);
isr_saved = isr = __raw_readl(isr_reg) & enabled;
if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
isr &= 0x0000ffff;
if (cpu_is_omap24xx())
if (cpu_is_omap24xx()) {
level_mask =
__raw_readl(bank->base +
OMAP24XX_GPIO_LEVELDETECT0) |
__raw_readl(bank->base +
OMAP24XX_GPIO_LEVELDETECT1);
level_mask &= enabled;
}
/* clear edge sensitive interrupts before handler(s) are
called so that we don't miss any interrupt occurred while
@ -781,19 +830,54 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
/* if there is only edge sensitive GPIO pin interrupts
configured, we could unmask GPIO bank interrupt immediately */
if (!level_mask)
if (!level_mask && !unmasked) {
unmasked = 1;
desc->chip->unmask(irq);
}
isr |= retrigger;
retrigger = 0;
if (!isr)
break;
gpio_irq = bank->virtual_irq_start;
for (; isr != 0; isr >>= 1, gpio_irq++) {
struct irqdesc *d;
int irq_mask;
if (!(isr & 1))
continue;
d = irq_desc + gpio_irq;
/* Don't run the handler if it's already running
* or was disabled lazely.
*/
if (unlikely((d->disable_depth || d->running))) {
irq_mask = 1 <<
(gpio_irq - bank->virtual_irq_start);
/* The unmasking will be done by
* enable_irq in case it is disabled or
* after returning from the handler if
* it's already running.
*/
_enable_gpio_irqbank(bank, irq_mask, 0);
if (!d->disable_depth) {
/* Level triggered interrupts
* won't ever be reentered
*/
BUG_ON(level_mask & irq_mask);
d->pending = 1;
}
continue;
}
d->running = 1;
desc_handle_irq(gpio_irq, d, regs);
d->running = 0;
if (unlikely(d->pending && !d->disable_depth)) {
irq_mask = 1 <<
(gpio_irq - bank->virtual_irq_start);
d->pending = 0;
_enable_gpio_irqbank(bank, irq_mask, 1);
retrigger |= irq_mask;
}
}
if (cpu_is_omap24xx()) {
@ -803,13 +887,14 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
_enable_gpio_irqbank(bank, isr_saved & level_mask, 1);
}
/* if bank has any level sensitive GPIO pin interrupt
configured, we must unmask the bank interrupt only after
handler(s) are executed in order to avoid spurious bank
interrupt */
if (level_mask)
desc->chip->unmask(irq);
}
/* if bank has any level sensitive GPIO pin interrupt
configured, we must unmask the bank interrupt only after
handler(s) are executed in order to avoid spurious bank
interrupt */
if (!unmasked)
desc->chip->unmask(irq);
}
static void gpio_ack_irq(unsigned int irq)