static int imx21_gpio_irq_type(unsigned int _irq, unsigned int type) { unsigned int irq_type = 0, irq, reg, bit; irq = _irq - IRQ_GPIOA(0); reg = irq >> 5; bit = 1 << (irq % 32); if (type == IRQT_PROBE) { /* Don't mess with enabled GPIOs using preconfigured edges or GPIOs set to alternate function during probe */ /* TODO: support probe */ // if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) & // GPIO_bit(gpio)) // return 0; // if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2))) // return 0; // type = __IRQT_RISEDGE | __IRQT_FALEDGE; } GIUS(reg) |= bit; DDIR(reg) &= ~(bit); DEBUG_IRQ("setting type of irq %d to ", _irq); if (type & __IRQT_RISEDGE) { DEBUG_IRQ("rising edges\n"); irq_type = 0x0; } if (type & __IRQT_FALEDGE) { DEBUG_IRQ("falling edges\n"); irq_type = 0x1; } if (type & __IRQT_LOWLVL) { DEBUG_IRQ("low level\n"); irq_type = 0x3; } if (type & __IRQT_HIGHLVL) { DEBUG_IRQ("high level\n"); irq_type = 0x2; } if (irq % 32 < 16) { ICR1(reg) = (ICR1(reg) & ~(0x3 << ((irq % 16) * 2))) | (irq_type << ((irq % 16) * 2)); } else { ICR2(reg) = (ICR2(reg) & ~(0x3 << ((irq % 16) * 2))) | (irq_type << ((irq % 16) * 2)); } return 0; }
void __init imx21_init_irq(void) { unsigned int irq; DEBUG_IRQ("Initializing imx21 interrupts\n"); /* Mask all interrupts initially */ IMR(0) = 0; IMR(1) = 0; IMR(2) = 0; IMR(3) = 0; IMR(4) = 0; IMR(5) = 0; for (irq = 0; irq < IMX21_IRQS; irq++) { set_irq_chip(irq, &imx21_internal_chip); set_irq_handler(irq, do_level_IRQ); set_irq_flags(irq, IRQF_VALID); } for (irq = IRQ_GPIOA(0); irq < IRQ_GPIOF(32); irq++) { set_irq_chip(irq, &imx21_gpio_chip); set_irq_handler(irq, do_edge_IRQ); set_irq_flags(irq, IRQF_VALID); } set_irq_chained_handler(INT_GPIO, imx21_gpio_handler); /* Disable all interrupts initially. */ /* In IMX21 this is done in the bootloader. */ }
static void imx21_gpio_unmask_irq(unsigned int irq) { DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq); IMR(IRQ_TO_REG(irq)) |= 1 << ((irq - IRQ_GPIOA(0)) % 32); PMASK = PMASK | (1 << IRQ_TO_REG(irq)); }
static void imx21_gpio_handler(unsigned int irq_unused, struct irqdesc *desc, struct pt_regs *regs) { unsigned int mask; unsigned int port; unsigned int irq_base; unsigned int irq = 0; for (port = 0; port < 6; port++) { if (ISR(port) & IMR(port)) { break; } } mask = ISR(port); irq_base = IRQ_GPIOA(0) + (port * 32); desc = irq_desc + irq_base; while (mask) { if (mask & 1) { DEBUG_IRQ("handling irq %d (port %d)\n", irq, port); desc->handle(irq + irq_base, desc, regs); ISR(port) = (1 << irq); } irq++; desc++; mask >>= 1; } }
static void imx21_gpio_ack_irq(unsigned int irq) { DEBUG_IRQ("%s: irq %d isr %d\n", __FUNCTION__, irq, IRQ_TO_REG(irq)); ISR(IRQ_TO_REG(irq)) |= 1 << ((irq - IRQ_GPIOA(0)) % 32); }
void __init imx_init_irq(void) { unsigned int irq; DEBUG_IRQ("Initializing imx interrupts\n"); /* Mask all interrupts initially */ IMR(0) = 0; IMR(1) = 0; IMR(2) = 0; IMR(3) = 0; for (irq = 0; irq < IMX_IRQS; irq++) { set_irq_chip(irq, &imx_internal_chip); set_irq_handler(irq, do_level_IRQ); set_irq_flags(irq, IRQF_VALID); } for (irq = IRQ_GPIOA(0); irq < IRQ_GPIOD(32); irq++) { set_irq_chip(irq, &imx_gpio_chip); set_irq_handler(irq, do_edge_IRQ); set_irq_flags(irq, IRQF_VALID); } set_irq_chained_handler(GPIO_INT_PORTA, imx_gpioa_demux_handler); set_irq_chained_handler(GPIO_INT_PORTB, imx_gpiob_demux_handler); set_irq_chained_handler(GPIO_INT_PORTC, imx_gpioc_demux_handler); set_irq_chained_handler(GPIO_INT_PORTD, imx_gpiod_demux_handler); /* Disable all interrupts initially. */ /* In IMX this is done in the bootloader. */ }
static void imx_gpio_handler(unsigned int mask, unsigned int irq, struct irq_desc *desc) { while (mask) { if (mask & 1) { DEBUG_IRQ("handling irq %d\n", irq); generic_handle_irq(irq); } irq++; mask >>= 1; } }
static void imx_gpio_handler(unsigned int mask, unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { desc = irq_desc + irq; while (mask) { if (mask & 1) { DEBUG_IRQ("handling irq %d\n", irq); desc_handle_irq(irq, desc, regs); } irq++; desc++; mask >>= 1; } }
void __init imx_init_irq(void) { unsigned int irq; DEBUG_IRQ("Initializing imx interrupts\n"); /* Disable all interrupts initially. */ /* Do not rely on the bootloader. */ __raw_writel(0, IMX_AITC_INTENABLEH); __raw_writel(0, IMX_AITC_INTENABLEL); /* Mask all GPIO interrupts as well */ IMR(0) = 0; IMR(1) = 0; IMR(2) = 0; IMR(3) = 0; for (irq = 0; irq < IMX_IRQS; irq++) { set_irq_chip(irq, &imx_internal_chip); set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } for (irq = IRQ_GPIOA(0); irq < IRQ_GPIOD(32); irq++) { set_irq_chip(irq, &imx_gpio_chip); set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID); } set_irq_chained_handler(GPIO_INT_PORTA, imx_gpioa_demux_handler); set_irq_chained_handler(GPIO_INT_PORTB, imx_gpiob_demux_handler); set_irq_chained_handler(GPIO_INT_PORTC, imx_gpioc_demux_handler); set_irq_chained_handler(GPIO_INT_PORTD, imx_gpiod_demux_handler); /* Release masking of interrupts according to priority */ __raw_writel(-1, IMX_AITC_NIMASK); #ifdef CONFIG_FIQ /* Initialize FIQ */ init_FIQ(); #endif }
static void imx21_gpio_mask_irq(unsigned int irq) { DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq); IMR(IRQ_TO_REG(irq)) &= ~( 1 << ((irq - IRQ_GPIOA(0)) % 32)); }
static void imx_gpio_unmask_irq(unsigned int irq) { DEBUG_IRQ("%s: irq %d\n", __func__, irq); IMR(IRQ_TO_REG(irq)) |= 1 << ((irq - IRQ_GPIOA(0)) % 32); }