1/* arch/arm/mach-lh7a40x/irq-kev7a400.c 2 * 3 * Copyright (C) 2004 Coastal Environmental Systems 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * version 2 as published by the Free Software Foundation. 8 * 9 */ 10 11#include <linux/interrupt.h> 12#include <linux/init.h> 13 14#include <asm/irq.h> 15#include <asm/mach/irq.h> 16#include <asm/mach/hardware.h> 17#include <asm/mach/irqs.h> 18 19#include "common.h" 20 21 /* KEV7a400 CPLD IRQ handling */ 22 23static u16 CPLD_IRQ_mask; /* Mask for CPLD IRQs, 1 == unmasked */ 24 25static void 26lh7a400_ack_cpld_irq (u32 irq) 27{ 28 CPLD_CL_INT = 1 << (irq - IRQ_KEV7A400_CPLD); 29} 30 31static void 32lh7a400_mask_cpld_irq (u32 irq) 33{ 34 CPLD_IRQ_mask &= ~(1 << (irq - IRQ_KEV7A400_CPLD)); 35 CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask; 36} 37 38static void 39lh7a400_unmask_cpld_irq (u32 irq) 40{ 41 CPLD_IRQ_mask |= 1 << (irq - IRQ_KEV7A400_CPLD); 42 CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask; 43} 44 45static struct 46irq_chip lh7a400_cpld_chip = { 47 .name = "CPLD", 48 .ack = lh7a400_ack_cpld_irq, 49 .mask = lh7a400_mask_cpld_irq, 50 .unmask = lh7a400_unmask_cpld_irq, 51}; 52 53static void 54lh7a400_cpld_handler (unsigned int irq, struct irq_desc *desc) 55{ 56 u32 mask = CPLD_LATCHED_INTS; 57 irq = IRQ_KEV_7A400_CPLD; 58 for (; mask; mask >>= 1, ++irq) { 59 if (mask & 1) 60 desc[irq].handle (irq, desc); 61 } 62} 63 64 /* IRQ initialization */ 65 66void __init 67lh7a400_init_board_irq (void) 68{ 69 int irq; 70 71 for (irq = IRQ_KEV7A400_CPLD; 72 irq < IRQ_KEV7A400_CPLD + NR_IRQ_KEV7A400_CPLD; ++irq) { 73 set_irq_chip (irq, &lh7a400_cpld_chip); 74 set_irq_handler (irq, handle_edge_irq); 75 set_irq_flags (irq, IRQF_VALID); 76 } 77 set_irq_chained_handler (IRQ_CPLD, kev7a400_cpld_handler); 78 79 /* Clear all CPLD interrupts */ 80 CPLD_CL_INT = 0xff; /* CPLD_INTR_MMC_CD | CPLD_INTR_ETH_INT; */ 81 82 83 GPIO_GPIOINTEN = 0; /* Disable all GPIO interrupts */ 84 barrier(); 85 GPIO_INTTYPE1 86 = (GPIO_INTR_PCC1_CD | GPIO_INTR_PCC1_CD); /* Edge trig. */ 87 GPIO_INTTYPE2 = 0; /* Falling edge & low-level */ 88 GPIO_GPIOFEOI = 0xff; /* Clear all GPIO interrupts */ 89 GPIO_GPIOINTEN = 0xff; /* Enable all GPIO interrupts */ 90 91 init_FIQ(); 92} 93