* published by the Free Software Foundation.
*/
+#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
static inline struct gpio_bank *get_gpio_bank(int gpio)
{
#ifdef CONFIG_ARCH_OMAP15XX
- if (cpu_is_omap15xx()) {
+ if (cpu_is_omap1510()) {
if (OMAP_GPIO_IS_MPUIO(gpio))
return &gpio_bank[0];
return &gpio_bank[1];
return 0;
}
#ifdef CONFIG_ARCH_OMAP15XX
- if (cpu_is_omap15xx() && gpio < 16)
+ if (cpu_is_omap1510() && gpio < 16)
return 0;
#endif
#if defined(CONFIG_ARCH_OMAP16XX)
u32 gpio_bit = 1 << gpio;
MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
- trigger & __IRQT_LOWLVL);
+ trigger & IRQT_LOW);
MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
- trigger & __IRQT_HIGHLVL);
+ trigger & IRQT_HIGH);
MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
- trigger & __IRQT_RISEDGE);
+ trigger & IRQT_RISING);
MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
- trigger & __IRQT_FALEDGE);
+ trigger & IRQT_FALLING);
/* FIXME: Possibly do 'set_irq_handler(j, do_level_IRQ)' if only level
* triggering requested. */
}
case METHOD_MPUIO:
reg += OMAP_MPUIO_GPIO_INT_EDGE;
l = __raw_readl(reg);
- if (trigger & __IRQT_RISEDGE)
+ if (trigger == IRQT_RISING)
l |= 1 << gpio;
- else if (trigger & __IRQT_FALEDGE)
+ else if (trigger == IRQT_FALLING)
l &= ~(1 << gpio);
else
goto bad;
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_INT_CONTROL;
l = __raw_readl(reg);
- if (trigger & __IRQT_RISEDGE)
+ if (trigger == IRQT_RISING)
l |= 1 << gpio;
- else if (trigger & __IRQT_FALEDGE)
+ else if (trigger == IRQT_FALLING)
l &= ~(1 << gpio);
else
goto bad;
reg += OMAP1610_GPIO_EDGE_CTRL1;
gpio &= 0x07;
/* We allow only edge triggering, i.e. two lowest bits */
- if (trigger & (__IRQT_LOWLVL | __IRQT_HIGHLVL))
+ if (trigger & ~IRQT_BOTHEDGE)
BUG();
+ /* NOTE: knows __IRQT_{FAL,RIS}EDGE match OMAP hardware */
+ trigger &= 0x03;
l = __raw_readl(reg);
l &= ~(3 << (gpio << 1));
- if (trigger & __IRQT_RISEDGE)
- l |= 2 << (gpio << 1);
- if (trigger & __IRQT_FALEDGE)
- l |= 1 << (gpio << 1);
+ l |= trigger << (gpio << 1);
break;
case METHOD_GPIO_730:
reg += OMAP730_GPIO_INT_CONTROL;
l = __raw_readl(reg);
- if (trigger & __IRQT_RISEDGE)
+ if (trigger == IRQT_RISING)
l |= 1 << gpio;
- else if (trigger & __IRQT_FALEDGE)
+ else if (trigger == IRQT_FALLING)
l &= ~(1 << gpio);
else
goto bad;
if (check_gpio(gpio) < 0)
return -EINVAL;
- if (type & IRQT_PROBE)
- return -EINVAL;
- if (!cpu_is_omap24xx() && (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL)))
+ if (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL|IRQT_PROBE))
return -EINVAL;
bank = get_gpio_bank(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;
u32 isr;
unsigned int gpio_irq;
struct gpio_bank *bank;
- u32 retrigger = 0;
- int unmasked = 0;
desc->chip->ack(irq);
- bank = get_irq_data(irq);
+ bank = (struct gpio_bank *) desc->data;
if (bank->method == METHOD_MPUIO)
isr_reg = bank->base + OMAP_MPUIO_GPIO_INT;
#ifdef CONFIG_ARCH_OMAP15XX
if (bank->method == METHOD_GPIO_24XX)
isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
#endif
- while(1) {
- u32 isr_saved, level_mask = 0;
- u32 enabled;
-
- 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()) {
- 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
- executing them */
- _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0);
- _clear_gpio_irqbank(bank, isr_saved & ~level_mask);
- _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1);
-
- /* if there is only edge sensitive GPIO pin interrupts
- configured, we could unmask GPIO bank interrupt immediately */
- if (!level_mask && !unmasked) {
- unmasked = 1;
- desc->chip->unmask(irq);
- }
+ while(1) {
+ isr = __raw_readl(isr_reg);
+ _enable_gpio_irqbank(bank, isr, 0);
+ _clear_gpio_irqbank(bank, isr);
+ _enable_gpio_irqbank(bank, isr, 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->depth ||
- (d->status & IRQ_INPROGRESS)))) {
- 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->depth) {
- /* Level triggered interrupts
- * won't ever be reentered
- */
- BUG_ON(level_mask & irq_mask);
- d->status |= IRQ_PENDING;
- }
- continue;
- }
-
desc_handle_irq(gpio_irq, d, regs);
-
- if (unlikely((d->status & IRQ_PENDING) && !d->depth)) {
- irq_mask = 1 <<
- (gpio_irq - bank->virtual_irq_start);
- d->status &= ~IRQ_PENDING;
- _enable_gpio_irqbank(bank, irq_mask, 1);
- retrigger |= irq_mask;
- }
}
-
- if (cpu_is_omap24xx()) {
- /* clear level sensitive interrupts after handler(s) */
- _enable_gpio_irqbank(bank, isr_saved & level_mask, 0);
- _clear_gpio_irqbank(bank, isr_saved & level_mask);
- _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 (!unmasked)
- desc->chip->unmask(irq);
-
}
static void gpio_ack_irq(unsigned int irq)
_set_gpio_irqenable(bank, gpio, 1);
}
-static struct irq_chip gpio_irq_chip = {
- .name = "GPIO",
+static struct irqchip gpio_irq_chip = {
.ack = gpio_ack_irq,
.mask = gpio_mask_irq,
.unmask = gpio_unmask_irq,
.set_wake = gpio_wake_enable,
};
-static struct irq_chip mpuio_irq_chip = {
- .name = "MPUIO",
+static struct irqchip mpuio_irq_chip = {
.ack = mpuio_ack_irq,
.mask = mpuio_mask_irq,
- .unmask = mpuio_unmask_irq
+ .unmask = mpuio_unmask_irq
};
static int initialized;
initialized = 1;
- if (cpu_is_omap15xx()) {
+ if (cpu_is_omap1510()) {
gpio_ick = clk_get(NULL, "arm_gpio_ck");
if (IS_ERR(gpio_ick))
printk("Could not get arm_gpio_ck\n");
}
#ifdef CONFIG_ARCH_OMAP15XX
- if (cpu_is_omap15xx()) {
+ if (cpu_is_omap1510()) {
printk(KERN_INFO "OMAP1510 GPIO hardware\n");
gpio_bank_count = 2;
gpio_bank = gpio_bank_1510;