/* * linux/arch/arm26/mach-arc/irq.c * * Copyright (C) 1996 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Changelog: * 24-09-1996 RMK Created * 10-10-1996 RMK Brought up to date with arch-sa110eval * 22-10-1996 RMK Changed interrupt numbers & uses new inb/outb macros * 11-01-1998 RMK Added mask_and_ack_irq * 22-08-1998 RMK Restructured IRQ routines * 08-09-2002 IM Brought up to date for 2.5 * 01-06-2003 JMA Removed arc_fiq_chip */ #include #include #include #include #include #include extern void init_FIQ(void); #define a_clf() clf() #define a_stf() stf() static void arc_ack_irq_a(unsigned int irq) { unsigned int val, mask; mask = 1 << irq; a_clf(); val = ioc_readb(IOC_IRQMASKA); ioc_writeb(val & ~mask, IOC_IRQMASKA); ioc_writeb(mask, IOC_IRQCLRA); a_stf(); } static void arc_mask_irq_a(unsigned int irq) { unsigned int val, mask; mask = 1 << irq; a_clf(); val = ioc_readb(IOC_IRQMASKA); ioc_writeb(val & ~mask, IOC_IRQMASKA); a_stf(); } static void arc_unmask_irq_a(unsigned int irq) { unsigned int val, mask; mask = 1 << irq; a_clf(); val = ioc_readb(IOC_IRQMASKA); ioc_writeb(val | mask, IOC_IRQMASKA); a_stf(); } static struct irqchip arc_a_chip = { .ack = arc_ack_irq_a, .mask = arc_mask_irq_a, .unmask = arc_unmask_irq_a, }; static void arc_mask_irq_b(unsigned int irq) { unsigned int val, mask; mask = 1 << (irq & 7); val = ioc_readb(IOC_IRQMASKB); ioc_writeb(val & ~mask, IOC_IRQMASKB); } static void arc_unmask_irq_b(unsigned int irq) { unsigned int val, mask; mask = 1 << (irq & 7); val = ioc_readb(IOC_IRQMASKB); ioc_writeb(val | mask, IOC_IRQMASKB); } static struct irqchip arc_b_chip = { .ack = arc_mask_irq_b, .mask = arc_mask_irq_b, .unmask = arc_unmask_irq_b, }; /* FIXME - JMA none of these functions are used in arm26 currently static void arc_mask_irq_fiq(unsigned int irq) { unsigned int val, mask; mask = 1 << (irq & 7); val = ioc_readb(IOC_FIQMASK); ioc_writeb(val & ~mask, IOC_FIQMASK); } static void arc_unmask_irq_fiq(unsigned int irq) { unsigned int val, mask; mask = 1 << (irq & 7); val = ioc_readb(IOC_FIQMASK); ioc_writeb(val | mask, IOC_FIQMASK); } static struct irqchip arc_fiq_chip = { .ack = arc_mask_irq_fiq, .mask = arc_mask_irq_fiq, .unmask = arc_unmask_irq_fiq, }; */ void __init arc_init_irq(void) { unsigned int irq, flags; /* Disable all IOC interrupt sources */ ioc_writeb(0, IOC_IRQMASKA); ioc_writeb(0, IOC_IRQMASKB); ioc_writeb(0, IOC_FIQMASK); for (irq = 0; irq < NR_IRQS; irq++) { flags = IRQF_VALID; if (irq <= 6 || (irq >= 9 && irq <= 15)) flags |= IRQF_PROBE; if (irq == IRQ_KEYBOARDTX) flags |= IRQF_NOAUTOEN; switch (irq) { case 0 ... 7: set_irq_chip(irq, &arc_a_chip); set_irq_handler(irq, do_level_IRQ); set_irq_flags(irq, flags); break; case 8 ... 15: set_irq_chip(irq, &arc_b_chip); set_irq_handler(irq, do_level_IRQ); set_irq_flags(irq, flags); /* case 64 ... 72: set_irq_chip(irq, &arc_fiq_chip); set_irq_flags(irq, flags); break; */ } } irq_desc[IRQ_KEYBOARDTX].noautoenable = 1; init_FIQ(); }