Viewing file: irq.c (2.79 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* * 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); } }
|