void __init kirkwood_init_irq(void) { int i; orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)); orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)); /* * Mask and clear GPIO IRQ interrupts. */ writel(0, GPIO_LEVEL_MASK(0)); writel(0, GPIO_EDGE_MASK(0)); writel(0, GPIO_EDGE_CAUSE(0)); writel(0, GPIO_LEVEL_MASK(32)); writel(0, GPIO_EDGE_MASK(32)); writel(0, GPIO_EDGE_CAUSE(32)); for (i = IRQ_KIRKWOOD_GPIO_START; i < NR_IRQS; i++) { set_irq_chip(i, &orion_gpio_irq_chip); set_irq_handler(i, handle_level_irq); irq_desc[i].status |= IRQ_LEVEL; set_irq_flags(i, IRQF_VALID); } set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_0_7, gpio_irq_handler); set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_8_15, gpio_irq_handler); set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_16_23, gpio_irq_handler); set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_24_31, gpio_irq_handler); set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_0_7, gpio_irq_handler); set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_8_15, gpio_irq_handler); set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_16_23, gpio_irq_handler); }
void orion_gpio_irq_handler(int pinoff) { u32 cause; int pin; cause = readl(GPIO_DATA_IN(pinoff)) & readl(GPIO_LEVEL_MASK(pinoff)); cause |= readl(GPIO_EDGE_CAUSE(pinoff)) & readl(GPIO_EDGE_MASK(pinoff)); for (pin = pinoff; pin < pinoff + 8; pin++) { int irq = gpio_to_irq(pin); struct irq_desc *desc = irq_desc + irq; if (!(cause & (1 << (pin & 31)))) continue; if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { /* Swap polarity (race with GPIO line) */ u32 polarity; polarity = readl(GPIO_IN_POL(pin)); polarity ^= 1 << (pin & 31); writel(polarity, GPIO_IN_POL(pin)); } desc_handle_irq(irq, desc); } }
static void gpio_irq_ack(u32 irq) { int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK; if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { int pin = irq_to_gpio(irq); writel(~(1 << (pin & 31)), GPIO_EDGE_CAUSE(pin)); } }
void __init dove_init_irq(void) { int i; orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)); orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)); /* * Mask and clear GPIO IRQ interrupts. */ writel(0, GPIO_LEVEL_MASK(0)); writel(0, GPIO_EDGE_MASK(0)); writel(0, GPIO_EDGE_CAUSE(0)); /* * Mask and clear PMU interrupts */ writel(0, PMU_INTERRUPT_MASK); writel(0, PMU_INTERRUPT_CAUSE); for (i = IRQ_DOVE_GPIO_START; i < IRQ_DOVE_PMU_START; i++) { set_irq_chip(i, &orion_gpio_irq_chip); set_irq_handler(i, handle_level_irq); irq_desc[i].status |= IRQ_LEVEL; set_irq_flags(i, IRQF_VALID); } set_irq_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler); set_irq_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler); set_irq_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler); set_irq_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler); set_irq_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler); for (i = IRQ_DOVE_PMU_START; i < NR_IRQS; i++) { set_irq_chip(i, &pmu_irq_chip); set_irq_handler(i, handle_level_irq); irq_desc[i].status |= IRQ_LEVEL; set_irq_flags(i, IRQF_VALID); } set_irq_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler); }