irq.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:3k
- /*
- * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Looks after interrupts on the HARP board.
- *
- * Bases on the IPR irq system
- */
- #include <linux/config.h>
- #include <linux/init.h>
- #include <linux/irq.h>
- #include <asm/system.h>
- #include <asm/io.h>
- #include "harp.h"
- #define NUM_EXTERNAL_IRQS 16
- // Early versions of the STB1 Overdrive required this nasty frig
- //#define INVERT_INTMASK_WRITES
- static void enable_harp_irq(unsigned int irq);
- static void disable_harp_irq(unsigned int irq);
- /* shutdown is same as "disable" */
- #define shutdown_harp_irq disable_harp_irq
- static void mask_and_ack_harp(unsigned int);
- static void end_harp_irq(unsigned int irq);
- static unsigned int startup_harp_irq(unsigned int irq)
- {
- enable_harp_irq(irq);
- return 0; /* never anything pending */
- }
- static struct hw_interrupt_type harp_irq_type = {
- "Harp-IRQ",
- startup_harp_irq,
- shutdown_harp_irq,
- enable_harp_irq,
- disable_harp_irq,
- mask_and_ack_harp,
- end_harp_irq
- };
- static void disable_harp_irq(unsigned int irq)
- {
- unsigned val, flags;
- unsigned maskReg;
- unsigned mask;
- int pri;
- if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
- return;
- pri = 15 - irq;
- if (pri < 8) {
- maskReg = EPLD_INTMASK0;
- } else {
- maskReg = EPLD_INTMASK1;
- pri -= 8;
- }
- save_and_cli(flags);
- mask = ctrl_inl(maskReg);
- mask &= (~(1 << pri));
- #if defined(INVERT_INTMASK_WRITES)
- mask ^= 0xff;
- #endif
- ctrl_outl(mask, maskReg);
- restore_flags(flags);
- }
- static void enable_harp_irq(unsigned int irq)
- {
- unsigned flags;
- unsigned maskReg;
- unsigned mask;
- int pri;
- if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
- return;
- pri = 15 - irq;
- if (pri < 8) {
- maskReg = EPLD_INTMASK0;
- } else {
- maskReg = EPLD_INTMASK1;
- pri -= 8;
- }
- save_and_cli(flags);
- mask = ctrl_inl(maskReg);
- mask |= (1 << pri);
- #if defined(INVERT_INTMASK_WRITES)
- mask ^= 0xff;
- #endif
- ctrl_outl(mask, maskReg);
- restore_flags(flags);
- }
- /* This functions sets the desired irq handler to be an overdrive type */
- static void __init make_harp_irq(unsigned int irq)
- {
- disable_irq_nosync(irq);
- irq_desc[irq].handler = &harp_irq_type;
- disable_harp_irq(irq);
- }
- static void mask_and_ack_harp(unsigned int irq)
- {
- disable_harp_irq(irq);
- }
- static void end_harp_irq(unsigned int irq)
- {
- enable_harp_irq(irq);
- }
- void __init init_harp_irq(void)
- {
- int i;
- #if !defined(INVERT_INTMASK_WRITES)
- // On the harp these are set to enable an interrupt
- ctrl_outl(0x00, EPLD_INTMASK0);
- ctrl_outl(0x00, EPLD_INTMASK1);
- #else
- // On the Overdrive the data is inverted before being stored in the reg
- ctrl_outl(0xff, EPLD_INTMASK0);
- ctrl_outl(0xff, EPLD_INTMASK1);
- #endif
- for (i = 0; i < NUM_EXTERNAL_IRQS; i++) {
- make_harp_irq(i);
- }
- }