99 lines
1.8 KiB
C
99 lines
1.8 KiB
C
/*
|
|
* Copyright (C) 2000 STMicroelectronics Limited
|
|
* Author: 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/init.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/irq.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/io.h>
|
|
#include <asm/system.h>
|
|
#include <mach/epld.h>
|
|
#include <mach/common.h>
|
|
|
|
#define NUM_EXTERNAL_IRQS 16
|
|
|
|
static void disable_harp_irq(unsigned int irq)
|
|
{
|
|
unsigned maskReg;
|
|
unsigned mask;
|
|
int pri;
|
|
|
|
if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
|
|
return;
|
|
|
|
pri = 15 - irq;
|
|
|
|
if (pri < 8) {
|
|
maskReg = EPLD_INTMASK0CLR;
|
|
} else {
|
|
maskReg = EPLD_INTMASK1CLR;
|
|
pri -= 8;
|
|
}
|
|
mask = 1 << pri;
|
|
|
|
epld_write(mask, maskReg);
|
|
|
|
/* Read back the value we just wrote to flush any write posting */
|
|
epld_read(maskReg);
|
|
}
|
|
|
|
static void enable_harp_irq(unsigned int irq)
|
|
{
|
|
unsigned maskReg;
|
|
unsigned mask;
|
|
int pri;
|
|
|
|
if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
|
|
return;
|
|
|
|
pri = 15 - irq;
|
|
|
|
if (pri < 8) {
|
|
maskReg = EPLD_INTMASK0SET;
|
|
} else {
|
|
maskReg = EPLD_INTMASK1SET;
|
|
pri -= 8;
|
|
}
|
|
mask = 1 << pri;
|
|
|
|
epld_write(mask, maskReg);
|
|
}
|
|
|
|
static void __init disable_all_interrupts(void)
|
|
{
|
|
epld_write(0x00, EPLD_INTMASK0);
|
|
epld_write(0x00, EPLD_INTMASK1);
|
|
}
|
|
|
|
static struct irq_chip harp_chips[NUM_EXTERNAL_IRQS] = {
|
|
[0 ... NUM_EXTERNAL_IRQS-1] = {
|
|
.mask = disable_harp_irq,
|
|
.unmask = enable_harp_irq,
|
|
.mask_ack = disable_harp_irq,
|
|
.name = "harp",
|
|
}
|
|
};
|
|
|
|
void __init harp_init_irq(void)
|
|
{
|
|
int irq;
|
|
|
|
disable_all_interrupts();
|
|
|
|
for (irq = 0; irq < NUM_EXTERNAL_IRQS; irq++) {
|
|
disable_irq_nosync(irq);
|
|
set_irq_chip_and_handler_name(irq, &harp_chips[irq],
|
|
handle_level_irq, "level");
|
|
disable_harp_irq(irq);
|
|
}
|
|
}
|